Tue, 14 Sep 2010 10:15:27 -0400
Merge
1.1 --- a/.hgtags Fri Sep 10 12:36:47 2010 -0400 1.2 +++ b/.hgtags Tue Sep 14 10:15:27 2010 -0400 1.3 @@ -114,4 +114,6 @@ 1.4 1b81ca701fa5fc30adc4cfdaa4bdd153df5e6c86 jdk7-b106 1.5 cc3fdfeb54b049f18edcf3463e6ab051d0b7b609 hs19-b05 1.6 688a538aa65412178286ae2a6b0c00b6711e121b hs19-b06 1.7 +bf496cbe9b74dda5975a1559da7ecfdd313e509e jdk7-b107 1.8 0000000000000000000000000000000000000000 hs19-b06 1.9 +6c43216df13513a0f96532aa06f213066c49e27b hs19-b06
2.1 --- a/make/hotspot_version Fri Sep 10 12:36:47 2010 -0400 2.2 +++ b/make/hotspot_version Tue Sep 14 10:15:27 2010 -0400 2.3 @@ -33,9 +33,9 @@ 2.4 # Don't put quotes (fail windows build). 2.5 HOTSPOT_VM_COPYRIGHT=Copyright 2010 2.6 2.7 -HS_MAJOR_VER=19 2.8 +HS_MAJOR_VER=20 2.9 HS_MINOR_VER=0 2.10 -HS_BUILD_NUMBER=06 2.11 +HS_BUILD_NUMBER=01 2.12 2.13 JDK_MAJOR_VER=1 2.14 JDK_MINOR_VER=7
3.1 --- a/src/share/vm/services/heapDumper.cpp Fri Sep 10 12:36:47 2010 -0400 3.2 +++ b/src/share/vm/services/heapDumper.cpp Tue Sep 14 10:15:27 2010 -0400 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -1305,6 +1305,8 @@ 3.11 static VM_HeapDumper* _global_dumper; 3.12 static DumpWriter* _global_writer; 3.13 DumpWriter* _local_writer; 3.14 + JavaThread* _oome_thread; 3.15 + methodOop _oome_constructor; 3.16 bool _gc_before_heap_dump; 3.17 bool _is_segmented_dump; 3.18 jlong _dump_start; 3.19 @@ -1366,7 +1368,7 @@ 3.20 void end_of_dump(); 3.21 3.22 public: 3.23 - VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump) : 3.24 + VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump, bool oome) : 3.25 VM_GC_Operation(0 /* total collections, dummy, ignored */, 3.26 0 /* total full collections, dummy, ignored */, 3.27 gc_before_heap_dump) { 3.28 @@ -1377,6 +1379,18 @@ 3.29 _klass_map = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true); 3.30 _stack_traces = NULL; 3.31 _num_threads = 0; 3.32 + if (oome) { 3.33 + assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread"); 3.34 + // get OutOfMemoryError zero-parameter constructor 3.35 + instanceKlass* oome_ik = instanceKlass::cast(SystemDictionary::OutOfMemoryError_klass()); 3.36 + _oome_constructor = oome_ik->find_method(vmSymbols::object_initializer_name(), 3.37 + vmSymbols::void_method_signature()); 3.38 + // get thread throwing OOME when generating the heap dump at OOME 3.39 + _oome_thread = JavaThread::current(); 3.40 + } else { 3.41 + _oome_thread = NULL; 3.42 + _oome_constructor = NULL; 3.43 + } 3.44 } 3.45 ~VM_HeapDumper() { 3.46 if (_stack_traces != NULL) { 3.47 @@ -1557,7 +1571,11 @@ 3.48 frame f = java_thread->last_frame(); 3.49 vframe* vf = vframe::new_vframe(&f, ®_map, java_thread); 3.50 frame* last_entry_frame = NULL; 3.51 + int extra_frames = 0; 3.52 3.53 + if (java_thread == _oome_thread && _oome_constructor != NULL) { 3.54 + extra_frames++; 3.55 + } 3.56 while (vf != NULL) { 3.57 blk.set_frame_number(stack_depth); 3.58 if (vf->is_java_frame()) { 3.59 @@ -1574,7 +1592,7 @@ 3.60 writer()->write_u1(HPROF_GC_ROOT_JAVA_FRAME); 3.61 writer()->write_objectID(o); 3.62 writer()->write_u4(thread_serial_num); 3.63 - writer()->write_u4((u4) stack_depth); 3.64 + writer()->write_u4((u4) (stack_depth + extra_frames)); 3.65 } 3.66 } 3.67 } 3.68 @@ -1764,6 +1782,17 @@ 3.69 // write HPROF_FRAME records for this thread's stack trace 3.70 int depth = stack_trace->get_stack_depth(); 3.71 int thread_frame_start = frame_serial_num; 3.72 + int extra_frames = 0; 3.73 + // write fake frame that makes it look like the thread, which caused OOME, 3.74 + // is in the OutOfMemoryError zero-parameter constructor 3.75 + if (thread == _oome_thread && _oome_constructor != NULL) { 3.76 + int oome_serial_num = _klass_map->find(Klass::cast(_oome_constructor->method_holder())); 3.77 + // the class serial number starts from 1 3.78 + assert(oome_serial_num > 0, "OutOfMemoryError class not found"); 3.79 + DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, oome_serial_num, 3.80 + _oome_constructor, 0); 3.81 + extra_frames++; 3.82 + } 3.83 for (int j=0; j < depth; j++) { 3.84 StackFrameInfo* frame = stack_trace->stack_frame_at(j); 3.85 methodOop m = frame->method(); 3.86 @@ -1772,6 +1801,7 @@ 3.87 assert(class_serial_num > 0, "class not found"); 3.88 DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, class_serial_num, m, frame->bci()); 3.89 } 3.90 + depth += extra_frames; 3.91 3.92 // write HPROF_TRACE record for one thread 3.93 DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4) + depth*oopSize); 3.94 @@ -1808,7 +1838,7 @@ 3.95 } 3.96 3.97 // generate the dump 3.98 - VM_HeapDumper dumper(&writer, _gc_before_heap_dump); 3.99 + VM_HeapDumper dumper(&writer, _gc_before_heap_dump, _oome); 3.100 if (Thread::current()->is_VM_thread()) { 3.101 assert(SafepointSynchronize::is_at_safepoint(), "Expected to be called at a safepoint"); 3.102 dumper.doit(); 3.103 @@ -1869,12 +1899,22 @@ 3.104 } 3.105 } 3.106 3.107 +// Called by out-of-memory error reporting by a single Java thread 3.108 +// outside of a JVM safepoint 3.109 +void HeapDumper::dump_heap_from_oome() { 3.110 + HeapDumper::dump_heap(true); 3.111 +} 3.112 + 3.113 // Called by error reporting by a single Java thread outside of a JVM safepoint, 3.114 // or by heap dumping by the VM thread during a (GC) safepoint. Thus, these various 3.115 // callers are strictly serialized and guaranteed not to interfere below. For more 3.116 // general use, however, this method will need modification to prevent 3.117 // inteference when updating the static variables base_path and dump_file_seq below. 3.118 void HeapDumper::dump_heap() { 3.119 + HeapDumper::dump_heap(false); 3.120 +} 3.121 + 3.122 +void HeapDumper::dump_heap(bool oome) { 3.123 static char base_path[JVM_MAXPATHLEN] = {'\0'}; 3.124 static uint dump_file_seq = 0; 3.125 char my_path[JVM_MAXPATHLEN] = {'\0'}; 3.126 @@ -1930,6 +1970,7 @@ 3.127 dump_file_seq++; // increment seq number for next time we dump 3.128 3.129 HeapDumper dumper(false /* no GC before heap dump */, 3.130 - true /* send to tty */); 3.131 + true /* send to tty */, 3.132 + oome /* pass along out-of-memory-error flag */); 3.133 dumper.dump(my_path); 3.134 }
4.1 --- a/src/share/vm/services/heapDumper.hpp Fri Sep 10 12:36:47 2010 -0400 4.2 +++ b/src/share/vm/services/heapDumper.hpp Tue Sep 14 10:15:27 2010 -0400 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -39,8 +39,12 @@ 4.11 char* _error; 4.12 bool _print_to_tty; 4.13 bool _gc_before_heap_dump; 4.14 + bool _oome; 4.15 elapsedTimer _t; 4.16 4.17 + HeapDumper(bool gc_before_heap_dump, bool print_to_tty, bool oome) : 4.18 + _gc_before_heap_dump(gc_before_heap_dump), _error(NULL), _print_to_tty(print_to_tty), _oome(oome) { } 4.19 + 4.20 // string representation of error 4.21 char* error() const { return _error; } 4.22 void set_error(char* error); 4.23 @@ -51,11 +55,11 @@ 4.24 // internal timer. 4.25 elapsedTimer* timer() { return &_t; } 4.26 4.27 + static void dump_heap(bool oome); 4.28 + 4.29 public: 4.30 HeapDumper(bool gc_before_heap_dump) : 4.31 - _gc_before_heap_dump(gc_before_heap_dump), _error(NULL), _print_to_tty(false) { } 4.32 - HeapDumper(bool gc_before_heap_dump, bool print_to_tty) : 4.33 - _gc_before_heap_dump(gc_before_heap_dump), _error(NULL), _print_to_tty(print_to_tty) { } 4.34 + _gc_before_heap_dump(gc_before_heap_dump), _error(NULL), _print_to_tty(false), _oome(false) { } 4.35 4.36 ~HeapDumper(); 4.37 4.38 @@ -66,4 +70,6 @@ 4.39 char* error_as_C_string() const; 4.40 4.41 static void dump_heap() KERNEL_RETURN; 4.42 + 4.43 + static void dump_heap_from_oome() KERNEL_RETURN; 4.44 };
5.1 --- a/src/share/vm/utilities/debug.cpp Fri Sep 10 12:36:47 2010 -0400 5.2 +++ b/src/share/vm/utilities/debug.cpp Tue Sep 14 10:15:27 2010 -0400 5.3 @@ -234,7 +234,7 @@ 5.4 // create heap dump before OnOutOfMemoryError commands are executed 5.5 if (HeapDumpOnOutOfMemoryError) { 5.6 tty->print_cr("java.lang.OutOfMemoryError: %s", message); 5.7 - HeapDumper::dump_heap(); 5.8 + HeapDumper::dump_heap_from_oome(); 5.9 } 5.10 5.11 if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {