218 }
219
220
221 // The implementation of the following two methods was factorized into the
222 // class StackValue because it is also used from within deoptimization.cpp for
223 // rematerialization and relocking of non-escaping objects.
224
225 StackValue *compiledVFrame::create_stack_value(ScopeValue *sv) const {
226 stackChunkOop c = _reg_map.stack_chunk()();
227 int index = _reg_map.stack_chunk_index();
228 const_cast<RegisterMap*>(&_reg_map)->set_stack_chunk(_chunk());
229
230 StackValue* res = StackValue::create_stack_value(&_fr, register_map(), sv);
231
232 const_cast<RegisterMap*>(&_reg_map)->set_stack_chunk(c);
233 const_cast<RegisterMap*>(&_reg_map)->set_stack_chunk_index(index);
234 return res;
235 }
236
237 BasicLock* compiledVFrame::resolve_monitor_lock(Location location) const {
238 return StackValue::resolve_monitor_lock(&_fr, location);
239 }
240
241
242 GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
243 // Natives has no scope
244 if (scope() == nullptr) {
245 nmethod* nm = code();
246 Method* method = nm->method();
247 assert(method->is_native(), "Expect a native method");
248 if (!method->is_synchronized()) {
249 return new GrowableArray<MonitorInfo*>(0);
250 }
251 // This monitor is not really needed but return it for now as it might be
252 // useful for stack traces and tools
253 GrowableArray<MonitorInfo*> *monitors = new GrowableArray<MonitorInfo*>(1);
254 // Casting away const
255 frame& fr = (frame&) _fr;
256 MonitorInfo* info = new MonitorInfo(
257 fr.get_native_receiver(), fr.get_native_monitor(), false, false);
258 monitors->push(info);
267 MonitorValue* mv = monitors->at(index);
268 ScopeValue* ov = mv->owner();
269 StackValue *owner_sv = create_stack_value(ov); // it is an oop
270 if (ov->is_object() && owner_sv->obj_is_scalar_replaced()) { // The owner object was scalar replaced
271 assert(mv->eliminated(), "monitor should be eliminated for scalar replaced object");
272 // Put klass for scalar replaced object.
273 ScopeValue* kv = ((ObjectValue *)ov)->klass();
274 assert(kv->is_constant_oop(), "klass should be oop constant for scalar replaced object");
275 Handle k(Thread::current(), ((ConstantOopReadValue*)kv)->value()());
276 assert(java_lang_Class::is_instance(k()), "must be");
277 result->push(new MonitorInfo(k(), resolve_monitor_lock(mv->basic_lock()),
278 mv->eliminated(), true));
279 } else {
280 result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()),
281 mv->eliminated(), false));
282 }
283 }
284
285 // Replace the original values with any stores that have been
286 // performed through compiledVFrame::update_monitors.
287 GrowableArrayView<jvmtiDeferredLocalVariableSet*>* list = JvmtiDeferredUpdates::deferred_locals(thread());
288 if (list != nullptr ) {
289 // In real life this never happens or is typically a single element search
290 for (int i = 0; i < list->length(); i++) {
291 if (list->at(i)->matches(this)) {
292 list->at(i)->update_monitors(result);
293 break;
294 }
295 }
296 }
297
298 return result;
299 }
300
301
302 compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, nmethod* nm)
303 : javaVFrame(fr, reg_map, thread) {
304 _scope = nullptr;
305 _vframe_id = 0;
306 // Compiled method (native stub or Java code)
|
218 }
219
220
221 // The implementation of the following two methods was factorized into the
222 // class StackValue because it is also used from within deoptimization.cpp for
223 // rematerialization and relocking of non-escaping objects.
224
225 StackValue *compiledVFrame::create_stack_value(ScopeValue *sv) const {
226 stackChunkOop c = _reg_map.stack_chunk()();
227 int index = _reg_map.stack_chunk_index();
228 const_cast<RegisterMap*>(&_reg_map)->set_stack_chunk(_chunk());
229
230 StackValue* res = StackValue::create_stack_value(&_fr, register_map(), sv);
231
232 const_cast<RegisterMap*>(&_reg_map)->set_stack_chunk(c);
233 const_cast<RegisterMap*>(&_reg_map)->set_stack_chunk_index(index);
234 return res;
235 }
236
237 BasicLock* compiledVFrame::resolve_monitor_lock(Location location) const {
238 return StackValue::resolve_monitor_lock(stack_chunk() == nullptr ? _fr : stack_chunk()->derelativize(_fr), location);
239 }
240
241
242 GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
243 // Natives has no scope
244 if (scope() == nullptr) {
245 nmethod* nm = code();
246 Method* method = nm->method();
247 assert(method->is_native(), "Expect a native method");
248 if (!method->is_synchronized()) {
249 return new GrowableArray<MonitorInfo*>(0);
250 }
251 // This monitor is not really needed but return it for now as it might be
252 // useful for stack traces and tools
253 GrowableArray<MonitorInfo*> *monitors = new GrowableArray<MonitorInfo*>(1);
254 // Casting away const
255 frame& fr = (frame&) _fr;
256 MonitorInfo* info = new MonitorInfo(
257 fr.get_native_receiver(), fr.get_native_monitor(), false, false);
258 monitors->push(info);
267 MonitorValue* mv = monitors->at(index);
268 ScopeValue* ov = mv->owner();
269 StackValue *owner_sv = create_stack_value(ov); // it is an oop
270 if (ov->is_object() && owner_sv->obj_is_scalar_replaced()) { // The owner object was scalar replaced
271 assert(mv->eliminated(), "monitor should be eliminated for scalar replaced object");
272 // Put klass for scalar replaced object.
273 ScopeValue* kv = ((ObjectValue *)ov)->klass();
274 assert(kv->is_constant_oop(), "klass should be oop constant for scalar replaced object");
275 Handle k(Thread::current(), ((ConstantOopReadValue*)kv)->value()());
276 assert(java_lang_Class::is_instance(k()), "must be");
277 result->push(new MonitorInfo(k(), resolve_monitor_lock(mv->basic_lock()),
278 mv->eliminated(), true));
279 } else {
280 result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()),
281 mv->eliminated(), false));
282 }
283 }
284
285 // Replace the original values with any stores that have been
286 // performed through compiledVFrame::update_monitors.
287 if (thread() == nullptr) return result; // Unmounted continuations have no thread so nothing to do.
288 GrowableArrayView<jvmtiDeferredLocalVariableSet*>* list = JvmtiDeferredUpdates::deferred_locals(thread());
289 if (list != nullptr ) {
290 // In real life this never happens or is typically a single element search
291 for (int i = 0; i < list->length(); i++) {
292 if (list->at(i)->matches(this)) {
293 list->at(i)->update_monitors(result);
294 break;
295 }
296 }
297 }
298
299 return result;
300 }
301
302
303 compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, nmethod* nm)
304 : javaVFrame(fr, reg_map, thread) {
305 _scope = nullptr;
306 _vframe_id = 0;
307 // Compiled method (native stub or Java code)
|