hotspot/src/share/vm/classfile/javaClasses.cpp
changeset 34273 8598d07915d9
parent 34253 ba3946143842
child 34280 72bfaaffee36
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Tue Nov 24 09:02:26 2015 +0000
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Tue Nov 24 10:12:11 2015 -0800
@@ -1518,11 +1518,43 @@
 // After this many redefines, the stack trace is unreliable.
 const int MAX_VERSION = USHRT_MAX;
 
+// Helper backtrace functions to store bci|version together.
+static inline int merge_bci_and_version(int bci, int version) {
+  // only store u2 for version, checking for overflow.
+  if (version > USHRT_MAX || version < 0) version = MAX_VERSION;
+  assert((jushort)bci == bci, "bci should be short");
+  return build_int_from_shorts(version, bci);
+}
+
+static inline int bci_at(unsigned int merged) {
+  return extract_high_short_from_int(merged);
+}
+static inline int version_at(unsigned int merged) {
+  return extract_low_short_from_int(merged);
+}
+
 static inline bool version_matches(Method* method, int version) {
   assert(version < MAX_VERSION, "version is too big");
   return method != NULL && (method->constants()->version() == version);
 }
 
+static inline int get_line_number(Method* method, int bci) {
+  int line_number = 0;
+  if (method->is_native()) {
+    // Negative value different from -1 below, enabling Java code in
+    // class java.lang.StackTraceElement to distinguish "native" from
+    // "no LineNumberTable".  JDK tests for -2.
+    line_number = -2;
+  } else {
+    // Returns -1 if no LineNumberTable, and otherwise actual line number
+    line_number = method->line_number_from_bci(bci);
+    if (line_number == -1 && ShowHiddenFrames) {
+      line_number = bci + 1000000;
+    }
+  }
+  return line_number;
+}
+
 // This class provides a simple wrapper over the internal structure of
 // exception backtrace to insulate users of the backtrace from needing
 // to know what it looks like.
@@ -1644,7 +1676,7 @@
     }
 
     _methods->short_at_put(_index, method->orig_method_idnum());
-    _bcis->int_at_put(_index, Backtrace::merge_bci_and_version(bci, method->constants()->version()));
+    _bcis->int_at_put(_index, merge_bci_and_version(bci, method->constants()->version()));
     _cprefs->short_at_put(_index, method->name_index());
 
     // We need to save the mirrors in the backtrace to keep the class
@@ -1656,6 +1688,19 @@
 
 };
 
+Symbol* get_source_file_name(InstanceKlass* holder, int version) {
+  // Find the specific ik version that contains this source_file_name_index
+  // via the previous versions list, but use the current version's
+  // constant pool to look it up.  The previous version's index has been
+  // merged for the current constant pool.
+  InstanceKlass* ik = holder->get_klass_version(version);
+  // This version has been cleaned up.
+  if (ik == NULL) return NULL;
+  int source_file_name_index = ik->source_file_name_index();
+  return (source_file_name_index == 0) ?
+      (Symbol*)NULL : holder->constants()->symbol_at(source_file_name_index);
+}
+
 // Print stack trace element to resource allocated buffer
 char* java_lang_Throwable::print_stack_element_to_buffer(Handle mirror,
                                   int method_id, int version, int bci, int cpref) {
@@ -1673,7 +1718,7 @@
   buf_len += (int)strlen(method_name);
 
   char* source_file_name = NULL;
-  Symbol* source = Backtrace::get_source_file_name(holder, version);
+  Symbol* source = get_source_file_name(holder, version);
   if (source != NULL) {
     source_file_name = source->as_C_string();
     buf_len += (int)strlen(source_file_name);
@@ -1688,7 +1733,7 @@
   if (!version_matches(method, version)) {
     strcat(buf, "(Redefined)");
   } else {
-    int line_number = Backtrace::get_line_number(method, bci);
+    int line_number = get_line_number(method, bci);
     if (line_number == -2) {
       strcat(buf, "(Native Method)");
     } else {
@@ -1757,8 +1802,8 @@
         // NULL mirror means end of stack trace
         if (mirror.is_null()) goto handle_cause;
         int method = methods->short_at(index);
-        int version = Backtrace::version_at(bcis->int_at(index));
-        int bci = Backtrace::bci_at(bcis->int_at(index));
+        int version = version_at(bcis->int_at(index));
+        int bci = bci_at(bcis->int_at(index));
         int cpref = cprefs->short_at(index);
         print_stack_element(st, mirror, method, version, bci, cpref);
       }
@@ -2045,8 +2090,8 @@
   assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check");
 
   int method = methods->short_at(chunk_index);
-  int version = Backtrace::version_at(bcis->int_at(chunk_index));
-  int bci = Backtrace::bci_at(bcis->int_at(chunk_index));
+  int version = version_at(bcis->int_at(chunk_index));
+  int bci = bci_at(bcis->int_at(chunk_index));
   int cpref = cprefs->short_at(chunk_index);
   Handle mirror(THREAD, mirrors->obj_at(chunk_index));
 
@@ -2069,7 +2114,6 @@
   }
 
   Handle element = ik->allocate_instance_handle(CHECK_0);
-
   // Fill in class name
   ResourceMark rm(THREAD);
   InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
@@ -2092,13 +2136,13 @@
     java_lang_StackTraceElement::set_lineNumber(element(), -1);
   } else {
     // Fill in source file name and line number.
-    Symbol* source = Backtrace::get_source_file_name(holder, version);
+    Symbol* source = get_source_file_name(holder, version);
     if (ShowHiddenFrames && source == NULL)
       source = vmSymbols::unknown_class_name();
     oop filename = StringTable::intern(source, CHECK_0);
     java_lang_StackTraceElement::set_fileName(element(), filename);
 
-    int line_number = Backtrace::get_line_number(method, bci);
+    int line_number = get_line_number(method, bci);
     java_lang_StackTraceElement::set_lineNumber(element(), line_number);
   }
   return element();
@@ -2111,108 +2155,6 @@
   return create(mirror, method_id, method->constants()->version(), bci, cpref, THREAD);
 }
 
