Skip to content

Commit

Permalink
Merge upstream-jdk
Browse files Browse the repository at this point in the history
  • Loading branch information
corretto-github-robot committed Oct 23, 2024
2 parents 30db771 + e1fab4b commit 9030389
Show file tree
Hide file tree
Showing 15 changed files with 348 additions and 149 deletions.
2 changes: 1 addition & 1 deletion src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ address NativeCall::destination() const {
//
// Used in the runtime linkage of calls; see class CompiledIC.
void NativeCall::set_destination_mt_safe(address dest) {
assert((Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
assert((CodeCache_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
CompiledICLocker::is_safe(addr_at(0)),
"concurrent code patching");

Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/cpu/ppc/nativeInst_ppc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ address NativeCall::destination() const {
// Used in the runtime linkage of calls; see class CompiledIC.
//
// Add parameter assert_lock to switch off assertion
// during code generation, where no patching lock is needed.
// during code generation, where no lock is needed.
void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) {
assert(!assert_lock ||
(Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
(CodeCache_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
CompiledICLocker::is_safe(addr_at(0)),
"concurrent code patching");

Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/cpu/riscv/nativeInst_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ address NativeCall::destination() const {
// Used in the runtime linkage of calls; see class CompiledIC.
//
// Add parameter assert_lock to switch off assertion
// during code generation, where no patching lock is needed.
// during code generation, where no lock is needed.
void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) {
assert(!assert_lock ||
(Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
(CodeCache_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
CompiledICLocker::is_safe(addr_at(0)),
"concurrent code patching");

Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/cpu/s390/nativeInst_s390.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,8 @@ void NativeGeneralJump::insert_unconditional(address code_pos, address entry) {

void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) {
assert(((intptr_t)instr_addr & (BytesPerWord-1)) == 0, "requirement for mt safe patching");
// Bytes_after_jump cannot change, because we own the Patching_lock.
assert(Patching_lock->owned_by_self(), "must hold lock to patch instruction");
// Bytes_after_jump cannot change, because we own the CodeCache_lock.
assert(CodeCache_lock->owned_by_self(), "must hold lock to patch instruction");
intptr_t bytes_after_jump = (*(intptr_t*)instr_addr) & 0x000000000000ffffL; // 2 bytes after jump.
intptr_t load_const_bytes = (*(intptr_t*)code_buffer) & 0xffffffffffff0000L;
*(intptr_t*)instr_addr = load_const_bytes | bytes_after_jump;
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/cpu/x86/nativeInst_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ void NativeCall::insert(address code_pos, address entry) {
// (spinlock). Then patches the last byte, and then atomically replaces
// the jmp's with the first 4 byte of the new instruction.
void NativeCall::replace_mt_safe(address instr_addr, address code_buffer) {
assert(Patching_lock->is_locked() ||
assert(CodeCache_lock->is_locked() ||
SafepointSynchronize::is_at_safepoint(), "concurrent code patching");
assert (instr_addr != nullptr, "illegal address for code patching");

Expand Down Expand Up @@ -281,7 +281,7 @@ void NativeCall::set_destination_mt_safe(address dest) {
debug_only(verify());
// Make sure patching code is locked. No two threads can patch at the same
// time but one may be executing this code.
assert(Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint() ||
assert(CodeCache_lock->is_locked() || SafepointSynchronize::is_at_safepoint() ||
CompiledICLocker::is_safe(instruction_address()), "concurrent code patching");
// Both C1 and C2 should now be generating code which aligns the patched address
// to be within a single cache line.
Expand Down
12 changes: 4 additions & 8 deletions src/hotspot/share/c1/c1_Runtime1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ static Klass* resolve_field_return_klass(const methodHandle& caller, int bci, TR
// movl reg, [reg1 + <const>] (for field offsets)
// jmp continue
// <being_init offset> <bytes to copy> <bytes to skip>
// patch_stub: jmp Runtim1::patch_code (through a runtime stub)
// patch_stub: jmp Runtime1::patch_code (through a runtime stub)
// jmp patch_site
//
// If the class is being initialized the patch body is rewritten and
Expand Down Expand Up @@ -1096,7 +1096,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* current, Runtime1::StubID stub_
// Now copy code back

{
MutexLocker ml_patch (current, Patching_lock, Mutex::_no_safepoint_check_flag);
MutexLocker ml_code (current, CodeCache_lock, Mutex::_no_safepoint_check_flag);
//
// Deoptimization may have happened while we waited for the lock.
// In that case we don't bother to do any patching we just return
Expand Down Expand Up @@ -1261,12 +1261,8 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* current, Runtime1::StubID stub_
}
}
}
}

// If we are patching in a non-perm oop, make sure the nmethod
// is on the right list.
{
MutexLocker ml_code (current, CodeCache_lock, Mutex::_no_safepoint_check_flag);
// If we are patching in a non-perm oop, make sure the nmethod
// is on the right list.
nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
guarantee(nm != nullptr, "only nmethods can contain non-perm oops");

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/code/nmethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2052,7 +2052,7 @@ bool nmethod::make_not_entrant() {
} // leave critical region under NMethodState_lock

#if INCLUDE_JVMCI
// Invalidate can't occur while holding the Patching lock
// Invalidate can't occur while holding the NMethodState_lock
JVMCINMethodData* nmethod_data = jvmci_nmethod_data();
if (nmethod_data != nullptr) {
nmethod_data->invalidate_nmethod_mirror(this);
Expand Down
143 changes: 73 additions & 70 deletions src/hotspot/share/opto/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3260,23 +3260,28 @@ void TypeRawPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
// Convenience common pre-built type.
const TypeOopPtr *TypeOopPtr::BOTTOM;

TypeInterfaces::TypeInterfaces()
: Type(Interfaces), _list(Compile::current()->type_arena(), 0, 0, nullptr),
TypeInterfaces::TypeInterfaces(ciInstanceKlass** interfaces_base, int nb_interfaces)
: Type(Interfaces), _interfaces(interfaces_base, nb_interfaces),
_hash(0), _exact_klass(nullptr) {
DEBUG_ONLY(_initialized = true);
}

TypeInterfaces::TypeInterfaces(GrowableArray<ciInstanceKlass*>* interfaces)
: Type(Interfaces), _list(Compile::current()->type_arena(), interfaces->length(), 0, nullptr),
_hash(0), _exact_klass(nullptr) {
for (int i = 0; i < interfaces->length(); i++) {
add(interfaces->at(i));
}
_interfaces.sort(compare);
initialize();
}

const TypeInterfaces* TypeInterfaces::make(GrowableArray<ciInstanceKlass*>* interfaces) {
TypeInterfaces* result = (interfaces == nullptr) ? new TypeInterfaces() : new TypeInterfaces(interfaces);
// hashcons() can only delete the last thing that was allocated: to
// make sure all memory for the newly created TypeInterfaces can be
// freed if an identical one exists, allocate space for the array of
// interfaces right after the TypeInterfaces object so that they
// form a contiguous piece of memory.
int nb_interfaces = interfaces == nullptr ? 0 : interfaces->length();
size_t total_size = sizeof(TypeInterfaces) + nb_interfaces * sizeof(ciInstanceKlass*);

void* allocated_mem = operator new(total_size);
ciInstanceKlass** interfaces_base = (ciInstanceKlass**)((char*)allocated_mem + sizeof(TypeInterfaces));
for (int i = 0; i < nb_interfaces; ++i) {
interfaces_base[i] = interfaces->at(i);
}
TypeInterfaces* result = ::new (allocated_mem) TypeInterfaces(interfaces_base, nb_interfaces);
return (const TypeInterfaces*)result->hashcons();
}

Expand All @@ -3295,20 +3300,18 @@ int TypeInterfaces::compare(ciInstanceKlass* const& k1, ciInstanceKlass* const&
return 0;
}

void TypeInterfaces::add(ciInstanceKlass* interface) {
assert(interface->is_interface(), "for interfaces only");
_list.insert_sorted<compare>(interface);
verify();
int TypeInterfaces::compare(ciInstanceKlass** k1, ciInstanceKlass** k2) {
return compare(*k1, *k2);
}

bool TypeInterfaces::eq(const Type* t) const {
const TypeInterfaces* other = (const TypeInterfaces*)t;
if (_list.length() != other->_list.length()) {
if (_interfaces.length() != other->_interfaces.length()) {
return false;
}
for (int i = 0; i < _list.length(); i++) {
ciKlass* k1 = _list.at(i);
ciKlass* k2 = other->_list.at(i);
for (int i = 0; i < _interfaces.length(); i++) {
ciKlass* k1 = _interfaces.at(i);
ciKlass* k2 = other->_interfaces.at(i);
if (!k1->equals(k2)) {
return false;
}
Expand All @@ -3319,12 +3322,12 @@ bool TypeInterfaces::eq(const Type* t) const {
bool TypeInterfaces::eq(ciInstanceKlass* k) const {
assert(k->is_loaded(), "should be loaded");
GrowableArray<ciInstanceKlass *>* interfaces = k->transitive_interfaces();
if (_list.length() != interfaces->length()) {
if (_interfaces.length() != interfaces->length()) {
return false;
}
for (int i = 0; i < interfaces->length(); i++) {
bool found = false;
_list.find_sorted<ciInstanceKlass*, compare>(interfaces->at(i), found);
_interfaces.find_sorted<ciInstanceKlass*, compare>(interfaces->at(i), found);
if (!found) {
return false;
}
Expand All @@ -3344,8 +3347,8 @@ const Type* TypeInterfaces::xdual() const {

void TypeInterfaces::compute_hash() {
uint hash = 0;
for (int i = 0; i < _list.length(); i++) {
ciKlass* k = _list.at(i);
for (int i = 0; i < _interfaces.length(); i++) {
ciKlass* k = _interfaces.at(i);
hash += k->hash();
}
_hash = hash;
Expand All @@ -3356,13 +3359,13 @@ static int compare_interfaces(ciInstanceKlass** k1, ciInstanceKlass** k2) {
}

void TypeInterfaces::dump(outputStream* st) const {
if (_list.length() == 0) {
if (_interfaces.length() == 0) {
return;
}
ResourceMark rm;
st->print(" (");
GrowableArray<ciInstanceKlass*> interfaces;
interfaces.appendAll(&_list);
interfaces.appendAll(&_interfaces);
// Sort the interfaces so they are listed in the same order from one run to the other of the same compilation
interfaces.sort(compare_interfaces);
for (int i = 0; i < interfaces.length(); i++) {
Expand All @@ -3377,9 +3380,9 @@ void TypeInterfaces::dump(outputStream* st) const {

#ifdef ASSERT
void TypeInterfaces::verify() const {
for (int i = 1; i < _list.length(); i++) {
ciInstanceKlass* k1 = _list.at(i-1);
ciInstanceKlass* k2 = _list.at(i);
for (int i = 1; i < _interfaces.length(); i++) {
ciInstanceKlass* k1 = _interfaces.at(i-1);
ciInstanceKlass* k2 = _interfaces.at(i);
assert(compare(k2, k1) > 0, "should be ordered");
assert(k1 != k2, "no duplicate");
}
Expand All @@ -3390,38 +3393,38 @@ const TypeInterfaces* TypeInterfaces::union_with(const TypeInterfaces* other) co
GrowableArray<ciInstanceKlass*> result_list;
int i = 0;
int j = 0;
while (i < _list.length() || j < other->_list.length()) {
while (i < _list.length() &&
(j >= other->_list.length() ||
compare(_list.at(i), other->_list.at(j)) < 0)) {
result_list.push(_list.at(i));
while (i < _interfaces.length() || j < other->_interfaces.length()) {
while (i < _interfaces.length() &&
(j >= other->_interfaces.length() ||
compare(_interfaces.at(i), other->_interfaces.at(j)) < 0)) {
result_list.push(_interfaces.at(i));
i++;
}
while (j < other->_list.length() &&
(i >= _list.length() ||
compare(other->_list.at(j), _list.at(i)) < 0)) {
result_list.push(other->_list.at(j));
while (j < other->_interfaces.length() &&
(i >= _interfaces.length() ||
compare(other->_interfaces.at(j), _interfaces.at(i)) < 0)) {
result_list.push(other->_interfaces.at(j));
j++;
}
if (i < _list.length() &&
j < other->_list.length() &&
_list.at(i) == other->_list.at(j)) {
result_list.push(_list.at(i));
if (i < _interfaces.length() &&
j < other->_interfaces.length() &&
_interfaces.at(i) == other->_interfaces.at(j)) {
result_list.push(_interfaces.at(i));
i++;
j++;
}
}
const TypeInterfaces* result = TypeInterfaces::make(&result_list);
#ifdef ASSERT
result->verify();
for (int i = 0; i < _list.length(); i++) {
assert(result->_list.contains(_list.at(i)), "missing");
for (int i = 0; i < _interfaces.length(); i++) {
assert(result->_interfaces.contains(_interfaces.at(i)), "missing");
}
for (int i = 0; i < other->_list.length(); i++) {
assert(result->_list.contains(other->_list.at(i)), "missing");
for (int i = 0; i < other->_interfaces.length(); i++) {
assert(result->_interfaces.contains(other->_interfaces.at(i)), "missing");
}
for (int i = 0; i < result->_list.length(); i++) {
assert(_list.contains(result->_list.at(i)) || other->_list.contains(result->_list.at(i)), "missing");
for (int i = 0; i < result->_interfaces.length(); i++) {
assert(_interfaces.contains(result->_interfaces.at(i)) || other->_interfaces.contains(result->_interfaces.at(i)), "missing");
}
#endif
return result;
Expand All @@ -3431,36 +3434,36 @@ const TypeInterfaces* TypeInterfaces::intersection_with(const TypeInterfaces* ot
GrowableArray<ciInstanceKlass*> result_list;
int i = 0;
int j = 0;
while (i < _list.length() || j < other->_list.length()) {
while (i < _list.length() &&
(j >= other->_list.length() ||
compare(_list.at(i), other->_list.at(j)) < 0)) {
while (i < _interfaces.length() || j < other->_interfaces.length()) {
while (i < _interfaces.length() &&
(j >= other->_interfaces.length() ||
compare(_interfaces.at(i), other->_interfaces.at(j)) < 0)) {
i++;
}
while (j < other->_list.length() &&
(i >= _list.length() ||
compare(other->_list.at(j), _list.at(i)) < 0)) {
while (j < other->_interfaces.length() &&
(i >= _interfaces.length() ||
compare(other->_interfaces.at(j), _interfaces.at(i)) < 0)) {
j++;
}
if (i < _list.length() &&
j < other->_list.length() &&
_list.at(i) == other->_list.at(j)) {
result_list.push(_list.at(i));
if (i < _interfaces.length() &&
j < other->_interfaces.length() &&
_interfaces.at(i) == other->_interfaces.at(j)) {
result_list.push(_interfaces.at(i));
i++;
j++;
}
}
const TypeInterfaces* result = TypeInterfaces::make(&result_list);
#ifdef ASSERT
result->verify();
for (int i = 0; i < _list.length(); i++) {
assert(!other->_list.contains(_list.at(i)) || result->_list.contains(_list.at(i)), "missing");
for (int i = 0; i < _interfaces.length(); i++) {
assert(!other->_interfaces.contains(_interfaces.at(i)) || result->_interfaces.contains(_interfaces.at(i)), "missing");
}
for (int i = 0; i < other->_list.length(); i++) {
assert(!_list.contains(other->_list.at(i)) || result->_list.contains(other->_list.at(i)), "missing");
for (int i = 0; i < other->_interfaces.length(); i++) {
assert(!_interfaces.contains(other->_interfaces.at(i)) || result->_interfaces.contains(other->_interfaces.at(i)), "missing");
}
for (int i = 0; i < result->_list.length(); i++) {
assert(_list.contains(result->_list.at(i)) && other->_list.contains(result->_list.at(i)), "missing");
for (int i = 0; i < result->_interfaces.length(); i++) {
assert(_interfaces.contains(result->_interfaces.at(i)) && other->_interfaces.contains(result->_interfaces.at(i)), "missing");
}
#endif
return result;
Expand All @@ -3473,13 +3476,13 @@ ciInstanceKlass* TypeInterfaces::exact_klass() const {
}

void TypeInterfaces::compute_exact_klass() {
if (_list.length() == 0) {
if (_interfaces.length() == 0) {
_exact_klass = nullptr;
return;
}
ciInstanceKlass* res = nullptr;
for (int i = 0; i < _list.length(); i++) {
ciInstanceKlass* interface = _list.at(i);
for (int i = 0; i < _interfaces.length(); i++) {
ciInstanceKlass* interface = _interfaces.at(i);
if (eq(interface)) {
assert(res == nullptr, "");
res = interface;
Expand All @@ -3490,8 +3493,8 @@ void TypeInterfaces::compute_exact_klass() {

#ifdef ASSERT
void TypeInterfaces::verify_is_loaded() const {
for (int i = 0; i < _list.length(); i++) {
ciKlass* interface = _list.at(i);
for (int i = 0; i < _interfaces.length(); i++) {
ciKlass* interface = _interfaces.at(i);
assert(interface->is_loaded(), "Interface not loaded");
}
}
Expand Down
Loading

0 comments on commit 9030389

Please sign in to comment.