8337396: Cleanup usage of ExternalAddess
Co-authored-by: Fei Yang <fyang@openjdk.org> Reviewed-by: vlivanov, adinn
This commit is contained in:
parent
7deee74525
commit
34edc7358f
src/hotspot
cpu
aarch64
riscv
x86
share/code
@ -736,7 +736,7 @@ void MacroAssembler::reserved_stack_check() {
|
||||
br(Assembler::LO, no_reserved_zone_enabling);
|
||||
|
||||
enter(); // LR and FP are live.
|
||||
lea(rscratch1, CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone));
|
||||
lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone)));
|
||||
mov(c_rarg0, rthread);
|
||||
blr(rscratch1);
|
||||
leave();
|
||||
@ -1879,7 +1879,7 @@ void MacroAssembler::_verify_oop(Register reg, const char* s, const char* file,
|
||||
movptr(rscratch1, (uintptr_t)(address)b);
|
||||
|
||||
// call indirectly to solve generation ordering problem
|
||||
lea(rscratch2, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
|
||||
lea(rscratch2, RuntimeAddress(StubRoutines::verify_oop_subroutine_entry_address()));
|
||||
ldr(rscratch2, Address(rscratch2));
|
||||
blr(rscratch2);
|
||||
|
||||
@ -1918,7 +1918,7 @@ void MacroAssembler::_verify_oop_addr(Address addr, const char* s, const char* f
|
||||
movptr(rscratch1, (uintptr_t)(address)b);
|
||||
|
||||
// call indirectly to solve generation ordering problem
|
||||
lea(rscratch2, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
|
||||
lea(rscratch2, RuntimeAddress(StubRoutines::verify_oop_subroutine_entry_address()));
|
||||
ldr(rscratch2, Address(rscratch2));
|
||||
blr(rscratch2);
|
||||
|
||||
@ -6454,7 +6454,7 @@ void MacroAssembler::verify_cross_modify_fence_not_required() {
|
||||
Label fence_not_required;
|
||||
cbz(rscratch1, fence_not_required);
|
||||
// If it does then fail.
|
||||
lea(rscratch1, CAST_FROM_FN_PTR(address, JavaThread::verify_cross_modify_fence_failure));
|
||||
lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::verify_cross_modify_fence_failure)));
|
||||
mov(c_rarg0, rthread);
|
||||
blr(rscratch1);
|
||||
bind(fence_not_required);
|
||||
|
@ -7045,7 +7045,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
Label thaw_success;
|
||||
// rscratch2 contains the size of the frames to thaw, 0 if overflow or no more frames
|
||||
__ cbnz(rscratch2, thaw_success);
|
||||
__ lea(rscratch1, ExternalAddress(StubRoutines::throw_StackOverflowError_entry()));
|
||||
__ lea(rscratch1, RuntimeAddress(StubRoutines::throw_StackOverflowError_entry()));
|
||||
__ br(rscratch1);
|
||||
__ bind(thaw_success);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -1337,8 +1337,8 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
{
|
||||
Label L;
|
||||
__ ldr(r10, Address(rmethod, Method::native_function_offset()));
|
||||
address unsatisfied = (SharedRuntime::native_method_throw_unsatisfied_link_error_entry());
|
||||
__ mov(rscratch2, unsatisfied);
|
||||
ExternalAddress unsatisfied(SharedRuntime::native_method_throw_unsatisfied_link_error_entry());
|
||||
__ lea(rscratch2, unsatisfied);
|
||||
__ ldr(rscratch2, rscratch2);
|
||||
__ cmp(r10, rscratch2);
|
||||
__ br(Assembler::NE, L);
|
||||
@ -1432,7 +1432,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
// hand.
|
||||
//
|
||||
__ mov(c_rarg0, rthread);
|
||||
__ mov(rscratch2, CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans));
|
||||
__ lea(rscratch2, RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)));
|
||||
__ blr(rscratch2);
|
||||
__ get_method(rmethod);
|
||||
__ reinit_heapbase();
|
||||
@ -1482,7 +1482,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
|
||||
__ push_call_clobbered_registers();
|
||||
__ mov(c_rarg0, rthread);
|
||||
__ mov(rscratch2, CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages));
|
||||
__ lea(rscratch2, RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)));
|
||||
__ blr(rscratch2);
|
||||
__ pop_call_clobbered_registers();
|
||||
|
||||
@ -2085,7 +2085,7 @@ void TemplateInterpreterGenerator::trace_bytecode(Template* t) {
|
||||
|
||||
assert(Interpreter::trace_code(t->tos_in()) != nullptr,
|
||||
"entry must have been generated");
|
||||
__ bl(Interpreter::trace_code(t->tos_in()));
|
||||
__ bl(RuntimeAddress(Interpreter::trace_code(t->tos_in())));
|
||||
__ reinit_heapbase();
|
||||
}
|
||||
|
||||
|
@ -547,7 +547,7 @@ void MacroAssembler::_verify_oop(Register reg, const char* s, const char* file,
|
||||
}
|
||||
|
||||
// call indirectly to solve generation ordering problem
|
||||
ExternalAddress target(StubRoutines::verify_oop_subroutine_entry_address());
|
||||
RuntimeAddress target(StubRoutines::verify_oop_subroutine_entry_address());
|
||||
relocate(target.rspec(), [&] {
|
||||
int32_t offset;
|
||||
la(t1, target.target(), offset);
|
||||
@ -592,7 +592,7 @@ void MacroAssembler::_verify_oop_addr(Address addr, const char* s, const char* f
|
||||
}
|
||||
|
||||
// call indirectly to solve generation ordering problem
|
||||
ExternalAddress target(StubRoutines::verify_oop_subroutine_entry_address());
|
||||
RuntimeAddress target(StubRoutines::verify_oop_subroutine_entry_address());
|
||||
relocate(target.rspec(), [&] {
|
||||
int32_t offset;
|
||||
la(t1, target.target(), offset);
|
||||
|
@ -3774,7 +3774,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
Label thaw_success;
|
||||
// t1 contains the size of the frames to thaw, 0 if overflow or no more frames
|
||||
__ bnez(t1, thaw_success);
|
||||
__ la(t0, ExternalAddress(StubRoutines::throw_StackOverflowError_entry()));
|
||||
__ la(t0, RuntimeAddress(StubRoutines::throw_StackOverflowError_entry()));
|
||||
__ jr(t0);
|
||||
__ bind(thaw_success);
|
||||
|
||||
|
@ -1111,8 +1111,8 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
{
|
||||
Label L;
|
||||
__ ld(x28, Address(xmethod, Method::native_function_offset()));
|
||||
address unsatisfied = (SharedRuntime::native_method_throw_unsatisfied_link_error_entry());
|
||||
__ mv(t, unsatisfied);
|
||||
ExternalAddress unsatisfied(SharedRuntime::native_method_throw_unsatisfied_link_error_entry());
|
||||
__ la(t, unsatisfied);
|
||||
__ load_long_misaligned(t1, Address(t, 0), t0, 2); // 2 bytes aligned, but not 4 or 8
|
||||
|
||||
__ bne(x28, t1, L);
|
||||
@ -1815,7 +1815,7 @@ void TemplateInterpreterGenerator::trace_bytecode(Template* t) {
|
||||
// the tosca in-state for the given template.
|
||||
|
||||
assert(Interpreter::trace_code(t->tos_in()) != nullptr, "entry must have been generated");
|
||||
__ call(Interpreter::trace_code(t->tos_in()));
|
||||
__ rt_call(Interpreter::trace_code(t->tos_in()));
|
||||
__ reinit_heapbase();
|
||||
}
|
||||
|
||||
|
@ -3702,7 +3702,7 @@ address StubGenerator::generate_cont_thaw(const char* label, Continuation::thaw_
|
||||
Label L_thaw_success;
|
||||
__ testptr(rbx, rbx);
|
||||
__ jccb(Assembler::notZero, L_thaw_success);
|
||||
__ jump(ExternalAddress(StubRoutines::throw_StackOverflowError_entry()));
|
||||
__ jump(RuntimeAddress(StubRoutines::throw_StackOverflowError_entry()));
|
||||
__ bind(L_thaw_success);
|
||||
|
||||
// Make room for the thawed frames and align the stack.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -178,7 +178,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(
|
||||
rarg, rarg2);
|
||||
}
|
||||
// throw exception
|
||||
__ jump(ExternalAddress(Interpreter::throw_exception_entry()));
|
||||
__ jump(RuntimeAddress(Interpreter::throw_exception_entry()));
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ -546,7 +546,7 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(void) {
|
||||
// Note: the restored frame is not necessarily interpreted.
|
||||
// Use the shared runtime version of the StackOverflowError.
|
||||
assert(StubRoutines::throw_StackOverflowError_entry() != nullptr, "stub not yet generated");
|
||||
__ jump(ExternalAddress(StubRoutines::throw_StackOverflowError_entry()));
|
||||
__ jump(RuntimeAddress(StubRoutines::throw_StackOverflowError_entry()));
|
||||
// all done with frame size check
|
||||
__ bind(after_frame_check_pop);
|
||||
NOT_LP64(__ pop(rsi));
|
||||
|
@ -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
|
||||
@ -774,7 +774,7 @@ void TemplateTable::index_check_without_pop(Register array, Register index) {
|
||||
__ jccb(Assembler::below, skip);
|
||||
// Pass array to create more detailed exceptions.
|
||||
__ mov(NOT_LP64(rax) LP64_ONLY(c_rarg1), array);
|
||||
__ jump(ExternalAddress(Interpreter::_throw_ArrayIndexOutOfBoundsException_entry));
|
||||
__ jump(RuntimeAddress(Interpreter::_throw_ArrayIndexOutOfBoundsException_entry));
|
||||
__ bind(skip);
|
||||
}
|
||||
|
||||
@ -1152,7 +1152,7 @@ void TemplateTable::aastore() {
|
||||
|
||||
// Come here on failure
|
||||
// object is at TOS
|
||||
__ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry));
|
||||
__ jump(RuntimeAddress(Interpreter::_throw_ArrayStoreException_entry));
|
||||
|
||||
// Come here on success
|
||||
__ bind(ok_is_subtype);
|
||||
@ -1432,7 +1432,7 @@ void TemplateTable::ldiv() {
|
||||
// generate explicit div0 check
|
||||
__ testq(rcx, rcx);
|
||||
__ jump_cc(Assembler::zero,
|
||||
ExternalAddress(Interpreter::_throw_ArithmeticException_entry));
|
||||
RuntimeAddress(Interpreter::_throw_ArithmeticException_entry));
|
||||
// Note: could xor rax and rcx and compare with (-1 ^ min_int). If
|
||||
// they are not equal, one could do a normal division (no correction
|
||||
// needed), which may speed up this implementation for the common case.
|
||||
@ -1445,7 +1445,7 @@ void TemplateTable::ldiv() {
|
||||
// check if y = 0
|
||||
__ orl(rax, rdx);
|
||||
__ jump_cc(Assembler::zero,
|
||||
ExternalAddress(Interpreter::_throw_ArithmeticException_entry));
|
||||
RuntimeAddress(Interpreter::_throw_ArithmeticException_entry));
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::ldiv));
|
||||
__ addptr(rsp, 4 * wordSize); // take off temporaries
|
||||
#endif
|
||||
@ -1458,7 +1458,7 @@ void TemplateTable::lrem() {
|
||||
__ pop_l(rax);
|
||||
__ testq(rcx, rcx);
|
||||
__ jump_cc(Assembler::zero,
|
||||
ExternalAddress(Interpreter::_throw_ArithmeticException_entry));
|
||||
RuntimeAddress(Interpreter::_throw_ArithmeticException_entry));
|
||||
// Note: could xor rax and rcx and compare with (-1 ^ min_int). If
|
||||
// they are not equal, one could do a normal division (no correction
|
||||
// needed), which may speed up this implementation for the common case.
|
||||
@ -1472,7 +1472,7 @@ void TemplateTable::lrem() {
|
||||
// check if y = 0
|
||||
__ orl(rax, rdx);
|
||||
__ jump_cc(Assembler::zero,
|
||||
ExternalAddress(Interpreter::_throw_ArithmeticException_entry));
|
||||
RuntimeAddress(Interpreter::_throw_ArithmeticException_entry));
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::lrem));
|
||||
__ addptr(rsp, 4 * wordSize);
|
||||
#endif
|
||||
@ -4222,7 +4222,7 @@ void TemplateTable::checkcast() {
|
||||
// Come here on failure
|
||||
__ push_ptr(rdx);
|
||||
// object is at TOS
|
||||
__ jump(ExternalAddress(Interpreter::_throw_ClassCastException_entry));
|
||||
__ jump(RuntimeAddress(Interpreter::_throw_ClassCastException_entry));
|
||||
|
||||
// Come here on success
|
||||
__ bind(ok_is_subtype);
|
||||
@ -4340,7 +4340,7 @@ void TemplateTable::_breakpoint() {
|
||||
void TemplateTable::athrow() {
|
||||
transition(atos, vtos);
|
||||
__ null_check(rax);
|
||||
__ jump(ExternalAddress(Interpreter::throw_exception_entry()));
|
||||
__ jump(RuntimeAddress(Interpreter::throw_exception_entry()));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/jniHandles.inline.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "utilities/copy.hpp"
|
||||
|
||||
#ifdef ASSERT
|
||||
@ -220,6 +221,11 @@ ExternalsRecorder* ExternalsRecorder::_recorder = nullptr;
|
||||
|
||||
ExternalsRecorder::ExternalsRecorder(): _arena(mtCode), _externals(&_arena) {}
|
||||
|
||||
#ifndef PRODUCT
|
||||
static int total_access_count = 0;
|
||||
static GrowableArray<int>* extern_hist = nullptr;
|
||||
#endif
|
||||
|
||||
void ExternalsRecorder_init() {
|
||||
ExternalsRecorder::initialize();
|
||||
}
|
||||
@ -228,30 +234,106 @@ void ExternalsRecorder::initialize() {
|
||||
// After Mutex and before CodeCache are initialized
|
||||
assert(_recorder == nullptr, "should initialize only once");
|
||||
_recorder = new ExternalsRecorder();
|
||||
#ifndef PRODUCT
|
||||
if (PrintNMethodStatistics) {
|
||||
Arena* arena = &_recorder->_arena;
|
||||
extern_hist = new(arena) GrowableArray<int>(arena, 512, 512, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
MutexLocker ml(ExternalsRecorder_lock, Mutex::_no_safepoint_check_flag);
|
||||
int index = _recorder->_externals.find_index(adr);
|
||||
#ifndef PRODUCT
|
||||
if (PrintNMethodStatistics) {
|
||||
total_access_count++;
|
||||
int n = extern_hist->at_grow(index, 0);
|
||||
extern_hist->at_put(index, (n + 1));
|
||||
}
|
||||
#endif
|
||||
return index;
|
||||
}
|
||||
|
||||
address ExternalsRecorder::at(int index) {
|
||||
assert(_recorder != nullptr, "sanity");
|
||||
// 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");
|
||||
MutexLocker ml(ExternalsRecorder_lock, Mutex::_no_safepoint_check_flag);
|
||||
return _recorder->_externals.count();
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
extern "C" {
|
||||
// Order from large to small values
|
||||
static int count_cmp(const void *i, const void *j) {
|
||||
int a = *(int*)i;
|
||||
int b = *(int*)j;
|
||||
return a < b ? 1 : a > b ? -1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ExternalsRecorder::print_statistics() {
|
||||
tty->print_cr("External addresses table: %d entries", count());
|
||||
int cnt = count();
|
||||
tty->print_cr("External addresses table: %d entries, %d accesses", cnt, total_access_count);
|
||||
{ // Print most accessed entries in the table.
|
||||
int* array = NEW_C_HEAP_ARRAY(int, (2 * cnt), mtCode);
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
array[(2 * i) + 0] = extern_hist->at(i);
|
||||
array[(2 * i) + 1] = i;
|
||||
}
|
||||
// Reverse sort to have "hottest" addresses first.
|
||||
qsort(array, cnt, 2*sizeof(int), count_cmp);
|
||||
// Print all entries with Verbose flag otherwise only top 5.
|
||||
int limit = (Verbose || cnt <= 5) ? cnt : 5;
|
||||
int j = 0;
|
||||
for (int i = 0; i < limit; i++) {
|
||||
int index = array[(2 * i) + 1];
|
||||
int n = extern_hist->at(index);
|
||||
if (n > 0) {
|
||||
address addr = at(index);
|
||||
tty->print("%d: %8d " INTPTR_FORMAT " :", j++, n, p2i(addr));
|
||||
if (addr != nullptr) {
|
||||
if (StubRoutines::contains(addr)) {
|
||||
StubCodeDesc* desc = StubCodeDesc::desc_for(addr);
|
||||
if (desc == nullptr) {
|
||||
desc = StubCodeDesc::desc_for(addr + frame::pc_return_offset);
|
||||
}
|
||||
const char* stub_name = (desc != nullptr) ? desc->name() : "<unknown>";
|
||||
tty->print(" stub: %s", stub_name);
|
||||
} else {
|
||||
ResourceMark rm;
|
||||
const int buflen = 1024;
|
||||
char* buf = NEW_RESOURCE_ARRAY(char, buflen);
|
||||
int offset = 0;
|
||||
if (os::dll_address_to_function_name(addr, buf, buflen, &offset)) {
|
||||
tty->print(" extn: %s", buf);
|
||||
if (offset != 0) {
|
||||
tty->print("+%d", offset);
|
||||
}
|
||||
} else {
|
||||
if (CodeCache::contains((void*)addr)) {
|
||||
// Something in CodeCache
|
||||
tty->print(" in CodeCache");
|
||||
} else {
|
||||
// It could be string
|
||||
memcpy(buf, (char*)addr, 80);
|
||||
buf[80] = '\0';
|
||||
tty->print(" '%s'", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tty->cr();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user