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
|