< prev index next >

src/hotspot/share/runtime/vmOperations.cpp

Print this page

258   _with_locked_monitors = with_locked_monitors;
259   _with_locked_synchronizers = with_locked_synchronizers;
260 }
261 
262 bool VM_ThreadDump::doit_prologue() {
263   if (_with_locked_synchronizers) {
264     // Acquire Heap_lock to dump concurrent locks
265     Heap_lock->lock();
266   }
267 
268   return true;
269 }
270 
271 void VM_ThreadDump::doit_epilogue() {
272   if (_with_locked_synchronizers) {
273     // Release Heap_lock
274     Heap_lock->unlock();
275   }
276 }
277 
278 // Hash table of void* to a list of ObjectMonitor* owned by the JavaThread.
279 // The JavaThread's owner key is either a JavaThread* or a stack lock
280 // address in the JavaThread so we use "void*".
281 //
282 class ObjectMonitorsDump : public MonitorClosure, public ObjectMonitorsView {
283  private:
284   static unsigned int ptr_hash(void* const& s1) {
285     // 2654435761 = 2^32 * Phi (golden ratio)
286     return (unsigned int)(((uint32_t)(uintptr_t)s1) * 2654435761u);
287   }
288 
289  private:
290   class ObjectMonitorLinkedList :
291     public LinkedListImpl<ObjectMonitor*,
292                           AnyObj::C_HEAP, mtThread,
293                           AllocFailStrategy::RETURN_NULL> {};
294 
295   // ResourceHashtable SIZE is specified at compile time so we
296   // use 1031 which is the first prime after 1024.
297   typedef ResourceHashtable<void*, ObjectMonitorLinkedList*, 1031, AnyObj::C_HEAP, mtThread,
298                             &ObjectMonitorsDump::ptr_hash> PtrTable;
299   PtrTable* _ptrs;
300   size_t _key_count;
301   size_t _om_count;
302 
303   void add_list(void* key, ObjectMonitorLinkedList* list) {
304     _ptrs->put(key, list);
305     _key_count++;
306   }
307 
308   ObjectMonitorLinkedList* get_list(void* key) {
309     ObjectMonitorLinkedList** listpp = _ptrs->get(key);
310     return (listpp == nullptr) ? nullptr : *listpp;
311   }
312 
313   void add(ObjectMonitor* monitor) {
314     void* key = monitor->owner();
315 
316     ObjectMonitorLinkedList* list = get_list(key);
317     if (list == nullptr) {
318       // Create new list and add it to the hash table:
319       list = new (mtThread) ObjectMonitorLinkedList;
320       _ptrs->put(key, list);
321       _key_count++;
322     }
323 
324     assert(list->find(monitor) == nullptr, "Should not contain duplicates");
325     list->add(monitor);  // Add the ObjectMonitor to the list.
326     _om_count++;
327   }
328 
329  public:
330   // ResourceHashtable is passed to various functions and populated in
331   // different places so we allocate it using C_HEAP to make it immune
332   // from any ResourceMarks that happen to be in the code paths.
333   ObjectMonitorsDump() : _ptrs(new (mtThread) PtrTable), _key_count(0), _om_count(0) {}
334 
335   ~ObjectMonitorsDump() {
336     class CleanupObjectMonitorsDump: StackObj {
337      public:
338       bool do_entry(void*& key, ObjectMonitorLinkedList*& list) {
339         list->clear();  // clear the LinkListNodes
340         delete list;    // then delete the LinkedList
341         return true;
342       }
343     } cleanup;
344 
345     _ptrs->unlink(&cleanup);  // cleanup the LinkedLists
346     delete _ptrs;             // then delete the hash table
347   }
348 
349   // Implements MonitorClosure used to collect all owned monitors in the system
350   void do_monitor(ObjectMonitor* monitor) override {
351     assert(monitor->has_owner(), "Expects only owned monitors");
352 
353     if (monitor->is_owner_anonymous()) {
354       // There's no need to collect anonymous owned monitors
355       // because the caller of this code is only interested
356       // in JNI owned monitors.
357       return;
358     }
359 
360     if (monitor->object_peek() == nullptr) {
361       // JNI code doesn't necessarily keep the monitor object
362       // alive. Filter out monitors with dead objects.
363       return;
364     }
365 
366     add(monitor);
367   }
368 
369   // Implements the ObjectMonitorsView interface
370   void visit(MonitorClosure* closure, JavaThread* thread) override {
371     ObjectMonitorLinkedList* list = get_list(thread);

372     LinkedListIterator<ObjectMonitor*> iter(list != nullptr ? list->head() : nullptr);
373     while (!iter.is_empty()) {
374       ObjectMonitor* monitor = *iter.next();
375       closure->do_monitor(monitor);
376     }
377   }
378 
379   size_t key_count() { return _key_count; }
380   size_t om_count() { return _om_count; }
381 };
382 
383 void VM_ThreadDump::doit() {
384   ResourceMark rm;
385 
386   // Set the hazard ptr in the originating thread to protect the
387   // current list of threads. This VM operation needs the current list
388   // of threads for a proper dump and those are the JavaThreads we need
389   // to be protected when we return info to the originating thread.
390   _result->set_t_list();
391 

258   _with_locked_monitors = with_locked_monitors;
259   _with_locked_synchronizers = with_locked_synchronizers;
260 }
261 
262 bool VM_ThreadDump::doit_prologue() {
263   if (_with_locked_synchronizers) {
264     // Acquire Heap_lock to dump concurrent locks
265     Heap_lock->lock();
266   }
267 
268   return true;
269 }
270 
271 void VM_ThreadDump::doit_epilogue() {
272   if (_with_locked_synchronizers) {
273     // Release Heap_lock
274     Heap_lock->unlock();
275   }
276 }
277 
278 // Hash table of int64_t to a list of ObjectMonitor* owned by the JavaThread.
279 // The JavaThread's owner key is either a JavaThread* or a stack lock
280 // address in the JavaThread so we use "int64_t".
281 //
282 class ObjectMonitorsDump : public MonitorClosure, public ObjectMonitorsView {
283  private:
284   static unsigned int ptr_hash(int64_t const& s1) {
285     // 2654435761 = 2^32 * Phi (golden ratio)
286     return (unsigned int)(((uint32_t)(uintptr_t)s1) * 2654435761u);
287   }
288 
289  private:
290   class ObjectMonitorLinkedList :
291     public LinkedListImpl<ObjectMonitor*,
292                           AnyObj::C_HEAP, mtThread,
293                           AllocFailStrategy::RETURN_NULL> {};
294 
295   // ResourceHashtable SIZE is specified at compile time so we
296   // use 1031 which is the first prime after 1024.
297   typedef ResourceHashtable<int64_t, ObjectMonitorLinkedList*, 1031, AnyObj::C_HEAP, mtThread,
298                             &ObjectMonitorsDump::ptr_hash> PtrTable;
299   PtrTable* _ptrs;
300   size_t _key_count;
301   size_t _om_count;
302 
303   void add_list(int64_t key, ObjectMonitorLinkedList* list) {
304     _ptrs->put(key, list);
305     _key_count++;
306   }
307 
308   ObjectMonitorLinkedList* get_list(int64_t key) {
309     ObjectMonitorLinkedList** listpp = _ptrs->get(key);
310     return (listpp == nullptr) ? nullptr : *listpp;
311   }
312 
313   void add(ObjectMonitor* monitor) {
314     int64_t key = monitor->owner();
315 
316     ObjectMonitorLinkedList* list = get_list(key);
317     if (list == nullptr) {
318       // Create new list and add it to the hash table:
319       list = new (mtThread) ObjectMonitorLinkedList;
320       _ptrs->put(key, list);
321       _key_count++;
322     }
323 
324     assert(list->find(monitor) == nullptr, "Should not contain duplicates");
325     list->add(monitor);  // Add the ObjectMonitor to the list.
326     _om_count++;
327   }
328 
329  public:
330   // ResourceHashtable is passed to various functions and populated in
331   // different places so we allocate it using C_HEAP to make it immune
332   // from any ResourceMarks that happen to be in the code paths.
333   ObjectMonitorsDump() : _ptrs(new (mtThread) PtrTable), _key_count(0), _om_count(0) {}
334 
335   ~ObjectMonitorsDump() {
336     class CleanupObjectMonitorsDump: StackObj {
337      public:
338       bool do_entry(int64_t& key, ObjectMonitorLinkedList*& list) {
339         list->clear();  // clear the LinkListNodes
340         delete list;    // then delete the LinkedList
341         return true;
342       }
343     } cleanup;
344 
345     _ptrs->unlink(&cleanup);  // cleanup the LinkedLists
346     delete _ptrs;             // then delete the hash table
347   }
348 
349   // Implements MonitorClosure used to collect all owned monitors in the system
350   void do_monitor(ObjectMonitor* monitor) override {
351     assert(monitor->has_owner(), "Expects only owned monitors");
352 
353     if (monitor->is_owner_anonymous()) {
354       // There's no need to collect anonymous owned monitors
355       // because the caller of this code is only interested
356       // in JNI owned monitors.
357       return;
358     }
359 
360     if (monitor->object_peek() == nullptr) {
361       // JNI code doesn't necessarily keep the monitor object
362       // alive. Filter out monitors with dead objects.
363       return;
364     }
365 
366     add(monitor);
367   }
368 
369   // Implements the ObjectMonitorsView interface
370   void visit(MonitorClosure* closure, JavaThread* thread) override {
371     int64_t key = ObjectMonitor::owner_for(thread);
372     ObjectMonitorLinkedList* list = get_list(key);
373     LinkedListIterator<ObjectMonitor*> iter(list != nullptr ? list->head() : nullptr);
374     while (!iter.is_empty()) {
375       ObjectMonitor* monitor = *iter.next();
376       closure->do_monitor(monitor);
377     }
378   }
379 
380   size_t key_count() { return _key_count; }
381   size_t om_count() { return _om_count; }
382 };
383 
384 void VM_ThreadDump::doit() {
385   ResourceMark rm;
386 
387   // Set the hazard ptr in the originating thread to protect the
388   // current list of threads. This VM operation needs the current list
389   // of threads for a proper dump and those are the JavaThreads we need
390   // to be protected when we return info to the originating thread.
391   _result->set_t_list();
392 
< prev index next >