Fri, 22 Jul 2011 00:29:01 -0700
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());