-Method* java_lang_StackFrameInfo::get_method(Handle stackFrame, InstanceKlass* holder, TRAPS) {
-  if (MemberNameInStackFrame) {
-    Handle mname(THREAD, stackFrame->obj_field(_memberName_offset));
-    Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mname());
-    // we should expand MemberName::name when Throwable uses StackTrace
-    // MethodHandles::expand_MemberName(mname, MethodHandles::_suppress_defc|MethodHandles::_suppress_type, CHECK_NULL);
-    return method;
-  } else {
-    short mid       = stackFrame->short_field(_mid_offset);
-    short version   = stackFrame->short_field(_version_offset);
-    return holder->method_with_orig_idnum(mid, version);
-  }
-}
-
-Symbol* java_lang_StackFrameInfo::get_file_name(Handle stackFrame, InstanceKlass* holder) {
-  if (MemberNameInStackFrame) {
-    return holder->source_file_name();
-  } else {
-    short version = stackFrame->short_field(_version_offset);
-    return Backtrace::get_source_file_name(holder, version);
-  }
-}
-
-void java_lang_StackFrameInfo::set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci) {
-  // set Method* or mid/cpref
-  if (MemberNameInStackFrame) {
-    oop mname = stackFrame->obj_field(_memberName_offset);
-    InstanceKlass* ik = method->method_holder();
-    CallInfo info(method(), ik);
-    MethodHandles::init_method_MemberName(mname, info);
-  } else {
-    int mid = method->orig_method_idnum();
-    int cpref = method->name_index();
-    assert((jushort)mid == mid,        "mid should be short");
-    assert((jushort)cpref == cpref,    "cpref should be short");
-    java_lang_StackFrameInfo::set_mid(stackFrame(),     (short)mid);
-    java_lang_StackFrameInfo::set_cpref(stackFrame(),   (short)cpref);
-  }
-  // set bci
-  java_lang_StackFrameInfo::set_bci(stackFrame(), bci);
-  // method may be redefined; store the version
-  int version = method->constants()->version();
-  assert((jushort)version == version, "version should be short");
-  java_lang_StackFrameInfo::set_version(stackFrame(), (short)version);
-}
-
-void java_lang_StackFrameInfo::fill_methodInfo(Handle stackFrame, TRAPS) {
-  ResourceMark rm(THREAD);
-  oop k = stackFrame->obj_field(_declaringClass_offset);
-  InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k));
-  Method* method = java_lang_StackFrameInfo::get_method(stackFrame, holder, CHECK);
-  int bci = stackFrame->int_field(_bci_offset);
-
-  // The method can be NULL if the requested class version is gone
-  Symbol* sym = (method != NULL) ? method->name() : NULL;
-  if (MemberNameInStackFrame) {
-    assert(sym != NULL, "MemberName must have method name");
-  } else {
-      // The method can be NULL if the requested class version is gone
-    if (sym == NULL) {
-      short cpref   = stackFrame->short_field(_cpref_offset);
-      sym = holder->constants()->symbol_at(cpref);
-    }
-  }
-
-  // set method name
-  oop methodname = StringTable::intern(sym, CHECK);
-  java_lang_StackFrameInfo::set_methodName(stackFrame(), methodname);
-
-  // set file name and line number
-  Symbol* source = get_file_name(stackFrame, holder);
-  if (source != NULL) {
-    oop filename = StringTable::intern(source, CHECK);
-    java_lang_StackFrameInfo::set_fileName(stackFrame(), filename);
-  }
-
-  // if the method has been redefined, the bci is no longer applicable
-  short version = stackFrame->short_field(_version_offset);
-  if (version_matches(method, version)) {
-    int line_number = Backtrace::get_line_number(method, bci);
-    java_lang_StackFrameInfo::set_lineNumber(stackFrame(), line_number);
-  }
-}
-
-void java_lang_StackFrameInfo::compute_offsets() {
-  Klass* k = SystemDictionary::StackFrameInfo_klass();
-  compute_offset(_declaringClass_offset, k, vmSymbols::declaringClass_name(),  vmSymbols::class_signature());
-  compute_offset(_memberName_offset,     k, vmSymbols::memberName_name(),  vmSymbols::object_signature());
-  compute_offset(_bci_offset,            k, vmSymbols::bci_name(),         vmSymbols::int_signature());
-  compute_offset(_methodName_offset,     k, vmSymbols::methodName_name(),  vmSymbols::string_signature());
-  compute_offset(_fileName_offset,       k, vmSymbols::fileName_name(),    vmSymbols::string_signature());
-  compute_offset(_lineNumber_offset,     k, vmSymbols::lineNumber_name(),  vmSymbols::int_signature());
-  STACKFRAMEINFO_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
-}
-
-void java_lang_LiveStackFrameInfo::compute_offsets() {
-  Klass* k = SystemDictionary::LiveStackFrameInfo_klass();
-  compute_offset(_monitors_offset,   k, vmSymbols::monitors_name(),    vmSymbols::object_array_signature());
-  compute_offset(_locals_offset,     k, vmSymbols::locals_name(),      vmSymbols::object_array_signature());
-  compute_offset(_operands_offset,   k, vmSymbols::operands_name(),    vmSymbols::object_array_signature());
-}
-
 void java_lang_reflect_AccessibleObject::compute_offsets() {
   Klass* k = SystemDictionary::reflect_AccessibleObject_klass();
   compute_offset(override_offset, k, vmSymbols::override_name(), vmSymbols::bool_signature());
@@ -3529,18 +3471,6 @@
 int java_lang_StackTraceElement::methodName_offset;
 int java_lang_StackTraceElement::fileName_offset;
 int java_lang_StackTraceElement::lineNumber_offset;
-int java_lang_StackFrameInfo::_declaringClass_offset;
-int java_lang_StackFrameInfo::_memberName_offset;
-int java_lang_StackFrameInfo::_bci_offset;
-int java_lang_StackFrameInfo::_methodName_offset;
-int java_lang_StackFrameInfo::_fileName_offset;
-int java_lang_StackFrameInfo::_lineNumber_offset;
-int java_lang_StackFrameInfo::_mid_offset;
-int java_lang_StackFrameInfo::_version_offset;
-int java_lang_StackFrameInfo::_cpref_offset;
-int java_lang_LiveStackFrameInfo::_monitors_offset;
-int java_lang_LiveStackFrameInfo::_locals_offset;
-int java_lang_LiveStackFrameInfo::_operands_offset;
 int java_lang_AssertionStatusDirectives::classes_offset;
 int java_lang_AssertionStatusDirectives::classEnabled_offset;
 int java_lang_AssertionStatusDirectives::packages_offset;
@@ -3570,50 +3500,6 @@
   element->int_field_put(lineNumber_offset, value);
 }
 
