From 486ff5d3fcfa924ebcb0ce92c067a02b8f9a2ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Sj=C3=B6len?= Date: Fri, 13 Feb 2026 10:56:13 +0000 Subject: [PATCH] 8377455: Replace LinkedList with GrowableArray in VM.ThreadDump's OMTable Reviewed-by: dholmes, coleenp --- src/hotspot/share/runtime/vmOperations.cpp | 55 +++++++--------------- 1 file changed, 16 insertions(+), 39 deletions(-) diff --git a/src/hotspot/share/runtime/vmOperations.cpp b/src/hotspot/share/runtime/vmOperations.cpp index c5539fd5e50..ef480f04c57 100644 --- a/src/hotspot/share/runtime/vmOperations.cpp +++ b/src/hotspot/share/runtime/vmOperations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,6 +51,7 @@ #include "runtime/threadSMR.inline.hpp" #include "runtime/vmOperations.hpp" #include "services/threadService.hpp" +#include "utilities/growableArray.hpp" #include "utilities/ticks.hpp" #define VM_OP_NAME_INITIALIZE(name) #name, @@ -286,42 +287,27 @@ class ObjectMonitorsDump : public MonitorClosure, public ObjectMonitorsView { } private: - class ObjectMonitorLinkedList : - public LinkedListImpl {}; + using ObjectMonitorList = GrowableArrayCHeap; // HashTable SIZE is specified at compile time so we // use 1031 which is the first prime after 1024. - typedef HashTable PtrTable; PtrTable* _ptrs; size_t _key_count; size_t _om_count; - void add_list(int64_t key, ObjectMonitorLinkedList* list) { - _ptrs->put(key, list); - _key_count++; - } - - ObjectMonitorLinkedList* get_list(int64_t key) { - ObjectMonitorLinkedList** listpp = _ptrs->get(key); - return (listpp == nullptr) ? nullptr : *listpp; - } - void add(ObjectMonitor* monitor) { int64_t key = monitor->owner(); - ObjectMonitorLinkedList* list = get_list(key); - if (list == nullptr) { - // Create new list and add it to the hash table: - list = new (mtThread) ObjectMonitorLinkedList; - _ptrs->put(key, list); + bool created = false; + ObjectMonitorList* list = _ptrs->put_if_absent(key, &created); + if (created) { _key_count++; } - assert(list->find(monitor) == nullptr, "Should not contain duplicates"); - list->add(monitor); // Add the ObjectMonitor to the list. + assert(list->find(monitor) == -1, "Should not contain duplicates"); + list->push(monitor); // Add the ObjectMonitor to the list. _om_count++; } @@ -332,17 +318,7 @@ class ObjectMonitorsDump : public MonitorClosure, public ObjectMonitorsView { ObjectMonitorsDump() : _ptrs(new (mtThread) PtrTable), _key_count(0), _om_count(0) {} ~ObjectMonitorsDump() { - class CleanupObjectMonitorsDump: StackObj { - public: - bool do_entry(int64_t& key, ObjectMonitorLinkedList*& list) { - list->clear(); // clear the LinkListNodes - delete list; // then delete the LinkedList - return true; - } - } cleanup; - - _ptrs->unlink(&cleanup); // cleanup the LinkedLists - delete _ptrs; // then delete the hash table + delete _ptrs; } // Implements MonitorClosure used to collect all owned monitors in the system @@ -368,11 +344,12 @@ class ObjectMonitorsDump : public MonitorClosure, public ObjectMonitorsView { // Implements the ObjectMonitorsView interface void visit(MonitorClosure* closure, JavaThread* thread) override { int64_t key = ObjectMonitor::owner_id_from(thread); - ObjectMonitorLinkedList* list = get_list(key); - LinkedListIterator iter(list != nullptr ? list->head() : nullptr); - while (!iter.is_empty()) { - ObjectMonitor* monitor = *iter.next(); - closure->do_monitor(monitor); + ObjectMonitorList* list = _ptrs->get(key); + if (list == nullptr) { + return; + } + for (int i = 0; i < list->length(); i++) { + closure->do_monitor(list->at(i)); } }