Sat, 23 Jul 2011 10:42:20 -0400
Merge
1.1 --- a/make/jprt.gmk Fri Jul 22 23:42:46 2011 -0700 1.2 +++ b/make/jprt.gmk Sat Jul 23 10:42:20 2011 -0400 1.3 @@ -34,13 +34,13 @@ 1.4 endif 1.5 1.6 jprt_build_productEmb: 1.7 - $(MAKE) JAVASE_EMBEDDED=true jprt_build_product 1.8 + $(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_product 1.9 1.10 jprt_build_debugEmb: 1.11 - $(MAKE) JAVASE_EMBEDDED=true jprt_build_debug 1.12 + $(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_debug 1.13 1.14 jprt_build_fastdebugEmb: 1.15 - $(MAKE) JAVASE_EMBEDDED=true jprt_build_fastdebug 1.16 + $(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_fastdebug 1.17 1.18 jprt_build_productOpen: 1.19 $(MAKE) OPENJDK=true jprt_build_product
2.1 --- a/src/share/vm/classfile/javaClasses.cpp Fri Jul 22 23:42:46 2011 -0700 2.2 +++ b/src/share/vm/classfile/javaClasses.cpp Sat Jul 23 10:42:20 2011 -0400 2.3 @@ -1019,6 +1019,16 @@ 2.4 compute_offset(_ngroups_offset, k, vmSymbols::ngroups_name(), vmSymbols::int_signature()); 2.5 } 2.6 2.7 +oop java_lang_Throwable::unassigned_stacktrace() { 2.8 + instanceKlass* ik = instanceKlass::cast(SystemDictionary::Throwable_klass()); 2.9 + address addr = ik->static_field_addr(static_unassigned_stacktrace_offset); 2.10 + if (UseCompressedOops) { 2.11 + return oopDesc::load_decode_heap_oop((narrowOop *)addr); 2.12 + } else { 2.13 + return oopDesc::load_decode_heap_oop((oop*)addr); 2.14 + } 2.15 +} 2.16 + 2.17 oop java_lang_Throwable::backtrace(oop throwable) { 2.18 return throwable->obj_field_acquire(backtrace_offset); 2.19 } 2.20 @@ -1044,9 +1054,13 @@ 2.21 } 2.22 2.23 2.24 +void java_lang_Throwable::set_stacktrace(oop throwable, oop st_element_array) { 2.25 + throwable->obj_field_put(stackTrace_offset, st_element_array); 2.26 +} 2.27 + 2.28 void java_lang_Throwable::clear_stacktrace(oop throwable) { 2.29 assert(JDK_Version::is_gte_jdk14x_version(), "should only be called in >= 1.4"); 2.30 - throwable->obj_field_put(stackTrace_offset, NULL); 2.31 + set_stacktrace(throwable, NULL); 2.32 } 2.33 2.34 2.35 @@ -1340,6 +1354,7 @@ 2.36 if (JDK_Version::is_gte_jdk14x_version()) { 2.37 // New since 1.4, clear lazily constructed Java level stacktrace if 2.38 // refilling occurs 2.39 + // This is unnecessary in 1.7+ but harmless 2.40 clear_stacktrace(throwable()); 2.41 } 2.42 2.43 @@ -1541,6 +1556,15 @@ 2.44 // Bail-out for deep stacks 2.45 if (chunk_count >= max_chunks) break; 2.46 } 2.47 + 2.48 + // For Java 7+ we support the Throwable immutability protocol defined for Java 7. This support 2.49 + // was missing in 7u0 so in 7u0 there is a workaround in the Throwable class. That workaround 2.50 + // can be removed in a JDK using this JVM version 2.51 + if (JDK_Version::is_gte_jdk17x_version()) { 2.52 + java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace()); 2.53 + assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized"); 2.54 + } 2.55 + 2.56 } 2.57 2.58 2.59 @@ -2770,6 +2794,7 @@ 2.60 int java_lang_Throwable::detailMessage_offset; 2.61 int java_lang_Throwable::cause_offset; 2.62 int java_lang_Throwable::stackTrace_offset; 2.63 +int java_lang_Throwable::static_unassigned_stacktrace_offset; 2.64 int java_lang_reflect_AccessibleObject::override_offset; 2.65 int java_lang_reflect_Method::clazz_offset; 2.66 int java_lang_reflect_Method::name_offset; 2.67 @@ -2947,6 +2972,7 @@ 2.68 java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header; 2.69 java_lang_Throwable::cause_offset = java_lang_Throwable::hc_cause_offset * x + header; 2.70 java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header; 2.71 + java_lang_Throwable::static_unassigned_stacktrace_offset = java_lang_Throwable::hc_static_unassigned_stacktrace_offset * x; 2.72 2.73 // java_lang_boxing_object 2.74 java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset + header;
3.1 --- a/src/share/vm/classfile/javaClasses.hpp Fri Jul 22 23:42:46 2011 -0700 3.2 +++ b/src/share/vm/classfile/javaClasses.hpp Sat Jul 23 10:42:20 2011 -0400 3.3 @@ -393,6 +393,9 @@ 3.4 hc_cause_offset = 2, // New since 1.4 3.5 hc_stackTrace_offset = 3 // New since 1.4 3.6 }; 3.7 + enum { 3.8 + hc_static_unassigned_stacktrace_offset = 0 // New since 1.7 3.9 + }; 3.10 // Trace constants 3.11 enum { 3.12 trace_methods_offset = 0, 3.13 @@ -406,6 +409,7 @@ 3.14 static int detailMessage_offset; 3.15 static int cause_offset; 3.16 static int stackTrace_offset; 3.17 + static int static_unassigned_stacktrace_offset; 3.18 3.19 // Printing 3.20 static char* print_stack_element_to_buffer(methodOop method, int bci); 3.21 @@ -414,6 +418,9 @@ 3.22 static void clear_stacktrace(oop throwable); 3.23 // No stack trace available 3.24 static const char* no_stack_trace_message(); 3.25 + // Stacktrace (post JDK 1.7.0 to allow immutability protocol to be followed) 3.26 + static void set_stacktrace(oop throwable, oop st_element_array); 3.27 + static oop unassigned_stacktrace(); 3.28 3.29 public: 3.30 // Backtrace 3.31 @@ -438,7 +445,6 @@ 3.32 static void allocate_backtrace(Handle throwable, TRAPS); 3.33 // Fill in current stack trace for throwable with preallocated backtrace (no GC) 3.34 static void fill_in_stack_trace_of_preallocated_backtrace(Handle throwable); 3.35 - 3.36 // Fill in current stack trace, can cause GC 3.37 static void fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS); 3.38 static void fill_in_stack_trace(Handle throwable, methodHandle method = methodHandle());
4.1 --- a/src/share/vm/prims/jvmtiTagMap.cpp Fri Jul 22 23:42:46 2011 -0700 4.2 +++ b/src/share/vm/prims/jvmtiTagMap.cpp Sat Jul 23 10:42:20 2011 -0400 4.3 @@ -1647,6 +1647,7 @@ 4.4 // saved headers 4.5 static GrowableArray<oop>* _saved_oop_stack; 4.6 static GrowableArray<markOop>* _saved_mark_stack; 4.7 + static bool _needs_reset; // do we need to reset mark bits? 4.8 4.9 public: 4.10 static void init(); // initialize 4.11 @@ -1654,10 +1655,14 @@ 4.12 4.13 static inline void mark(oop o); // mark an object 4.14 static inline bool visited(oop o); // check if object has been visited 4.15 + 4.16 + static inline bool needs_reset() { return _needs_reset; } 4.17 + static inline void set_needs_reset(bool v) { _needs_reset = v; } 4.18 }; 4.19 4.20 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL; 4.21 GrowableArray<markOop>* ObjectMarker::_saved_mark_stack = NULL; 4.22 +bool ObjectMarker::_needs_reset = true; // need to reset mark bits by default 4.23 4.24 // initialize ObjectMarker - prepares for object marking 4.25 void ObjectMarker::init() { 4.26 @@ -1680,7 +1685,13 @@ 4.27 // iterate over all objects and restore the mark bits to 4.28 // their initial value 4.29 RestoreMarksClosure blk; 4.30 - Universe::heap()->object_iterate(&blk); 4.31 + if (needs_reset()) { 4.32 + Universe::heap()->object_iterate(&blk); 4.33 + } else { 4.34 + // We don't need to reset mark bits on this call, but reset the 4.35 + // flag to the default for the next call. 4.36 + set_needs_reset(true); 4.37 + } 4.38 4.39 // When sharing is enabled we need to restore the headers of the objects 4.40 // in the readwrite space too. 4.41 @@ -3023,7 +3034,8 @@ 4.42 } 4.43 4.44 4.45 -// collects all simple (non-stack) roots. 4.46 +// Collects all simple (non-stack) roots except for threads; 4.47 +// threads are handled in collect_stack_roots() as an optimization. 4.48 // if there's a heap root callback provided then the callback is 4.49 // invoked for each simple root. 4.50 // if an object reference callback is provided then all simple 4.51 @@ -3054,16 +3066,7 @@ 4.52 return false; 4.53 } 4.54 4.55 - // Threads 4.56 - for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) { 4.57 - oop threadObj = thread->threadObj(); 4.58 - if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) { 4.59 - bool cont = CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD, threadObj); 4.60 - if (!cont) { 4.61 - return false; 4.62 - } 4.63 - } 4.64 - } 4.65 + // threads are now handled in collect_stack_roots() 4.66 4.67 // Other kinds of roots maintained by HotSpot 4.68 // Many of these won't be visible but others (such as instances of important 4.69 @@ -3175,13 +3178,20 @@ 4.70 } 4.71 4.72 4.73 -// collects all stack roots - for each thread it walks the execution 4.74 +// Collects the simple roots for all threads and collects all 4.75 +// stack roots - for each thread it walks the execution 4.76 // stack to find all references and local JNI refs. 4.77 inline bool VM_HeapWalkOperation::collect_stack_roots() { 4.78 JNILocalRootsClosure blk; 4.79 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) { 4.80 oop threadObj = thread->threadObj(); 4.81 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) { 4.82 + // Collect the simple root for this thread before we 4.83 + // collect its stack roots 4.84 + if (!CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD, 4.85 + threadObj)) { 4.86 + return false; 4.87 + } 4.88 if (!collect_stack_roots(thread, &blk)) { 4.89 return false; 4.90 } 4.91 @@ -3235,8 +3245,20 @@ 4.92 4.93 // the heap walk starts with an initial object or the heap roots 4.94 if (initial_object().is_null()) { 4.95 + // If either collect_stack_roots() or collect_simple_roots() 4.96 + // returns false at this point, then there are no mark bits 4.97 + // to reset. 4.98 + ObjectMarker::set_needs_reset(false); 4.99 + 4.100 + // Calling collect_stack_roots() before collect_simple_roots() 4.101 + // can result in a big performance boost for an agent that is 4.102 + // focused on analyzing references in the thread stacks. 4.103 + if (!collect_stack_roots()) return; 4.104 + 4.105 if (!collect_simple_roots()) return; 4.106 - if (!collect_stack_roots()) return; 4.107 + 4.108 + // no early return so enable heap traversal to reset the mark bits 4.109 + ObjectMarker::set_needs_reset(true); 4.110 } else { 4.111 visit_stack()->push(initial_object()()); 4.112 }