Name: cl74495 Date: 03/05/2004
Running a Sparc 64 bit fastdebug VM build from 1.4.2.04 sources,
I got the following assertion failure during a Full GC .
It would appear that there are several uses of "HandleMark"
within oop_follow_contents methods on the share/vm/oops/*.cpp
files that are incompatible with instance of HandleMark in
GenCollectedHeap::do_collection and the usage of GenericGrowableArray
in the markSweep code .
I think the HandleMark's in the oop_follow_contents methods
should be removed.
------------------------------------------
# Error ID: /export/avocet2/users/otisa/fac30a/vm/hotspot/src/share/vm/utilities/growableArray.cpp, 64 [ Patched ]
[9] report_error
[10] report_fatal
[11] GenericGrowableArray::check_nesting
[12] MarkSweep::preserve_mark
[13] MarkSweep::_mark_and_push
[14] klassKlass::oop_follow_contents
[15] instanceKlassKlass::oop_follow_contents
[16] MarkSweep::follow_stack
[17] Universe::oops_do
[18] GenCollectedHeap::process_strong_roots
[19] GenMarkSweep::mark_sweep_phase1
[20] GenMarkSweep::invoke_at_safepoint
[21] OneContigSpaceCardGeneration::collect
=>[22] GenCollectedHeap::do_collection
[23] TwoGenerationCollectorPolicy::satisfy_failed_allocation
[24] VM_GenCollectForAllocation::doit
[25] VM_Operation::evaluate
[26] VMThread::evaluate_operation
[27] VMThread::loop
[28] VMThread::run
Heap at VM Abort:
Heap
def new generation total 2240K, used 63K [0xffffffff21c00000, 0xffffffff21e40000, 0xffffffff26c00000)
eden space 2176K, 0% used [0xffffffff21c00000, 0xffffffff21c00000, 0xffffffff21e20000)
from space 64K, 99% used [0xffffffff21e30000, 0xffffffff21e3fff0, 0xffffffff21e40000)
to space 64K, 0% used [0xffffffff21e20000, 0xffffffff21e20000, 0xffffffff21e30000)
tenured generation total 4672K, used 4556K [0xffffffff26c00000, 0xffffffff27090000, 0xffffffff30c00000)
the space 4672K, 97% used [0xffffffff26c00000, 0xffffffff270733c0, 0xffffffff27073400, 0xffffffff27090000)
compacting perm gen total 16384K, used 12987K [0xffffffff30c00000, 0xffffffff31c00000, 0xffffffff36400000)
the space 16384K, 79% used [0xffffffff30c00000, 0xffffffff318aec60, 0xffffffff318aee00, 0xffffffff31c00000)
----------------------------------
Now here is the stack in more detail
Now here is the stack in more detail
[10] report_fatal(file_name = 0xffffffff7e16ea22 "/export/avocet2/users/otisa/fac30a/vm/ho" ..., line_no = 64, format = 0xffffffff7e16ea79 "allocation bug: GrowableArray could grow" ..., ...), line 140 in "debug.cpp"
---------
[11] GenericGrowableArray::check_nesting(this = ???) (optimized), at 0xffffffff7d6e31cc (line ~66) in "growableArray.cpp"
58 void GenericGrowableArray::check_nesting() {
59 // Check for insidious allocation bug: if a GrowableArray overflows, the
60 // grown array must be allocated under the same ResourceMark as the original.
61 // Otherwise, the _data array will be deallocated too early.
62 if (on_stack() &&
63 _nesting != Thread::current()->resource_area()->nesting()) {
64 fatal("allocation bug: GrowableArray could grow within nested ResourceMark");
65 }
66 }
---------
[12] MarkSweep::preserve_mark(obj = ???, mark = ???) (optimized), at 0xffffffff7da77598 (line ~207) in "markSweep.cpp"
0xffffffff7da77598: preserve_mark+0x00e8: call check_nesting
markSweep.s:
! 204 ! _preserved_mark_stack->push(mark);
/* 0x00e4 204 */ ldx [%l3],%l3 ! volatile
.L900003415:
/* 0x00e8 204 */ call __1cUGenericGrowableArrayNcheck_nesting6
markSweep.cpp
192 void MarkSweep::preserve_mark(oop obj, markOop mark) {
193 // we try to store preserved marks in the to space of the new generation since this
194 // is storage which should be available. Most of the time this should be sufficient
195 // space for the marks we need to preserve but if it isn't we fall back in using
196 // GrowableArrays to keep track of the overflow.
197 if (_preserved_count < _preserved_count_max) {
198 _preserved_marks[_preserved_count++].init(obj, mark);
199 } else {
200 if (_preserved_mark_stack == NULL) {
201 _preserved_mark_stack = new GrowableArray<markOop>(40, true);
202 _preserved_oop_stack = new GrowableArray<oop>(40, true);
203 }
204 _preserved_mark_stack->push(mark);
205 _preserved_oop_stack->push(obj);
206 }
207 }
-----------
[13] MarkSweep::_mark_and_push(p = ???) (optimized), at 0xffffffff7da76c10 (line ~95) in "markSweep.cpp"
-----------
[14] klassKlass::oop_follow_contents(this = ???, obj = ???) (optimized), at 0xffffffff7d9ef4a4 (line ~44) in "klassKlass.cpp"
28 void klassKlass::oop_follow_contents(oop obj) {
29 Klass* k = Klass::cast(klassOop(obj));
30 // If we are alive it is valid to keep our superclass and subtype caches alive
31 MarkSweep::mark_and_push(k->adr_super());
32 for (juint i = 0; i < Klass::primary_super_limit(); i++)
33 MarkSweep::mark_and_push(k->adr_primary_supers()+i);
34 MarkSweep::mark_and_push(k->adr_secondary_super_cache());
35 MarkSweep::mark_and_push(k->adr_secondary_supers());
36 MarkSweep::mark_and_push(k->adr_java_mirror());
37 MarkSweep::mark_and_push(k->adr_name());
38 // We follow the subklass and sibling links at the end of the
39 // marking phase, since otherwise following them will prevent
40 // class unloading (all classes are transitively linked from
41 // java.lang.Object).
42 MarkSweep::revisit_weak_klass_link(k);
43 obj->follow_header();
44 }
----------- share/vm/oops/instanceKlassKlass.cpp
[15] instanceKlassKlass::oop_follow_contents(this = ???, obj = ???) (optimized), at 0xffffffff7d7207ac (line ~71) in "instanceKlassKlass.cpp"
32 void instanceKlassKlass::oop_follow_contents(oop obj) {
33 assert(obj->is_klass(),"must be a klass");
34 assert(klassOop(obj)->klass_part()->oop_is_instance(), "must be instance klass");
35
36 instanceKlass* ik = instanceKlass::cast(klassOop(obj));
37 ik->follow_static_fields();
38 {
39 HandleMark hm; <********* PROBLEM
40 ik->vtable()->oop_follow_contents(); <******** HERE
41 ik->itable()->oop_follow_contents();
42 }
----
[16] MarkSweep::follow_stack() (optimized), at 0xffffffff7da77228 (line ~145) in "markSweep.cpp"
void MarkSweep::follow_stack() {
while (!_marking_stack->is_empty()) {
oop obj = _marking_stack->pop();
assert (obj->is_gc_marked(), "p must be marked");
obj->follow_contents();
}
------------
[17] Universe::oops_do(f = ???) (optimized), at 0xffffffff7dd39644 (line ~161) in "universe.cpp"
(dbx) x 0xffffffff7dd39644 / 3 i
0xffffffff7dd39644: oops_do+0x002c: jmpl %l0, %o7
! 113 ! f->do_oop((oop*)&_boolArrayKlassObj);
}
-----------
[18] GenCollectedHeap::process_strong_roots(this = ???, level = ???, younger_gens_as_roots = ???, collecting_perm_gen = ???, cso = ???, older_gens = ???, not_older_gens = ???) (optimized), at 0xffffffff7d657494 (line ~541) in "genCollectedHeap.cpp"
void GenCollectedHeap::process_strong_roots(int level,
bool younger_gens_as_roots,
bool collecting_perm_gen,
ClassScanningOption cso,
OopsInGenClosure* older_gens,
OopsInGenClosure* not_older_gens) {
...
471 Universe::oops_do(not_older_gens);
------------
[19] GenMarkSweep::mark_sweep_phase1(level = ???, marked_for_unloading = ???, clear_all_softrefs = ???) (optimized), at 0xffffffff7d65bff0 (line ~266) in "genMarkSweep.cpp"
gch->process_strong_roots(level,
false, // Younger gens are not roots.
true, // Collecting permanent generation.
GenCollectedHeap::CSO_SystemClasses,
rootClosure, rootClosure );
------------
[20] GenMarkSweep::invoke_at_safepoint(level = ???, rp = ???, clear_all_softrefs = ???) (optimized), at 0xffffffff7d65b5a8 (line ~134) in "genMarkSweep.cpp"
no HandleMarks found
----
[21] OneContigSpaceCardGeneration::collect (line ~313) in "generation.cpp"
no HandleMarks found
----
[22] GenCollectedHeap::do_collection (line ~437) in "genCollectedHeap.cpp"
at 0xffffffff7d656b78
0xffffffff7d656b78: do_collection+0x0d14: jmpl %l0, %o7
! 343 ! _gens[i]->collect(full, clear_all_soft_refs, si
/* 0x0cf0 343 */ ldx [%sp+2231],%o1
...
/* 0x0d14 */ jmpl %l0,%o7
225 void GenCollectedHeap::do_collection(bool full,
...
235 ResourceMark rm;
...
326 HandleMark hm; // Discard invalid handles created during gc <*******
327 save_marks(); // save marks for all gens
328 // We want to discover references, but not process them yet.
329 // This mode is disabled in process_discovered_references if the
330 // generation does some collection work, or in
331 // enqueue_discovered_references if the generation returns
332 // without doing any work.
333 ReferenceProcessor* rp = _gens[i]->ref_processor();
334 // If the discovery of ("weak") refs in this generation is
335 // atomic wrt other collectors in this configuration, we
336 // are guaranteed to have empty discovered ref lists.
337 if (rp->discovery_is_atomic()) {
338 rp->verify_no_references_recorded();
339 rp->enable_discovery();
340 } else {
341 // collect() will enable discovery as appropriate
342 }
343 _gens[i]->collect(full, clear_all_soft_refs, size, is_large_noref,
-----------------
[23] TwoGenerationCollectorPolicy::satisfy_failed_allocation (line ~324) in "collectorPolicy.cpp"
no HandlMark in collectorPolicy.cpp
[24] VM_GenCollectForAllocation::doit (line ~106) in "vm_operations.cpp"
102 void VM_GenCollectForAllocation::doit() {
103 GenCollectedHeap* gch = GenCollectedHeap::heap();
104 _res = gch->satisfy_failed_allocation(_size, _large_noref, _tlab, _notify_ref_lock);
105 assert(gch->is_in_or_null(_res), "result not in heap");
106 }
[25] VM_Operation::evaluate (line ~30) in "vm_operations.cpp"
20 void VM_Operation::evaluate() {
21 ResourceMark rm;
22 if (TraceVMOperation) {
23 tty->print("[");
24 NOT_PRODUCT(print();)
25 }
26 doit();
27 if (TraceVMOperation) {
28 tty->print_cr("]");
29 }
30 }
[26] VMThread::evaluate_operation (line ~294) in "vmThread.cpp"
277 void VMThread::evaluate_operation(VM_Operation* op) {
278 ResourceMark rm;
279
280 op->evaluate();
[27] VMThread::loop (line ~435) in "vmThread.cpp" at 0xffffffff7dd82bc8
0xffffffff7dd82bc8: loop+0x0560: call evaluate_operation
/* 0x0560 376 */ call __1cIVMThreadSevaluate_operation6MpnMVM_
349 // Execute VM operation
350 //
351 { HandleMark hm(VMThread::vm_thread()); <**************
374 SafepointSynchronize::begin();
375 do {
376 evaluate_operation(_cur_vm_operation);
413 }
[28] VMThread::run (line ~244) in "vmThread.cpp" at 0xffffffff7dd820f4
0xffffffff7dd820f4: run+0x010c: call loop
203 // Wait for VM_Operations until termination
204 this->loop();
(Incident Review ID: 242205)
======================================================================
Running a Sparc 64 bit fastdebug VM build from 1.4.2.04 sources,
I got the following assertion failure during a Full GC .
It would appear that there are several uses of "HandleMark"
within oop_follow_contents methods on the share/vm/oops/*.cpp
files that are incompatible with instance of HandleMark in
GenCollectedHeap::do_collection and the usage of GenericGrowableArray
in the markSweep code .
I think the HandleMark's in the oop_follow_contents methods
should be removed.
------------------------------------------
# Error ID: /export/avocet2/users/otisa/fac30a/vm/hotspot/src/share/vm/utilities/growableArray.cpp, 64 [ Patched ]
[9] report_error
[10] report_fatal
[11] GenericGrowableArray::check_nesting
[12] MarkSweep::preserve_mark
[13] MarkSweep::_mark_and_push
[14] klassKlass::oop_follow_contents
[15] instanceKlassKlass::oop_follow_contents
[16] MarkSweep::follow_stack
[17] Universe::oops_do
[18] GenCollectedHeap::process_strong_roots
[19] GenMarkSweep::mark_sweep_phase1
[20] GenMarkSweep::invoke_at_safepoint
[21] OneContigSpaceCardGeneration::collect
=>[22] GenCollectedHeap::do_collection
[23] TwoGenerationCollectorPolicy::satisfy_failed_allocation
[24] VM_GenCollectForAllocation::doit
[25] VM_Operation::evaluate
[26] VMThread::evaluate_operation
[27] VMThread::loop
[28] VMThread::run
Heap at VM Abort:
Heap
def new generation total 2240K, used 63K [0xffffffff21c00000, 0xffffffff21e40000, 0xffffffff26c00000)
eden space 2176K, 0% used [0xffffffff21c00000, 0xffffffff21c00000, 0xffffffff21e20000)
from space 64K, 99% used [0xffffffff21e30000, 0xffffffff21e3fff0, 0xffffffff21e40000)
to space 64K, 0% used [0xffffffff21e20000, 0xffffffff21e20000, 0xffffffff21e30000)
tenured generation total 4672K, used 4556K [0xffffffff26c00000, 0xffffffff27090000, 0xffffffff30c00000)
the space 4672K, 97% used [0xffffffff26c00000, 0xffffffff270733c0, 0xffffffff27073400, 0xffffffff27090000)
compacting perm gen total 16384K, used 12987K [0xffffffff30c00000, 0xffffffff31c00000, 0xffffffff36400000)
the space 16384K, 79% used [0xffffffff30c00000, 0xffffffff318aec60, 0xffffffff318aee00, 0xffffffff31c00000)
----------------------------------
Now here is the stack in more detail
Now here is the stack in more detail
[10] report_fatal(file_name = 0xffffffff7e16ea22 "/export/avocet2/users/otisa/fac30a/vm/ho" ..., line_no = 64, format = 0xffffffff7e16ea79 "allocation bug: GrowableArray could grow" ..., ...), line 140 in "debug.cpp"
---------
[11] GenericGrowableArray::check_nesting(this = ???) (optimized), at 0xffffffff7d6e31cc (line ~66) in "growableArray.cpp"
58 void GenericGrowableArray::check_nesting() {
59 // Check for insidious allocation bug: if a GrowableArray overflows, the
60 // grown array must be allocated under the same ResourceMark as the original.
61 // Otherwise, the _data array will be deallocated too early.
62 if (on_stack() &&
63 _nesting != Thread::current()->resource_area()->nesting()) {
64 fatal("allocation bug: GrowableArray could grow within nested ResourceMark");
65 }
66 }
---------
[12] MarkSweep::preserve_mark(obj = ???, mark = ???) (optimized), at 0xffffffff7da77598 (line ~207) in "markSweep.cpp"
0xffffffff7da77598: preserve_mark+0x00e8: call check_nesting
markSweep.s:
! 204 ! _preserved_mark_stack->push(mark);
/* 0x00e4 204 */ ldx [%l3],%l3 ! volatile
.L900003415:
/* 0x00e8 204 */ call __1cUGenericGrowableArrayNcheck_nesting6
markSweep.cpp
192 void MarkSweep::preserve_mark(oop obj, markOop mark) {
193 // we try to store preserved marks in the to space of the new generation since this
194 // is storage which should be available. Most of the time this should be sufficient
195 // space for the marks we need to preserve but if it isn't we fall back in using
196 // GrowableArrays to keep track of the overflow.
197 if (_preserved_count < _preserved_count_max) {
198 _preserved_marks[_preserved_count++].init(obj, mark);
199 } else {
200 if (_preserved_mark_stack == NULL) {
201 _preserved_mark_stack = new GrowableArray<markOop>(40, true);
202 _preserved_oop_stack = new GrowableArray<oop>(40, true);
203 }
204 _preserved_mark_stack->push(mark);
205 _preserved_oop_stack->push(obj);
206 }
207 }
-----------
[13] MarkSweep::_mark_and_push(p = ???) (optimized), at 0xffffffff7da76c10 (line ~95) in "markSweep.cpp"
-----------
[14] klassKlass::oop_follow_contents(this = ???, obj = ???) (optimized), at 0xffffffff7d9ef4a4 (line ~44) in "klassKlass.cpp"
28 void klassKlass::oop_follow_contents(oop obj) {
29 Klass* k = Klass::cast(klassOop(obj));
30 // If we are alive it is valid to keep our superclass and subtype caches alive
31 MarkSweep::mark_and_push(k->adr_super());
32 for (juint i = 0; i < Klass::primary_super_limit(); i++)
33 MarkSweep::mark_and_push(k->adr_primary_supers()+i);
34 MarkSweep::mark_and_push(k->adr_secondary_super_cache());
35 MarkSweep::mark_and_push(k->adr_secondary_supers());
36 MarkSweep::mark_and_push(k->adr_java_mirror());
37 MarkSweep::mark_and_push(k->adr_name());
38 // We follow the subklass and sibling links at the end of the
39 // marking phase, since otherwise following them will prevent
40 // class unloading (all classes are transitively linked from
41 // java.lang.Object).
42 MarkSweep::revisit_weak_klass_link(k);
43 obj->follow_header();
44 }
----------- share/vm/oops/instanceKlassKlass.cpp
[15] instanceKlassKlass::oop_follow_contents(this = ???, obj = ???) (optimized), at 0xffffffff7d7207ac (line ~71) in "instanceKlassKlass.cpp"
32 void instanceKlassKlass::oop_follow_contents(oop obj) {
33 assert(obj->is_klass(),"must be a klass");
34 assert(klassOop(obj)->klass_part()->oop_is_instance(), "must be instance klass");
35
36 instanceKlass* ik = instanceKlass::cast(klassOop(obj));
37 ik->follow_static_fields();
38 {
39 HandleMark hm; <********* PROBLEM
40 ik->vtable()->oop_follow_contents(); <******** HERE
41 ik->itable()->oop_follow_contents();
42 }
----
[16] MarkSweep::follow_stack() (optimized), at 0xffffffff7da77228 (line ~145) in "markSweep.cpp"
void MarkSweep::follow_stack() {
while (!_marking_stack->is_empty()) {
oop obj = _marking_stack->pop();
assert (obj->is_gc_marked(), "p must be marked");
obj->follow_contents();
}
------------
[17] Universe::oops_do(f = ???) (optimized), at 0xffffffff7dd39644 (line ~161) in "universe.cpp"
(dbx) x 0xffffffff7dd39644 / 3 i
0xffffffff7dd39644: oops_do+0x002c: jmpl %l0, %o7
! 113 ! f->do_oop((oop*)&_boolArrayKlassObj);
}
-----------
[18] GenCollectedHeap::process_strong_roots(this = ???, level = ???, younger_gens_as_roots = ???, collecting_perm_gen = ???, cso = ???, older_gens = ???, not_older_gens = ???) (optimized), at 0xffffffff7d657494 (line ~541) in "genCollectedHeap.cpp"
void GenCollectedHeap::process_strong_roots(int level,
bool younger_gens_as_roots,
bool collecting_perm_gen,
ClassScanningOption cso,
OopsInGenClosure* older_gens,
OopsInGenClosure* not_older_gens) {
...
471 Universe::oops_do(not_older_gens);
------------
[19] GenMarkSweep::mark_sweep_phase1(level = ???, marked_for_unloading = ???, clear_all_softrefs = ???) (optimized), at 0xffffffff7d65bff0 (line ~266) in "genMarkSweep.cpp"
gch->process_strong_roots(level,
false, // Younger gens are not roots.
true, // Collecting permanent generation.
GenCollectedHeap::CSO_SystemClasses,
rootClosure, rootClosure );
------------
[20] GenMarkSweep::invoke_at_safepoint(level = ???, rp = ???, clear_all_softrefs = ???) (optimized), at 0xffffffff7d65b5a8 (line ~134) in "genMarkSweep.cpp"
no HandleMarks found
----
[21] OneContigSpaceCardGeneration::collect (line ~313) in "generation.cpp"
no HandleMarks found
----
[22] GenCollectedHeap::do_collection (line ~437) in "genCollectedHeap.cpp"
at 0xffffffff7d656b78
0xffffffff7d656b78: do_collection+0x0d14: jmpl %l0, %o7
! 343 ! _gens[i]->collect(full, clear_all_soft_refs, si
/* 0x0cf0 343 */ ldx [%sp+2231],%o1
...
/* 0x0d14 */ jmpl %l0,%o7
225 void GenCollectedHeap::do_collection(bool full,
...
235 ResourceMark rm;
...
326 HandleMark hm; // Discard invalid handles created during gc <*******
327 save_marks(); // save marks for all gens
328 // We want to discover references, but not process them yet.
329 // This mode is disabled in process_discovered_references if the
330 // generation does some collection work, or in
331 // enqueue_discovered_references if the generation returns
332 // without doing any work.
333 ReferenceProcessor* rp = _gens[i]->ref_processor();
334 // If the discovery of ("weak") refs in this generation is
335 // atomic wrt other collectors in this configuration, we
336 // are guaranteed to have empty discovered ref lists.
337 if (rp->discovery_is_atomic()) {
338 rp->verify_no_references_recorded();
339 rp->enable_discovery();
340 } else {
341 // collect() will enable discovery as appropriate
342 }
343 _gens[i]->collect(full, clear_all_soft_refs, size, is_large_noref,
-----------------
[23] TwoGenerationCollectorPolicy::satisfy_failed_allocation (line ~324) in "collectorPolicy.cpp"
no HandlMark in collectorPolicy.cpp
[24] VM_GenCollectForAllocation::doit (line ~106) in "vm_operations.cpp"
102 void VM_GenCollectForAllocation::doit() {
103 GenCollectedHeap* gch = GenCollectedHeap::heap();
104 _res = gch->satisfy_failed_allocation(_size, _large_noref, _tlab, _notify_ref_lock);
105 assert(gch->is_in_or_null(_res), "result not in heap");
106 }
[25] VM_Operation::evaluate (line ~30) in "vm_operations.cpp"
20 void VM_Operation::evaluate() {
21 ResourceMark rm;
22 if (TraceVMOperation) {
23 tty->print("[");
24 NOT_PRODUCT(print();)
25 }
26 doit();
27 if (TraceVMOperation) {
28 tty->print_cr("]");
29 }
30 }
[26] VMThread::evaluate_operation (line ~294) in "vmThread.cpp"
277 void VMThread::evaluate_operation(VM_Operation* op) {
278 ResourceMark rm;
279
280 op->evaluate();
[27] VMThread::loop (line ~435) in "vmThread.cpp" at 0xffffffff7dd82bc8
0xffffffff7dd82bc8: loop+0x0560: call evaluate_operation
/* 0x0560 376 */ call __1cIVMThreadSevaluate_operation6MpnMVM_
349 // Execute VM operation
350 //
351 { HandleMark hm(VMThread::vm_thread()); <**************
374 SafepointSynchronize::begin();
375 do {
376 evaluate_operation(_cur_vm_operation);
413 }
[28] VMThread::run (line ~244) in "vmThread.cpp" at 0xffffffff7dd820f4
0xffffffff7dd820f4: run+0x010c: call loop
203 // Wait for VM_Operations until termination
204 this->loop();
(Incident Review ID: 242205)
======================================================================