102
103 public:
104 ShenandoahNMethodOopDetector() : _oops(10) {};
105
106 void do_oop(oop* o) {
107 _oops.append(o);
108 }
109 void do_oop(narrowOop* o) {
110 fatal("NMethods should not have compressed oops embedded.");
111 }
112
113 GrowableArray<oop*>* oops() {
114 return &_oops;
115 }
116
117 bool has_oops() {
118 return !_oops.is_empty();
119 }
120 };
121
122 class ShenandoahNMethodOopInitializer : public OopClosure {
123 private:
124 ShenandoahHeap* const _heap;
125
126 public:
127 ShenandoahNMethodOopInitializer() : _heap(ShenandoahHeap::heap()) {};
128
129 private:
130 template <class T>
131 inline void do_oop_work(T* p) {
132 T o = RawAccess<>::oop_load(p);
133 if (! CompressedOops::is_null(o)) {
134 oop obj1 = CompressedOops::decode_not_null(o);
135 oop obj2 = ShenandoahBarrierSet::barrier_set()->write_barrier(obj1);
136 if (! oopDesc::equals_raw(obj1, obj2)) {
137 shenandoah_assert_not_in_cset(NULL, obj2);
138 RawAccess<IS_NOT_NULL>::oop_store(p, obj2);
139 if (_heap->is_concurrent_traversal_in_progress()) {
140 ShenandoahBarrierSet::barrier_set()->enqueue(obj2);
141 }
142 }
143 }
144 }
145
146 public:
147 void do_oop(oop* o) {
148 do_oop_work(o);
149 }
150 void do_oop(narrowOop* o) {
151 do_oop_work(o);
152 }
153 };
154
155 ShenandoahCodeRoots::PaddedLock ShenandoahCodeRoots::_recorded_nms_lock;
156 GrowableArray<ShenandoahNMethod*>* ShenandoahCodeRoots::_recorded_nms;
157
158 void ShenandoahCodeRoots::initialize() {
159 _recorded_nms_lock._lock = 0;
160 _recorded_nms = new (ResourceObj::C_HEAP, mtGC) GrowableArray<ShenandoahNMethod*>(100, true, mtGC);
161 }
162
163 void ShenandoahCodeRoots::add_nmethod(nmethod* nm) {
164 switch (ShenandoahCodeRootsStyle) {
165 case 0:
166 case 1: {
167 ShenandoahNMethodOopInitializer init;
168 nm->oops_do(&init);
169 nm->fix_oop_relocations();
170 break;
171 }
172 case 2: {
173 ShenandoahNMethodOopDetector detector;
174 nm->oops_do(&detector);
175
176 if (detector.has_oops()) {
177 ShenandoahNMethodOopInitializer init;
178 nm->oops_do(&init);
179 nm->fix_oop_relocations();
180
181 ShenandoahNMethod* nmr = new ShenandoahNMethod(nm, detector.oops());
182 nmr->assert_alive_and_correct();
183
184 ShenandoahCodeRootsLock lock(true);
185
186 int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod);
187 if (idx != -1) {
188 ShenandoahNMethod* old = _recorded_nms->at(idx);
189 _recorded_nms->at_put(idx, nmr);
190 delete old;
191 } else {
192 _recorded_nms->append(nmr);
193 }
194 }
195 break;
196 }
197 default:
198 ShouldNotReachHere();
199 }
200 };
|
102
103 public:
104 ShenandoahNMethodOopDetector() : _oops(10) {};
105
106 void do_oop(oop* o) {
107 _oops.append(o);
108 }
109 void do_oop(narrowOop* o) {
110 fatal("NMethods should not have compressed oops embedded.");
111 }
112
113 GrowableArray<oop*>* oops() {
114 return &_oops;
115 }
116
117 bool has_oops() {
118 return !_oops.is_empty();
119 }
120 };
121
122 ShenandoahCodeRoots::PaddedLock ShenandoahCodeRoots::_recorded_nms_lock;
123 GrowableArray<ShenandoahNMethod*>* ShenandoahCodeRoots::_recorded_nms;
124
125 void ShenandoahCodeRoots::initialize() {
126 _recorded_nms_lock._lock = 0;
127 _recorded_nms = new (ResourceObj::C_HEAP, mtGC) GrowableArray<ShenandoahNMethod*>(100, true, mtGC);
128 }
129
130 void ShenandoahCodeRoots::add_nmethod(nmethod* nm) {
131 switch (ShenandoahCodeRootsStyle) {
132 case 0:
133 case 1:
134 break;
135 case 2: {
136 ShenandoahNMethodOopDetector detector;
137 nm->oops_do(&detector);
138
139 if (detector.has_oops()) {
140 ShenandoahNMethod* nmr = new ShenandoahNMethod(nm, detector.oops());
141 nmr->assert_alive_and_correct();
142
143 ShenandoahCodeRootsLock lock(true);
144
145 int idx = _recorded_nms->find(nm, ShenandoahNMethod::find_with_nmethod);
146 if (idx != -1) {
147 ShenandoahNMethod* old = _recorded_nms->at(idx);
148 _recorded_nms->at_put(idx, nmr);
149 delete old;
150 } else {
151 _recorded_nms->append(nmr);
152 }
153 }
154 break;
155 }
156 default:
157 ShouldNotReachHere();
158 }
159 };
|