8193325: StackFrameInfo::getByteCodeIndex returns wrong value if bci > 32767
authormchung
Thu, 15 Aug 2019 13:41:30 -0700
changeset 57763 47511761bd04
parent 57762 7a700a9a89f2
child 57764 2c66dbb94227
8193325: StackFrameInfo::getByteCodeIndex returns wrong value if bci > 32767 Reviewed-by: coleenp, fparain, shade, plevart
src/hotspot/share/classfile/javaClasses.cpp
src/java.base/share/classes/java/lang/StackFrameInfo.java
--- a/src/hotspot/share/classfile/javaClasses.cpp	Thu Aug 15 14:35:29 2019 +0200
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Thu Aug 15 13:41:30 2019 -0700
@@ -2677,14 +2677,14 @@
   Method* method = java_lang_StackFrameInfo::get_method(stackFrame, holder, CHECK);
 
   short version = stackFrame->short_field(_version_offset);
-  short bci = stackFrame->short_field(_bci_offset);
+  int bci = stackFrame->int_field(_bci_offset);
   Symbol* name = method->name();
   java_lang_StackTraceElement::fill_in(stack_trace_element, holder, method, version, bci, name, CHECK);
 }
 
 #define STACKFRAMEINFO_FIELDS_DO(macro) \
   macro(_memberName_offset,     k, "memberName",  object_signature, false); \
-  macro(_bci_offset,            k, "bci",         short_signature,  false)
+  macro(_bci_offset,            k, "bci",         int_signature,    false)
 
 void java_lang_StackFrameInfo::compute_offsets() {
   InstanceKlass* k = SystemDictionary::StackFrameInfo_klass();
@@ -4224,6 +4224,7 @@
 }
 
 void java_lang_StackFrameInfo::set_bci(oop element, int value) {
+  assert(value >= 0 && value < max_jushort, "must be a valid bci value");
   element->int_field_put(_bci_offset, value);
 }
 
--- a/src/java.base/share/classes/java/lang/StackFrameInfo.java	Thu Aug 15 14:35:29 2019 +0200
+++ b/src/java.base/share/classes/java/lang/StackFrameInfo.java	Thu Aug 15 13:41:30 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -31,23 +31,23 @@
 import java.lang.invoke.MethodType;
 
 class StackFrameInfo implements StackFrame {
-    private final byte RETAIN_CLASS_REF = 0x01;
-
     private final static JavaLangInvokeAccess JLIA =
         SharedSecrets.getJavaLangInvokeAccess();
 
-    private final byte flags;
-    private final Object memberName;
-    private final short bci;
+    private final boolean retainClassRef;
+    private final Object memberName;    // MemberName initialized by VM
+    private int bci;                    // initialized by VM to >= 0
     private volatile StackTraceElement ste;
 
     /*
-     * Create StackFrameInfo for StackFrameTraverser and LiveStackFrameTraverser
-     * to use
+     * Construct an empty StackFrameInfo object that will be filled by the VM
+     * during stack walking.
+     *
+     * @see StackStreamFactory.AbstractStackWalker#callStackWalk
+     * @see StackStreamFactory.AbstractStackWalker#fetchStackFrames
      */
     StackFrameInfo(StackWalker walker) {
-        this.flags = walker.retainClassRef ? RETAIN_CLASS_REF : 0;
-        this.bci = -1;
+        this.retainClassRef = walker.retainClassRef;
         this.memberName = JLIA.newMemberName();
     }
 
@@ -135,7 +135,7 @@
     }
 
     private void ensureRetainClassRefEnabled() {
-        if ((flags & RETAIN_CLASS_REF) == 0) {
+        if (!retainClassRef) {
             throw new UnsupportedOperationException("No access to RETAIN_CLASS_REFERENCE");
         }
     }