107 oops.push(addr);
108 }
109 }
110 }
111
112 ShenandoahNMethod* ShenandoahNMethod::for_nmethod(nmethod* nm) {
113 ResourceMark rm;
114 bool non_immediate_oops = false;
115 GrowableArray<oop*> oops;
116
117 detect_reloc_oops(nm, oops, non_immediate_oops);
118 return new ShenandoahNMethod(nm, oops, non_immediate_oops);
119 }
120
121 void ShenandoahNMethod::heal_nmethod(nmethod* nm) {
122 ShenandoahNMethod* data = gc_data(nm);
123 assert(data != nullptr, "Sanity");
124 assert(data->lock()->owned_by_self(), "Must hold the lock");
125
126 ShenandoahHeap* const heap = ShenandoahHeap::heap();
127 if (heap->is_concurrent_mark_in_progress()) {
128 ShenandoahKeepAliveClosure cl;
129 data->oops_do(&cl);
130 } else if (heap->is_concurrent_weak_root_in_progress() ||
131 heap->is_concurrent_strong_root_in_progress() ) {
132 ShenandoahEvacOOMScope evac_scope;
133 heal_nmethod_metadata(data);
134 } else {
135 // There is possibility that GC is cancelled when it arrives final mark.
136 // In this case, concurrent root phase is skipped and degenerated GC should be
137 // followed, where nmethods are disarmed.
138 }
139 }
140
141 #ifdef ASSERT
142 void ShenandoahNMethod::assert_correct() {
143 ShenandoahHeap* heap = ShenandoahHeap::heap();
144 for (int c = 0; c < _oops_count; c++) {
145 oop *loc = _oops[c];
146 assert(_nm->code_contains((address) loc) || _nm->oops_contains(loc), "nmethod should contain the oop*");
147 oop o = RawAccess<>::oop_load(loc);
148 shenandoah_assert_correct_except(loc, o, o == nullptr || heap->is_full_gc_move_in_progress());
149 }
150
151 oop* const begin = _nm->oops_begin();
152 oop* const end = _nm->oops_end();
153 for (oop* p = begin; p < end; p++) {
|
107 oops.push(addr);
108 }
109 }
110 }
111
112 ShenandoahNMethod* ShenandoahNMethod::for_nmethod(nmethod* nm) {
113 ResourceMark rm;
114 bool non_immediate_oops = false;
115 GrowableArray<oop*> oops;
116
117 detect_reloc_oops(nm, oops, non_immediate_oops);
118 return new ShenandoahNMethod(nm, oops, non_immediate_oops);
119 }
120
121 void ShenandoahNMethod::heal_nmethod(nmethod* nm) {
122 ShenandoahNMethod* data = gc_data(nm);
123 assert(data != nullptr, "Sanity");
124 assert(data->lock()->owned_by_self(), "Must hold the lock");
125
126 ShenandoahHeap* const heap = ShenandoahHeap::heap();
127 if (heap->is_concurrent_weak_root_in_progress() ||
128 heap->is_concurrent_strong_root_in_progress()) {
129 ShenandoahEvacOOMScope evac_scope;
130 heal_nmethod_metadata(data);
131 } else if (heap->is_concurrent_mark_in_progress()) {
132 ShenandoahKeepAliveClosure cl;
133 data->oops_do(&cl);
134 } else {
135 // There is possibility that GC is cancelled when it arrives final mark.
136 // In this case, concurrent root phase is skipped and degenerated GC should be
137 // followed, where nmethods are disarmed.
138 }
139 }
140
141 #ifdef ASSERT
142 void ShenandoahNMethod::assert_correct() {
143 ShenandoahHeap* heap = ShenandoahHeap::heap();
144 for (int c = 0; c < _oops_count; c++) {
145 oop *loc = _oops[c];
146 assert(_nm->code_contains((address) loc) || _nm->oops_contains(loc), "nmethod should contain the oop*");
147 oop o = RawAccess<>::oop_load(loc);
148 shenandoah_assert_correct_except(loc, o, o == nullptr || heap->is_full_gc_move_in_progress());
149 }
150
151 oop* const begin = _nm->oops_begin();
152 oop* const end = _nm->oops_end();
153 for (oop* p = begin; p < end; p++) {
|