From 880e458a1072589ae199cc9204dcce9eab0f4eaa Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 21 Jun 2024 00:24:55 +0000 Subject: [PATCH] 8333819: Move embedded external addresses from relocation info into separate global table Reviewed-by: dlong --- src/hotspot/share/code/nmethod.cpp | 1 + src/hotspot/share/code/nmethod.hpp | 1 + src/hotspot/share/code/oopRecorder.cpp | 46 ++++++++++++++++++++++- src/hotspot/share/code/oopRecorder.hpp | 27 ++++++++++--- src/hotspot/share/code/relocInfo.cpp | 20 ++-------- src/hotspot/share/runtime/init.cpp | 4 +- src/hotspot/share/runtime/mutexLocker.cpp | 5 +++ src/hotspot/share/runtime/mutexLocker.hpp | 2 + 8 files changed, 82 insertions(+), 24 deletions(-) diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 7f91f69c9e3..2f4999dc4e3 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -3996,6 +3996,7 @@ void nmethod::print_statistics() { DebugInformationRecorder::print_statistics(); pc_nmethod_stats.print_pc_stats(); Dependencies::print_statistics(); + ExternalsRecorder::print_statistics(); if (xtty != nullptr) xtty->tail("statistics"); } diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index e3ac422ca70..ee0fe004331 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -705,6 +705,7 @@ public: void copy_values(GrowableArray* oops); void copy_values(GrowableArray* metadata); + void copy_values(GrowableArray
* metadata) {} // Nothing to do // Relocation support private: diff --git a/src/hotspot/share/code/oopRecorder.cpp b/src/hotspot/share/code/oopRecorder.cpp index bfcb4bad475..b8ecc1eccc0 100644 --- a/src/hotspot/share/code/oopRecorder.cpp +++ b/src/hotspot/share/code/oopRecorder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, 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 @@ -31,6 +31,7 @@ #include "memory/allocation.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/jniHandles.inline.hpp" +#include "runtime/mutexLocker.hpp" #include "utilities/copy.hpp" #ifdef ASSERT @@ -211,3 +212,46 @@ OopRecorder::OopRecorder(Arena* arena, bool deduplicate): _oops(arena), _metadat _object_lookup = nullptr; } } + +// Explicitly instantiate +template class ValueRecorder
; + +ExternalsRecorder* ExternalsRecorder::_recorder = nullptr; + +ExternalsRecorder::ExternalsRecorder(): _arena(mtCode), _externals(&_arena) {} + +void ExternalsRecorder_init() { + ExternalsRecorder::initialize(); +} + +void ExternalsRecorder::initialize() { + // After Mutex and before CodeCache are initialized + assert(_recorder == nullptr, "should initialize only once"); + _recorder = new ExternalsRecorder(); +} + +int ExternalsRecorder::find_index(address adr) { + MutexLocker ml(ExternalsRecorder_lock, Mutex::_no_safepoint_check_flag); + assert(_recorder != nullptr, "sanity"); + return _recorder->_externals.find_index(adr); +} + +address ExternalsRecorder::at(int index) { + // find_index() may resize array by reallocating it and freeing old, + // we need loock here to make sure we not accessing to old freed array. + MutexLocker ml(ExternalsRecorder_lock, Mutex::_no_safepoint_check_flag); + assert(_recorder != nullptr, "sanity"); + return _recorder->_externals.at(index); +} + +int ExternalsRecorder::count() { + MutexLocker ml(ExternalsRecorder_lock, Mutex::_no_safepoint_check_flag); + assert(_recorder != nullptr, "sanity"); + return _recorder->_externals.count(); +} + +#ifndef PRODUCT +void ExternalsRecorder::print_statistics() { + tty->print_cr("External addresses table: %d entries", count()); +} +#endif diff --git a/src/hotspot/share/code/oopRecorder.hpp b/src/hotspot/share/code/oopRecorder.hpp index 41d2c0da591..7eded5410e3 100644 --- a/src/hotspot/share/code/oopRecorder.hpp +++ b/src/hotspot/share/code/oopRecorder.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, 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 @@ -133,10 +133,10 @@ template class ValueRecorder : public StackObj { enum { null_index = 0, first_index = 1, index_cache_threshold = 20 }; GrowableArray* _handles; // ordered list (first is always nullptr) - GrowableArray* _no_finds; // all unfindable indexes; usually empty + GrowableArray* _no_finds; // all unfindable indexes; usually empty IndexCache* _indexes; // map: handle -> its probable index - Arena* _arena; - bool _complete; + Arena* _arena; + bool _complete; #ifdef ASSERT static int _find_index_calls, _hit_indexes, _missed_indexes; @@ -186,7 +186,7 @@ class OopRecorder : public ResourceObj { int allocate_oop_index(jobject h) { return _oops.allocate_index(h); } - virtual int find_index(jobject h) { + int find_index(jobject h) { return _object_lookup != nullptr ? _object_lookup->find_index(h, this) : _oops.find_index(h); } jobject oop_at(int index) { @@ -203,7 +203,7 @@ class OopRecorder : public ResourceObj { int allocate_metadata_index(Metadata* oop) { return _metadata.allocate_index(oop); } - virtual int find_index(Metadata* h) { + int find_index(Metadata* h) { return _metadata.find_index(h); } Metadata* metadata_at(int index) { @@ -243,5 +243,20 @@ class OopRecorder : public ResourceObj { #endif }; +// Class is used to record and retrive external addresses +// for Relocation info in compiled code and stubs. +class ExternalsRecorder : public CHeapObj { + private: + Arena _arena; + ValueRecorder
_externals; + static ExternalsRecorder* _recorder; + ExternalsRecorder(); + public: + static void initialize(); + static int find_index(address adr); + static address at(int index); + static int count(); + static void print_statistics() PRODUCT_RETURN; +}; #endif // SHARE_CODE_OOPRECORDER_HPP diff --git a/src/hotspot/share/code/relocInfo.cpp b/src/hotspot/share/code/relocInfo.cpp index 5527436413c..3b19b63f244 100644 --- a/src/hotspot/share/code/relocInfo.cpp +++ b/src/hotspot/share/code/relocInfo.cpp @@ -454,27 +454,15 @@ void trampoline_stub_Relocation::unpack_data() { void external_word_Relocation::pack_data_to(CodeSection* dest) { short* p = (short*) dest->locs_end(); -#ifndef _LP64 - p = pack_1_int_to(p, (int32_t) (intptr_t)_target); -#else - jlong t = (jlong) _target; - int32_t lo = low(t); - int32_t hi = high(t); - p = pack_2_ints_to(p, lo, hi); -#endif /* _LP64 */ + int index = ExternalsRecorder::find_index(_target); + p = pack_1_int_to(p, index); dest->set_locs_end((relocInfo*) p); } void external_word_Relocation::unpack_data() { -#ifndef _LP64 - _target = (address) (intptr_t)unpack_1_int(); -#else - jint lo, hi; - unpack_2_ints(lo, hi); - jlong t = jlong_from(hi, lo);; - _target = (address) t; -#endif /* _LP64 */ + int index = unpack_1_int(); + _target = ExternalsRecorder::at(index); } diff --git a/src/hotspot/share/runtime/init.cpp b/src/hotspot/share/runtime/init.cpp index d37ae99b418..368f4e62c76 100644 --- a/src/hotspot/share/runtime/init.cpp +++ b/src/hotspot/share/runtime/init.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, 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 @@ -57,6 +57,7 @@ void mutex_init(); void universe_oopstorage_init(); void perfMemory_init(); void SuspendibleThreadSet_init(); +void ExternalsRecorder_init(); // After mutex_init() and before CodeCache_init // Initialization done by Java thread in init_globals() void management_init(); @@ -107,6 +108,7 @@ void vm_init_globals() { universe_oopstorage_init(); perfMemory_init(); SuspendibleThreadSet_init(); + ExternalsRecorder_init(); // After mutex_init() and before CodeCache_init } diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index 2587375c52e..add47738db0 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -123,6 +123,8 @@ Monitor* JfrThreadSampler_lock = nullptr; Mutex* CodeHeapStateAnalytics_lock = nullptr; +Mutex* ExternalsRecorder_lock = nullptr; + Monitor* ContinuationRelativize_lock = nullptr; Mutex* Metaspace_lock = nullptr; @@ -328,6 +330,9 @@ void mutex_init() { MUTEX_DEFL(CodeCache_lock , PaddedMonitor, VtableStubs_lock); MUTEX_DEFL(NMethodState_lock , PaddedMutex , CodeCache_lock); + // tty_lock is held when printing nmethod and its relocations which use this lock. + MUTEX_DEFL(ExternalsRecorder_lock , PaddedMutex , tty_lock); + MUTEX_DEFL(Threads_lock , PaddedMonitor, CompileThread_lock, true); MUTEX_DEFL(Compile_lock , PaddedMutex , MethodCompileQueue_lock); MUTEX_DEFL(Heap_lock , PaddedMonitor, AdapterHandlerLibrary_lock); diff --git a/src/hotspot/share/runtime/mutexLocker.hpp b/src/hotspot/share/runtime/mutexLocker.hpp index 91310364b8f..160e6c97db0 100644 --- a/src/hotspot/share/runtime/mutexLocker.hpp +++ b/src/hotspot/share/runtime/mutexLocker.hpp @@ -142,6 +142,8 @@ extern Mutex* ClassLoaderDataGraph_lock; // protects CLDG list, needed f extern Mutex* CodeHeapStateAnalytics_lock; // lock print functions against concurrent analyze functions. // Only used locally in PrintCodeCacheLayout processing. +extern Mutex* ExternalsRecorder_lock; // used to guard access to the external addresses table + extern Monitor* ContinuationRelativize_lock; #if INCLUDE_JVMCI