8333819: Move embedded external addresses from relocation info into separate global table

Reviewed-by: dlong
This commit is contained in:
Vladimir Kozlov 2024-06-21 00:24:55 +00:00
parent e5de26ddf0
commit 880e458a10
8 changed files with 82 additions and 24 deletions

View File

@ -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");
}

View File

@ -705,6 +705,7 @@ public:
void copy_values(GrowableArray<jobject>* oops);
void copy_values(GrowableArray<Metadata*>* metadata);
void copy_values(GrowableArray<address>* metadata) {} // Nothing to do
// Relocation support
private:

View File

@ -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<address>;
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

View File

@ -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
@ -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<mtCode> {
private:
Arena _arena;
ValueRecorder<address> _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

View File

@ -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);
}

View File

@ -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
}

View File

@ -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);

View File

@ -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