8204209: [Graal] Compilation fails during nmethod printing with "assert(bci == 0 || 0 <= bci && bci < code_size()) failed: illegal bci"
authoriveresov
Fri, 22 Jun 2018 15:58:32 -0700
changeset 50729 7755c93d3923
parent 50728 9375184cec98
child 50730 bba832d63b88
child 50731 ed322b4cfe49
8204209: [Graal] Compilation fails during nmethod printing with "assert(bci == 0 || 0 <= bci && bci < code_size()) failed: illegal bci" Summary: Tolerate JVMCI placeholder bcis Reviewed-by: kvn, never, dlong
src/hotspot/share/code/nmethod.cpp
src/hotspot/share/compiler/compilerDefinitions.hpp
src/hotspot/share/jvmci/jvmciCodeInstaller.cpp
src/hotspot/share/jvmci/jvmciCodeInstaller.hpp
src/hotspot/share/jvmci/jvmciJavaClasses.hpp
src/hotspot/share/oops/method.cpp
src/hotspot/share/prims/jvmtiCodeBlobEvents.cpp
--- a/src/hotspot/share/code/nmethod.cpp	Fri Jun 22 17:46:58 2018 -0400
+++ b/src/hotspot/share/code/nmethod.cpp	Fri Jun 22 15:58:32 2018 -0700
@@ -2599,6 +2599,16 @@
     st->move_to(column);
     if (sd->bci() == SynchronizationEntryBCI) {
       st->print(";*synchronization entry");
+    } else if (sd->bci() == AfterBci) {
+      st->print(";* method exit (unlocked if synchronized)");
+    } else if (sd->bci() == UnwindBci) {
+      st->print(";* unwind (locked if synchronized)");
+    } else if (sd->bci() == AfterExceptionBci) {
+      st->print(";* unwind (unlocked if synchronized)");
+    } else if (sd->bci() == UnknownBci) {
+      st->print(";* unknown");
+    } else if (sd->bci() == InvalidFrameStateBci) {
+      st->print(";* invalid frame state");
     } else {
       if (sd->method() == NULL) {
         st->print("method is NULL");
--- a/src/hotspot/share/compiler/compilerDefinitions.hpp	Fri Jun 22 17:46:58 2018 -0400
+++ b/src/hotspot/share/compiler/compilerDefinitions.hpp	Fri Jun 22 15:58:32 2018 -0700
@@ -41,7 +41,13 @@
 
 // Handy constants for deciding which compiler mode to use.
 enum MethodCompilation {
-  InvocationEntryBci = -1     // i.e., not a on-stack replacement compilation
+  InvocationEntryBci   = -1,     // i.e., not a on-stack replacement compilation
+  BeforeBci            = InvocationEntryBci,
+  AfterBci             = -2,
+  UnwindBci            = -3,
+  AfterExceptionBci    = -4,
+  UnknownBci           = -5,
+  InvalidFrameStateBci = -6
 };
 
 // Enumeration to distinguish tiers of compilation
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Fri Jun 22 17:46:58 2018 -0400
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Fri Jun 22 15:58:32 2018 -0700
@@ -1048,6 +1048,26 @@
   record_scope(pc_offset, position, scope_mode, objectMapping, return_oop, CHECK);
 }
 
+int CodeInstaller::map_jvmci_bci(int bci) {
+  if (bci < 0) {
+    if (bci == BytecodeFrame::BEFORE_BCI()) {
+      return BeforeBci;
+    } else if (bci == BytecodeFrame::AFTER_BCI()) {
+      return AfterBci;
+    } else if (bci == BytecodeFrame::UNWIND_BCI()) {
+      return UnwindBci;
+    } else if (bci == BytecodeFrame::AFTER_EXCEPTION_BCI()) {
+      return AfterExceptionBci;
+    } else if (bci == BytecodeFrame::UNKNOWN_BCI()) {
+      return UnknownBci;
+    } else if (bci == BytecodeFrame::INVALID_FRAMESTATE_BCI()) {
+      return InvalidFrameStateBci;
+    }
+    ShouldNotReachHere();
+  }
+  return bci;
+}
+
 void CodeInstaller::record_scope(jint pc_offset, Handle position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, bool return_oop, TRAPS) {
   Handle frame;
   if (scope_mode == CodeInstaller::FullFrame) {
@@ -1063,16 +1083,13 @@
 
   Handle hotspot_method (THREAD, BytecodePosition::method(position));
   Method* method = getMethodFromHotSpotMethod(hotspot_method());
-  jint bci = BytecodePosition::bci(position);
-  if (bci == BytecodeFrame::BEFORE_BCI()) {
-    bci = SynchronizationEntryBCI;
-  }
+  jint bci = map_jvmci_bci(BytecodePosition::bci(position));
 
   TRACE_jvmci_2("Recording scope pc_offset=%d bci=%d method=%s", pc_offset, bci, method->name_and_sig_as_C_string());
 
   bool reexecute = false;
   if (frame.not_null()) {
-    if (bci == SynchronizationEntryBCI){
+    if (bci < 0) {
        reexecute = false;
     } else {
       Bytecodes::Code code = Bytecodes::java_code_at(method, method->bcp_from(bci));
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.hpp	Fri Jun 22 17:46:58 2018 -0400
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.hpp	Fri Jun 22 15:58:32 2018 -0700
@@ -255,6 +255,7 @@
     FullFrame
   };
 
+  int map_jvmci_bci(int bci);
   void record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, bool return_oop, TRAPS);
   void record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, TRAPS) {
     record_scope(pc_offset, debug_info, scope_mode, false /* return_oop */, THREAD);
--- a/src/hotspot/share/jvmci/jvmciJavaClasses.hpp	Fri Jun 22 17:46:58 2018 -0400
+++ b/src/hotspot/share/jvmci/jvmciJavaClasses.hpp	Fri Jun 22 15:58:32 2018 -0700
@@ -210,7 +210,12 @@
     int_field(BytecodeFrame, numLocks)                                                                                                                         \
     boolean_field(BytecodeFrame, rethrowException)                                                                                                             \
     boolean_field(BytecodeFrame, duringCall)                                                                                                                   \
+    static_int_field(BytecodeFrame, UNKNOWN_BCI)                                                                                                               \
+    static_int_field(BytecodeFrame, UNWIND_BCI)                                                                                                                \
     static_int_field(BytecodeFrame, BEFORE_BCI)                                                                                                                \
+    static_int_field(BytecodeFrame, AFTER_BCI)                                                                                                                 \
+    static_int_field(BytecodeFrame, AFTER_EXCEPTION_BCI)                                                                                                       \
+    static_int_field(BytecodeFrame, INVALID_FRAMESTATE_BCI)                                                                                                    \
   end_class                                                                                                                                                    \
   start_class(BytecodePosition)                                                                                                                                \
     oop_field(BytecodePosition, caller, "Ljdk/vm/ci/code/BytecodePosition;")                                                                                   \
--- a/src/hotspot/share/oops/method.cpp	Fri Jun 22 17:46:58 2018 -0400
+++ b/src/hotspot/share/oops/method.cpp	Fri Jun 22 15:58:32 2018 -0700
@@ -690,12 +690,10 @@
 
 
 int Method::line_number_from_bci(int bci) const {
-  if (bci == SynchronizationEntryBCI) bci = 0;
-  assert(bci == 0 || 0 <= bci && bci < code_size(), "illegal bci");
   int best_bci  =  0;
   int best_line = -1;
-
-  if (has_linenumber_table()) {
+  if (bci == SynchronizationEntryBCI) bci = 0;
+  if (0 <= bci && bci < code_size() && has_linenumber_table()) {
     // The line numbers are a short array of 2-tuples [start_pc, line_number].
     // Not necessarily sorted and not necessarily one-to-one.
     CompressedLineNumberReadStream stream(compressed_linenumber_table());
--- a/src/hotspot/share/prims/jvmtiCodeBlobEvents.cpp	Fri Jun 22 17:46:58 2018 -0400
+++ b/src/hotspot/share/prims/jvmtiCodeBlobEvents.cpp	Fri Jun 22 15:58:32 2018 -0700
@@ -269,7 +269,7 @@
       ScopeDesc *sd  = &sc0;
       while( !sd->is_top() ) { sd = sd->sender(); }
       int bci = sd->bci();
-      if (bci != InvocationEntryBci) {
+      if (bci >= 0) {
         assert(map_length < pcds_in_method, "checking");
         map[map_length].start_address = (const void*)pcd->real_pc(nm);
         map[map_length].location = bci;