Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8321509: False positive in get_trampoline fast path causes crash #3441

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

bulasevich
Copy link

@bulasevich bulasevich commented Apr 4, 2025

This change is a backport of JDK-8321509.

Note. This change adds two functions to trampoline_stub_Relocation class. On macos-aarch64 platform it triggers clang to report:

/Users/runner/work/jdk17u-dev/jdk17u-dev/src/hotspot/share/code/relocInfo.hpp:1212:8: error: 'pack_data_to' overrides a member function but is not marked 'override' [-Werror,-Winconsistent-missing-override]
  void pack_data_to(CodeSection * dest);
       ^
   ... (rest of output omitted)

Indeed, trampoline_stub_Relocation::pack_data_to overrides the virtual Relocation::pack_data_to. To fix the issue, I added the override keyword to the declaration of both pack_data_to and unpack_data in the trampoline_stub_Relocation class. To minimize changes, I did not modify other classes.

Also, it required a manual merge due to minor discrepancies between the mainline and jdk17u repositories. The reasons for the manual intervention are as follows:

  • Copyright Year
    • The mainline patch updated the copyright from 2023 to 2024
    • In jdk17u the year is still 2021
  • NULL -> nullptr conversion
    • mainline deals with nullptr after JDK-8301493: Replace NULL with nullptr in cpu/aarch64
  • CodeBlob Lookup Changes
    • on the mainline "JDK-8290025: Remove the Sweeper" changed CodeCache::find_blob_unsafe call to CodeCache::find_blob
    • in jdk17u the old variant is used

See the minor mismatches below. Left: original diff on JDK mainline. Right: diff actually applied

diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp b/src/ho    diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp b/src/ho
--- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp                    --- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp                    +++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp
@@ -1,5 +1,5 @@                                                         @@ -1,5 +1,5 @@
 /*                                                                      /*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All righ |  - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All righ
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All righ    + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All righ
  * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.           * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *                                                                       *
@@ -158,13 +158,18 @@ void NativeGotJump::verify() const {              @@ -158,13 +158,18 @@ void NativeGotJump::verify() const {
 }                                                                       }

 address NativeCall::destination() const {                               address NativeCall::destination() const {
-  address addr = (address)this;                                        -  address addr = (address)this;
-  address destination = instruction_address() + displacement();        -  address destination = instruction_address() + displacement();
+  address addr = instruction_address();                                +  address addr = instruction_address();
+  address destination = addr + displacement();                         +  address destination = addr + displacement();
+                                                                       +
+  // Performance optimization: no need to call find_blob() if it is    +  // Performance optimization: no need to call find_blob() if it is
+  if (destination == addr) {                                           +  if (destination == addr) {
+    return destination;                                                +    return destination;
+  }                                                                    +  }

   // Do we use a trampoline stub for this call?                           // Do we use a trampoline stub for this call?
   CodeBlob* cb = CodeCache::find_blob(addr);                        |     CodeBlob* cb = CodeCache::find_blob_unsafe(addr);   // Else we get assertion if nmethod is zombie.
-  assert(cb && cb->is_nmethod(), "sanity");                            -  assert(cb && cb->is_nmethod(), "sanity");
-  nmethod *nm = (nmethod *)cb;                                         -  nmethod *nm = (nmethod *)cb;
+  assert(cb != nullptr && cb->is_nmethod(), "nmethod expected");       +  assert(cb != nullptr && cb->is_nmethod(), "nmethod expected");
+  nmethod *nm = cb->as_nmethod();                                      +  nmethod *nm = cb->as_nmethod();
   if (nm->stub_contains(destination) && is_NativeCallTrampolineStub       if (nm->stub_contains(destination) && is_NativeCallTrampolineStub
     // Yes we do, so get the destination from the trampoline stub.          // Yes we do, so get the destination from the trampoline stub.
     const address trampoline_stub_addr = destination;                       const address trampoline_stub_addr = destination;
@@ -211,22 +212,18 @@ void NativeCall::set_destination_mt_safe(addre    @@ -211,22 +212,18 @@ void NativeCall::set_destination_mt_safe(addre
 }                                                                       }

 address NativeCall::get_trampoline() {                                  address NativeCall::get_trampoline() {
-  address call_addr = addr_at(0);                                      -  address call_addr = addr_at(0);
+  address call_addr = instruction_address();                           +  address call_addr = instruction_address();

   CodeBlob *code = CodeCache::find_blob(call_addr);                       CodeBlob *code = CodeCache::find_blob(call_addr);
-  assert(code != nullptr, "Could not find the containing code blob" |  -  assert(code != NULL, "Could not find the containing code blob");
+  assert(code != nullptr && code->is_nmethod(), "nmethod expected")    +  assert(code != nullptr && code->is_nmethod(), "nmethod expected")
+  nmethod* nm = code->as_nmethod();                                    +  nmethod* nm = code->as_nmethod();

-  address bl_destination                                               -  address bl_destination
-    = MacroAssembler::pd_call_destination(call_addr);                  -    = MacroAssembler::pd_call_destination(call_addr);
-  if (code->contains(bl_destination) &&                                -  if (code->contains(bl_destination) &&
+  address bl_destination = call_addr + displacement();                 +  address bl_destination = call_addr + displacement();
+  if (nm->stub_contains(bl_destination) &&                             +  if (nm->stub_contains(bl_destination) &&
       is_NativeCallTrampolineStub_at(bl_destination))                         is_NativeCallTrampolineStub_at(bl_destination))
     return bl_destination;                                                  return bl_destination;

-  if (code->is_nmethod()) {                                            -  if (code->is_nmethod()) {
-    return trampoline_stub_Relocation::get_trampoline_for(call_addr    -    return trampoline_stub_Relocation::get_trampoline_for(call_addr
-  }                                                                    -  }
-                                                                       -
-  return nullptr;                                                   |  -  return NULL;
+  return trampoline_stub_Relocation::get_trampoline_for(call_addr,     +  return trampoline_stub_Relocation::get_trampoline_for(call_addr,
 }                                                                       }

 // Inserts a native call instruction at a given pc                      // Inserts a native call instruction at a given pc
diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp b/src/ho    diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp b/src/ho
--- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp                    --- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp                    +++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp
@@ -1,5 +1,5 @@                                                         @@ -1,5 +1,5 @@
 /*                                                                      /*
- * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All righ |  - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All righ
+ * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All righ    + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All righ
  * Copyright (c) 2014, 2108, Red Hat Inc. All rights reserved.           * Copyright (c) 2014, 2108, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *                                                                       *
diff --git a/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp b/src/hot    diff --git a/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp b/src/hot
--- a/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp                     --- a/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp                     +++ b/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp
@@ -60,13 +60,12 @@ void Relocation::pd_set_data_value(address x, in    @@ -60,13 +60,12 @@ void Relocation::pd_set_data_value(address x, in

 address Relocation::pd_call_destination(address orig_addr) {            address Relocation::pd_call_destination(address orig_addr) {
   assert(is_call(), "should be a call here");                             assert(is_call(), "should be a call here");
-  if (NativeCall::is_call_at(addr())) {                                -  if (NativeCall::is_call_at(addr())) {
-    address trampoline = nativeCall_at(addr())->get_trampoline();      -    address trampoline = nativeCall_at(addr())->get_trampoline();
-    if (trampoline) {                                                  -    if (trampoline) {
-      return nativeCallTrampolineStub_at(trampoline)->destination()    -      return nativeCallTrampolineStub_at(trampoline)->destination()
+  if (orig_addr == nullptr) {                                          +  if (orig_addr == nullptr) {
+    if (NativeCall::is_call_at(addr())) {                              +    if (NativeCall::is_call_at(addr())) {
+      NativeCall* call = nativeCall_at(addr());                        +      NativeCall* call = nativeCall_at(addr());
+      return call->destination();                                      +      return call->destination();
     }                                                                       }
-  }                                                                    -  }
-  if (orig_addr != nullptr) {                                       |  -  if (orig_addr != NULL) {
+  } else {                                                             +  } else {
     address new_addr = MacroAssembler::pd_call_destination(orig_add         address new_addr = MacroAssembler::pd_call_destination(orig_add
     // If call is branch to self, don't try to relocate it, just le         // If call is branch to self, don't try to relocate it, just le
     // as branch to self. This happens during code generation if th         // as branch to self. This happens during code generation if th

Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • JDK-8321509 needs maintainer approval

Issue

  • JDK-8321509: False positive in get_trampoline fast path causes crash (Bug - P3)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk17u-dev.git pull/3441/head:pull/3441
$ git checkout pull/3441

Update a local copy of the PR:
$ git checkout pull/3441
$ git pull https://git.openjdk.org/jdk17u-dev.git pull/3441/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 3441

View PR using the GUI difftool:
$ git pr show -t 3441

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk17u-dev/pull/3441.diff

@bridgekeeper
Copy link

bridgekeeper bot commented Apr 4, 2025

👋 Welcome back bulasevich! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Apr 4, 2025

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk openjdk bot changed the title Backport 73e3e0edeb20c6f701b213423476f92fb05dd262 8321509: False positive in get_trampoline fast path causes crash Apr 4, 2025
@openjdk
Copy link

openjdk bot commented Apr 4, 2025

This backport pull request has now been updated with issue from the original commit.

@openjdk openjdk bot added the backport label Apr 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

1 participant