24
25 #include "precompiled.hpp"
26 #include "code/debugInfo.hpp"
27 #include "oops/access.hpp"
28 #include "oops/compressedOops.inline.hpp"
29 #include "oops/oop.hpp"
30 #include "runtime/frame.inline.hpp"
31 #include "runtime/globals.hpp"
32 #include "runtime/handles.inline.hpp"
33 #include "runtime/stackValue.hpp"
34 #if INCLUDE_ZGC
35 #include "gc/z/zBarrier.inline.hpp"
36 #endif
37 #if INCLUDE_SHENANDOAHGC
38 #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp"
39 #endif
40
41 class RegisterMap;
42 class SmallRegisterMap;
43
44 template StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* reg_map, ScopeValue* sv);
45 template StackValue* StackValue::create_stack_value(const frame* fr, const SmallRegisterMap* reg_map, ScopeValue* sv);
46
47 template<typename RegisterMapT>
48 StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMapT* reg_map, ScopeValue* sv) {
49 return create_stack_value(sv, stack_value_address(fr, reg_map, sv), reg_map);
50 }
51
52 static oop oop_from_oop_location(stackChunkOop chunk, void* addr) {
53 if (addr == nullptr) {
54 return nullptr;
55 }
56
57 if (UseCompressedOops) {
58 // When compressed oops is enabled, an oop location may
59 // contain narrow oop values - we deal with that here
60
61 if (chunk != nullptr && chunk->has_bitmap()) {
62 // Transformed stack chunk with narrow oops
63 return chunk->load_oop((narrowOop*)addr);
64 }
65
66 #ifdef _LP64
67 if (CompressedOops::is_base(*(void**)addr)) {
68 // Compiled code may produce decoded oop = narrow_oop_base
69 // when a narrow oop implicit null check is used.
70 // The narrow_oop_base could be null or be the address
131
132 return val;
133 }
134
135 StackValue* StackValue::create_stack_value_from_oop_location(stackChunkOop chunk, void* addr) {
136 oop val = oop_from_oop_location(chunk, addr);
137 assert(oopDesc::is_oop_or_null(val), "bad oop found at " INTPTR_FORMAT " in_cont: %d compressed: %d",
138 p2i(addr), chunk != nullptr, chunk != nullptr && chunk->has_bitmap() && UseCompressedOops);
139 Handle h(Thread::current(), val); // Wrap a handle around the oop
140 return new StackValue(h);
141 }
142
143 StackValue* StackValue::create_stack_value_from_narrowOop_location(stackChunkOop chunk, void* addr, bool is_register) {
144 oop val = oop_from_narrowOop_location(chunk, addr, is_register);
145 assert(oopDesc::is_oop_or_null(val), "bad oop found at " INTPTR_FORMAT " in_cont: %d compressed: %d",
146 p2i(addr), chunk != nullptr, chunk != nullptr && chunk->has_bitmap() && UseCompressedOops);
147 Handle h(Thread::current(), val); // Wrap a handle around the oop
148 return new StackValue(h);
149 }
150
151 template<typename RegisterMapT>
152 StackValue* StackValue::create_stack_value(ScopeValue* sv, address value_addr, const RegisterMapT* reg_map) {
153 stackChunkOop chunk = reg_map->stack_chunk()();
154 if (sv->is_location()) {
155 // Stack or register value
156 Location loc = ((LocationValue *)sv)->location();
157
158 // Then package it right depending on type
159 // Note: the transfer of the data is thru a union that contains
160 // an intptr_t. This is because an interpreter stack slot is
161 // really an intptr_t. The use of a union containing an intptr_t
162 // ensures that on a 64 bit platform we have proper alignment
163 // and that we store the value where the interpreter will expect
164 // to find it (i.e. proper endian). Similarly on a 32bit platform
165 // using the intptr_t ensures that when a value is larger than
166 // a stack slot (jlong/jdouble) that we capture the proper part
167 // of the value for the stack slot in question.
168 //
169 switch( loc.type() ) {
170 case Location::float_in_dbl: { // Holds a float in a double register?
171 // The callee has no clue whether the register holds a float,
172 // double or is unused. He always saves a double. Here we know
233 } else if (sv->is_constant_oop()) {
234 // constant oop
235 return new StackValue(sv->as_ConstantOopReadValue()->value());
236 #ifdef _LP64
237 } else if (sv->is_constant_double()) {
238 // Constant double in a single stack slot
239 union { intptr_t p; double d; } value;
240 value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
241 value.d = ((ConstantDoubleValue *)sv)->value();
242 return new StackValue(value.p);
243 } else if (sv->is_constant_long()) {
244 // Constant long in a single stack slot
245 union { intptr_t p; jlong jl; } value;
246 value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
247 value.jl = ((ConstantLongValue *)sv)->value();
248 return new StackValue(value.p);
249 #endif
250 } else if (sv->is_object()) { // Scalar replaced object in compiled frame
251 ObjectValue* ov = (ObjectValue *)sv;
252 Handle hdl = ov->value();
253 return new StackValue(hdl, hdl.is_null() && ov->is_scalar_replaced() ? 1 : 0);
254 } else if (sv->is_marker()) {
255 // Should never need to directly construct a marker.
256 ShouldNotReachHere();
257 }
258 // Unknown ScopeValue type
259 ShouldNotReachHere();
260 return new StackValue((intptr_t) 0); // dummy
261 }
262
263 template address StackValue::stack_value_address(const frame* fr, const RegisterMap* reg_map, ScopeValue* sv);
264 template address StackValue::stack_value_address(const frame* fr, const SmallRegisterMap* reg_map, ScopeValue* sv);
265
266 template<typename RegisterMapT>
267 address StackValue::stack_value_address(const frame* fr, const RegisterMapT* reg_map, ScopeValue* sv) {
268 if (!sv->is_location()) {
269 return nullptr;
270 }
271 Location loc = ((LocationValue *)sv)->location();
272 if (loc.type() == Location::invalid) {
273 return nullptr;
|
24
25 #include "precompiled.hpp"
26 #include "code/debugInfo.hpp"
27 #include "oops/access.hpp"
28 #include "oops/compressedOops.inline.hpp"
29 #include "oops/oop.hpp"
30 #include "runtime/frame.inline.hpp"
31 #include "runtime/globals.hpp"
32 #include "runtime/handles.inline.hpp"
33 #include "runtime/stackValue.hpp"
34 #if INCLUDE_ZGC
35 #include "gc/z/zBarrier.inline.hpp"
36 #endif
37 #if INCLUDE_SHENANDOAHGC
38 #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp"
39 #endif
40
41 class RegisterMap;
42 class SmallRegisterMap;
43
44
45 static oop oop_from_oop_location(stackChunkOop chunk, void* addr) {
46 if (addr == nullptr) {
47 return nullptr;
48 }
49
50 if (UseCompressedOops) {
51 // When compressed oops is enabled, an oop location may
52 // contain narrow oop values - we deal with that here
53
54 if (chunk != nullptr && chunk->has_bitmap()) {
55 // Transformed stack chunk with narrow oops
56 return chunk->load_oop((narrowOop*)addr);
57 }
58
59 #ifdef _LP64
60 if (CompressedOops::is_base(*(void**)addr)) {
61 // Compiled code may produce decoded oop = narrow_oop_base
62 // when a narrow oop implicit null check is used.
63 // The narrow_oop_base could be null or be the address
124
125 return val;
126 }
127
128 StackValue* StackValue::create_stack_value_from_oop_location(stackChunkOop chunk, void* addr) {
129 oop val = oop_from_oop_location(chunk, addr);
130 assert(oopDesc::is_oop_or_null(val), "bad oop found at " INTPTR_FORMAT " in_cont: %d compressed: %d",
131 p2i(addr), chunk != nullptr, chunk != nullptr && chunk->has_bitmap() && UseCompressedOops);
132 Handle h(Thread::current(), val); // Wrap a handle around the oop
133 return new StackValue(h);
134 }
135
136 StackValue* StackValue::create_stack_value_from_narrowOop_location(stackChunkOop chunk, void* addr, bool is_register) {
137 oop val = oop_from_narrowOop_location(chunk, addr, is_register);
138 assert(oopDesc::is_oop_or_null(val), "bad oop found at " INTPTR_FORMAT " in_cont: %d compressed: %d",
139 p2i(addr), chunk != nullptr, chunk != nullptr && chunk->has_bitmap() && UseCompressedOops);
140 Handle h(Thread::current(), val); // Wrap a handle around the oop
141 return new StackValue(h);
142 }
143
144
145 template StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* reg_map, ScopeValue* sv);
146 template StackValue* StackValue::create_stack_value(const frame* fr, const SmallRegisterMap* reg_map, ScopeValue* sv);
147
148 template<typename RegisterMapT>
149 StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMapT* reg_map, ScopeValue* sv) {
150 address value_addr = stack_value_address(fr, reg_map, sv);
151 stackChunkOop chunk = reg_map->stack_chunk()();
152 if (sv->is_location()) {
153 // Stack or register value
154 Location loc = ((LocationValue *)sv)->location();
155
156 // Then package it right depending on type
157 // Note: the transfer of the data is thru a union that contains
158 // an intptr_t. This is because an interpreter stack slot is
159 // really an intptr_t. The use of a union containing an intptr_t
160 // ensures that on a 64 bit platform we have proper alignment
161 // and that we store the value where the interpreter will expect
162 // to find it (i.e. proper endian). Similarly on a 32bit platform
163 // using the intptr_t ensures that when a value is larger than
164 // a stack slot (jlong/jdouble) that we capture the proper part
165 // of the value for the stack slot in question.
166 //
167 switch( loc.type() ) {
168 case Location::float_in_dbl: { // Holds a float in a double register?
169 // The callee has no clue whether the register holds a float,
170 // double or is unused. He always saves a double. Here we know
231 } else if (sv->is_constant_oop()) {
232 // constant oop
233 return new StackValue(sv->as_ConstantOopReadValue()->value());
234 #ifdef _LP64
235 } else if (sv->is_constant_double()) {
236 // Constant double in a single stack slot
237 union { intptr_t p; double d; } value;
238 value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
239 value.d = ((ConstantDoubleValue *)sv)->value();
240 return new StackValue(value.p);
241 } else if (sv->is_constant_long()) {
242 // Constant long in a single stack slot
243 union { intptr_t p; jlong jl; } value;
244 value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
245 value.jl = ((ConstantLongValue *)sv)->value();
246 return new StackValue(value.p);
247 #endif
248 } else if (sv->is_object()) { // Scalar replaced object in compiled frame
249 ObjectValue* ov = (ObjectValue *)sv;
250 Handle hdl = ov->value();
251 bool scalar_replaced = hdl.is_null() && ov->is_scalar_replaced();
252 if (ov->maybe_null()) {
253 // Don't treat inline type as scalar replaced if it is null
254 jint is_init = StackValue::create_stack_value(fr, reg_map, ov->is_init())->get_jint();
255 scalar_replaced &= (is_init != 0);
256 }
257 return new StackValue(hdl, scalar_replaced ? 1 : 0);
258 } else if (sv->is_marker()) {
259 // Should never need to directly construct a marker.
260 ShouldNotReachHere();
261 }
262 // Unknown ScopeValue type
263 ShouldNotReachHere();
264 return new StackValue((intptr_t) 0); // dummy
265 }
266
267 template address StackValue::stack_value_address(const frame* fr, const RegisterMap* reg_map, ScopeValue* sv);
268 template address StackValue::stack_value_address(const frame* fr, const SmallRegisterMap* reg_map, ScopeValue* sv);
269
270 template<typename RegisterMapT>
271 address StackValue::stack_value_address(const frame* fr, const RegisterMapT* reg_map, ScopeValue* sv) {
272 if (!sv->is_location()) {
273 return nullptr;
274 }
275 Location loc = ((LocationValue *)sv)->location();
276 if (loc.type() == Location::invalid) {
277 return nullptr;
|