-// Support for java_lang_StackFrameInfo
-void java_lang_StackFrameInfo::set_declaringClass(oop element, oop value) {
-  element->obj_field_put(_declaringClass_offset, value);
-}
-
-void java_lang_StackFrameInfo::set_mid(oop element, short value) {
-  element->short_field_put(_mid_offset, value);
-}
-
-void java_lang_StackFrameInfo::set_version(oop element, short value) {
-  element->short_field_put(_version_offset, value);
-}
-
-void java_lang_StackFrameInfo::set_cpref(oop element, short value) {
-  element->short_field_put(_cpref_offset, value);
-}
-
-void java_lang_StackFrameInfo::set_bci(oop element, int value) {
-  element->int_field_put(_bci_offset, value);
-}
-
-void java_lang_StackFrameInfo::set_fileName(oop element, oop value) {
-  element->obj_field_put(_fileName_offset, value);
-}
-
-void java_lang_StackFrameInfo::set_methodName(oop element, oop value) {
-  element->obj_field_put(_methodName_offset, value);
-}
-
-void java_lang_StackFrameInfo::set_lineNumber(oop element, int value) {
-  element->int_field_put(_lineNumber_offset, value);
-}
-
-void java_lang_LiveStackFrameInfo::set_monitors(oop element, oop value) {
-  element->obj_field_put(_monitors_offset, value);
-}
-
-void java_lang_LiveStackFrameInfo::set_locals(oop element, oop value) {
-  element->obj_field_put(_locals_offset, value);
-}
-
-void java_lang_LiveStackFrameInfo::set_operands(oop element, oop value) {
-  element->obj_field_put(_operands_offset, value);
-}
 
 // Support for java Assertions - java_lang_AssertionStatusDirectives.
 
@@ -3747,8 +3633,6 @@
   sun_reflect_ConstantPool::compute_offsets();
   sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets();
   java_lang_reflect_Parameter::compute_offsets();
-  java_lang_StackFrameInfo::compute_offsets();
-  java_lang_LiveStackFrameInfo::compute_offsets();
 
   // generated interpreter code wants to know about the offsets we just computed:
   AbstractAssembler::update_delayed_values();