7046490: Preallocated OOME objects should obey Throwable stack trace protocol

Fri, 22 Jul 2011 00:29:01 -0700

author
dholmes
date
Fri, 22 Jul 2011 00:29:01 -0700
changeset 3018
0b80db433fcb
parent 3017
bcc6475bc68f
child 3019
8107273fd204

7046490: Preallocated OOME objects should obey Throwable stack trace protocol
Summary: Update the OOME stacktrace to contain Throwable.UNASSIGNED_STACK when the backtrace is filled in
Reviewed-by: mchung, phh

src/share/vm/classfile/javaClasses.cpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/javaClasses.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/classfile/javaClasses.cpp	Sat Jul 16 22:21:39 2011 -0400
     1.2 +++ b/src/share/vm/classfile/javaClasses.cpp	Fri Jul 22 00:29:01 2011 -0700
     1.3 @@ -1019,6 +1019,16 @@
     1.4    compute_offset(_ngroups_offset,     k, vmSymbols::ngroups_name(),     vmSymbols::int_signature());
     1.5  }
     1.6  
     1.7 +oop java_lang_Throwable::unassigned_stacktrace() {
     1.8 +  instanceKlass* ik = instanceKlass::cast(SystemDictionary::Throwable_klass());
     1.9 +  address addr = ik->static_field_addr(static_unassigned_stacktrace_offset);
    1.10 +  if (UseCompressedOops) {
    1.11 +    return oopDesc::load_decode_heap_oop((narrowOop *)addr);
    1.12 +  } else {
    1.13 +    return oopDesc::load_decode_heap_oop((oop*)addr);
    1.14 +  }
    1.15 +}
    1.16 +
    1.17  oop java_lang_Throwable::backtrace(oop throwable) {
    1.18    return throwable->obj_field_acquire(backtrace_offset);
    1.19  }
    1.20 @@ -1044,9 +1054,13 @@
    1.21  }
    1.22  
    1.23  
    1.24 +void java_lang_Throwable::set_stacktrace(oop throwable, oop st_element_array) {
    1.25 +  throwable->obj_field_put(stackTrace_offset, st_element_array);
    1.26 +}
    1.27 +
    1.28  void java_lang_Throwable::clear_stacktrace(oop throwable) {
    1.29    assert(JDK_Version::is_gte_jdk14x_version(), "should only be called in >= 1.4");
    1.30 -  throwable->obj_field_put(stackTrace_offset, NULL);
    1.31 +  set_stacktrace(throwable, NULL);
    1.32  }
    1.33  
    1.34  
    1.35 @@ -1340,6 +1354,7 @@
    1.36    if (JDK_Version::is_gte_jdk14x_version()) {
    1.37      // New since 1.4, clear lazily constructed Java level stacktrace if
    1.38      // refilling occurs
    1.39 +    // This is unnecessary in 1.7+ but harmless
    1.40      clear_stacktrace(throwable());
    1.41    }
    1.42  
    1.43 @@ -1541,6 +1556,15 @@
    1.44      // Bail-out for deep stacks
    1.45      if (chunk_count >= max_chunks) break;
    1.46    }
    1.47 +
    1.48 +  // For Java 7+ we support the Throwable immutability protocol defined for Java 7. This support
    1.49 +  // was missing in 7u0 so in 7u0 there is a workaround in the Throwable class. That workaround
    1.50 +  // can be removed in a JDK using this JVM version
    1.51 +  if (JDK_Version::is_gte_jdk17x_version()) {
    1.52 +      java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace());
    1.53 +      assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized");
    1.54 +  }
    1.55 +
    1.56  }
    1.57  
    1.58  
    1.59 @@ -2770,6 +2794,7 @@
    1.60  int java_lang_Throwable::detailMessage_offset;
    1.61  int java_lang_Throwable::cause_offset;
    1.62  int java_lang_Throwable::stackTrace_offset;
    1.63 +int java_lang_Throwable::static_unassigned_stacktrace_offset;
    1.64  int java_lang_reflect_AccessibleObject::override_offset;
    1.65  int java_lang_reflect_Method::clazz_offset;
    1.66  int java_lang_reflect_Method::name_offset;
    1.67 @@ -2947,6 +2972,7 @@
    1.68    java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header;
    1.69    java_lang_Throwable::cause_offset      = java_lang_Throwable::hc_cause_offset      * x + header;
    1.70    java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header;
    1.71 +  java_lang_Throwable::static_unassigned_stacktrace_offset = java_lang_Throwable::hc_static_unassigned_stacktrace_offset *  x;
    1.72  
    1.73    // java_lang_boxing_object
    1.74    java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset + header;
     2.1 --- a/src/share/vm/classfile/javaClasses.hpp	Sat Jul 16 22:21:39 2011 -0400
     2.2 +++ b/src/share/vm/classfile/javaClasses.hpp	Fri Jul 22 00:29:01 2011 -0700
     2.3 @@ -393,6 +393,9 @@
     2.4      hc_cause_offset         =  2,  // New since 1.4
     2.5      hc_stackTrace_offset    =  3   // New since 1.4
     2.6    };
     2.7 +  enum {
     2.8 +      hc_static_unassigned_stacktrace_offset = 0  // New since 1.7
     2.9 +  };
    2.10    // Trace constants
    2.11    enum {
    2.12      trace_methods_offset = 0,
    2.13 @@ -406,6 +409,7 @@
    2.14    static int detailMessage_offset;
    2.15    static int cause_offset;
    2.16    static int stackTrace_offset;
    2.17 +  static int static_unassigned_stacktrace_offset;
    2.18  
    2.19    // Printing
    2.20    static char* print_stack_element_to_buffer(methodOop method, int bci);
    2.21 @@ -414,6 +418,9 @@
    2.22    static void clear_stacktrace(oop throwable);
    2.23    // No stack trace available
    2.24    static const char* no_stack_trace_message();
    2.25 +  // Stacktrace (post JDK 1.7.0 to allow immutability protocol to be followed)
    2.26 +  static void set_stacktrace(oop throwable, oop st_element_array);
    2.27 +  static oop unassigned_stacktrace();
    2.28  
    2.29   public:
    2.30    // Backtrace
    2.31 @@ -438,7 +445,6 @@
    2.32    static void allocate_backtrace(Handle throwable, TRAPS);
    2.33    // Fill in current stack trace for throwable with preallocated backtrace (no GC)
    2.34    static void fill_in_stack_trace_of_preallocated_backtrace(Handle throwable);
    2.35 -
    2.36    // Fill in current stack trace, can cause GC
    2.37    static void fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS);
    2.38    static void fill_in_stack_trace(Handle throwable, methodHandle method = methodHandle());

mercurial