@@ -1498,6 +1498,40 @@ nmethod::nmethod(const nmethod &nm) : CodeBlob(nm._name, nm._kind, nm._size, nm.
14981498 // - OOP table
14991499 memcpy (consts_begin (), nm.consts_begin (), nm.data_end () - nm.consts_begin ());
15001500
1501+ // Fix relocation
1502+ RelocIterator iter (this );
1503+ CodeBuffer src (&nm);
1504+ CodeBuffer dst (this );
1505+ while (iter.next ()) {
1506+ #ifdef USE_TRAMPOLINE_STUB_FIX_OWNER
1507+ // After an nmethod is moved, some direct call sites may end up out of range.
1508+ // CallRelocation::fix_relocation_after_move() assumes the target is always
1509+ // reachable and does not check branch range. Calling it without range checks
1510+ // could cause us to write an offset too large for the instruction.
1511+ //
1512+ // If a call site has a trampoline, we skip the normal call relocation. The
1513+ // associated trampoline_stub_Relocation will handle the call and the
1514+ // trampoline, including range checks and updating the branch as needed.
1515+ //
1516+ // If no trampoline exists, we can assume the call target is always
1517+ // reachable and therefore within direct branch range, so calling
1518+ // CallRelocation::fix_relocation_after_move() is safe.
1519+ if (iter.reloc ()->is_call ()) {
1520+ address trampoline = trampoline_stub_Relocation::get_trampoline_for (iter.reloc ()->addr (), this );
1521+ if (trampoline != nullptr ) {
1522+ continue ;
1523+ }
1524+ }
1525+ #endif
1526+
1527+ iter.reloc ()->fix_relocation_after_move (&src, &dst);
1528+ }
1529+
1530+ {
1531+ MutexLocker ml (NMethodState_lock, Mutex::_no_safepoint_check_flag);
1532+ clear_inline_caches ();
1533+ }
1534+
15011535 post_init ();
15021536}
15031537
@@ -1521,25 +1555,6 @@ nmethod* nmethod::relocate(CodeBlobType code_blob_type) {
15211555 return nullptr ;
15221556 }
15231557
1524- // Fix relocation
1525- RelocIterator iter (nm_copy);
1526- CodeBuffer src (this );
1527- CodeBuffer dst (nm_copy);
1528- while (iter.next ()) {
1529- #ifdef USE_TRAMPOLINE_STUB_FIX_OWNER
1530- // Direct calls may no longer be in range and the use of a trampoline may now be required.
1531- // Instead, allow trampoline relocations to update their owners and perform the necessary checks.
1532- if (iter.reloc ()->is_call ()) {
1533- address trampoline = trampoline_stub_Relocation::get_trampoline_for (iter.reloc ()->addr (), nm_copy);
1534- if (trampoline != nullptr ) {
1535- continue ;
1536- }
1537- }
1538- #endif
1539-
1540- iter.reloc ()->fix_relocation_after_move (&src, &dst);
1541- }
1542-
15431558 // To make dependency checking during class loading fast, record
15441559 // the nmethod dependencies in the classes it is dependent on.
15451560 // This allows the dependency checking code to simply walk the
@@ -1569,16 +1584,14 @@ nmethod* nmethod::relocate(CodeBlobType code_blob_type) {
15691584 if (!is_marked_for_deoptimization () && is_in_use ()) {
15701585 assert (method () != nullptr && method ()->code () == this , " should be if is in use" );
15711586
1572- nm_copy->clear_inline_caches ();
1573-
15741587 // Attempt to start using the copy
15751588 if (nm_copy->make_in_use ()) {
15761589 ICache::invalidate_range (nm_copy->code_begin (), nm_copy->code_size ());
15771590
15781591 methodHandle mh (Thread::current (), nm_copy->method ());
15791592 nm_copy->method ()->set_code (mh, nm_copy);
15801593
1581- make_not_used ( );
1594+ make_not_entrant (InvalidationReason::RELOCATED );
15821595
15831596 nm_copy->post_compiled_method_load_event ();
15841597
0 commit comments