69 // It's also OK to access static fields inside a constructor,
70 // because any thread calling the constructor must first have
71 // synchronized on the class by executing a '_new' bytecode.
72 access_OK = true;
73 }
74 }
75 }
76
77 return access_OK;
78
79 }
80
81
82 void Parse::do_field_access(bool is_get, bool is_field) {
83 bool will_link;
84 ciField* field = iter().get_field(will_link);
85 assert(will_link, "getfield: typeflow responsibility");
86
87 ciInstanceKlass* field_holder = field->holder();
88
89 if (is_field && field_holder->is_valuetype()) {
90 assert(is_get, "value type field store not supported");
91 BasicType bt = field->layout_type();
92 ValueTypeNode* vt = pop()->as_ValueType();
93 Node* value = vt->field_value_by_offset(field->offset());
94 push_node(bt, value);
95 return;
96 }
97
98 if (is_field == field->is_static()) {
99 // Interpreter will throw java_lang_IncompatibleClassChangeError
100 // Check this before allowing <clinit> methods to access static fields
101 uncommon_trap(Deoptimization::Reason_unhandled,
102 Deoptimization::Action_none);
103 return;
104 }
105
106 if (!is_field && !field_holder->is_initialized()) {
107 if (!static_field_ok_in_clinit(field, method())) {
108 uncommon_trap(Deoptimization::Reason_uninitialized,
109 Deoptimization::Action_reinterpret,
110 NULL, "!static_field_ok_in_clinit");
111 return;
112 }
113 }
114
216 ciObject* val = mirror->field_value(field).as_object();
217 if (!val->is_null_object()) {
218 type = type->join_speculative(TypePtr::NOTNULL);
219 }
220 }
221 }
222 } else {
223 type = Type::get_const_basic_type(bt);
224 }
225
226 Node* ld = NULL;
227 if (flattened) {
228 // Load flattened value type
229 ld = ValueTypeNode::make_from_flattened(this, field_klass->as_value_klass(), obj, obj, field->holder(), offset);
230 } else {
231 DecoratorSet decorators = IN_HEAP;
232 decorators |= is_vol ? MO_SEQ_CST : MO_UNORDERED;
233 ld = access_load_at(obj, adr, adr_type, type, bt, decorators);
234 if (bt == T_VALUETYPE) {
235 // Load a non-flattened value type from memory
236 ld = ValueTypeNode::make_from_oop(this, ld, field_klass->as_value_klass(), /* buffer_check */ false, /* null2default */ flattenable, iter().next_bci());
237 }
238 }
239
240 // Adjust Java stack
241 if (type2size[bt] == 1)
242 push(ld);
243 else
244 push_pair(ld);
245
246 if (must_assert_null) {
247 // Do not take a trap here. It's possible that the program
248 // will never load the field's class, and will happily see
249 // null values in this field forever. Don't stumble into a
250 // trap for such a program, or we might get a long series
251 // of useless recompilations. (Or, we might load a class
252 // which should not be loaded.) If we ever see a non-null
253 // value, we will then trap and recompile. (The trap will
254 // not need to mention the class index, since the class will
255 // already have been loaded if we ever see a non-null value.)
256 // uncommon_trap(iter().get_field_signature_index());
276 const TypePtr* adr_type = C->alias_type(field)->adr_type();
277 Node* adr = basic_plus_adr(obj, obj, offset);
278 BasicType bt = field->layout_type();
279 // Value to be stored
280 Node* val = type2size[bt] == 1 ? pop() : pop_pair();
281
282 DecoratorSet decorators = IN_HEAP;
283 decorators |= is_vol ? MO_SEQ_CST : MO_UNORDERED;
284
285 // Store the value.
286 const Type* field_type;
287 if (!field->type()->is_loaded()) {
288 field_type = TypeInstPtr::BOTTOM;
289 } else {
290 if (bt == T_OBJECT || bt == T_ARRAY || bt == T_VALUETYPE) {
291 field_type = TypeOopPtr::make_from_klass(field->type()->as_klass());
292 } else {
293 field_type = Type::BOTTOM;
294 }
295 }
296 if (field->is_flattenable() && !val->is_ValueType()) {
297 // We can see a null constant here
298 assert(val->bottom_type()->remove_speculative() == TypePtr::NULL_PTR, "Anything other than null?");
299 push(null());
300 uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
301 assert(stopped(), "dead path");
302 return;
303 } else if (field->is_flattened()) {
304 // Store flattened value type to a non-static field
305 assert(bt == T_VALUETYPE, "flattening is only supported for value type fields");
306 val->as_ValueType()->store_flattened(this, obj, obj, field->holder(), offset);
307 } else {
308 access_store_at(control(), obj, adr, adr_type, val, field_type, bt, decorators);
309 }
310
311 if (is_field) {
312 // Remember we wrote a volatile field.
313 // For not multiple copy atomic cpu (ppc64) a barrier should be issued
314 // in constructors which have such stores. See do_exits() in parse1.cpp.
315 if (is_vol) {
316 set_wrote_volatile(true);
317 }
318 set_wrote_fields(true);
319
320 // If the field is final, the rules of Java say we are in <init> or <clinit>.
321 // Note the presence of writes to final non-static fields, so that we
322 // can insert a memory barrier later on to keep the writes from floating
323 // out of the constructor.
|
69 // It's also OK to access static fields inside a constructor,
70 // because any thread calling the constructor must first have
71 // synchronized on the class by executing a '_new' bytecode.
72 access_OK = true;
73 }
74 }
75 }
76
77 return access_OK;
78
79 }
80
81
82 void Parse::do_field_access(bool is_get, bool is_field) {
83 bool will_link;
84 ciField* field = iter().get_field(will_link);
85 assert(will_link, "getfield: typeflow responsibility");
86
87 ciInstanceKlass* field_holder = field->holder();
88
89 if (is_field && field_holder->is_valuetype() && peek()->is_ValueType()) {
90 assert(is_get, "value type field store not supported");
91 ValueTypeNode* vt = pop()->as_ValueType();
92 Node* value = vt->field_value_by_offset(field->offset());
93 push_node(field->layout_type(), value);
94 return;
95 }
96
97 if (is_field == field->is_static()) {
98 // Interpreter will throw java_lang_IncompatibleClassChangeError
99 // Check this before allowing <clinit> methods to access static fields
100 uncommon_trap(Deoptimization::Reason_unhandled,
101 Deoptimization::Action_none);
102 return;
103 }
104
105 if (!is_field && !field_holder->is_initialized()) {
106 if (!static_field_ok_in_clinit(field, method())) {
107 uncommon_trap(Deoptimization::Reason_uninitialized,
108 Deoptimization::Action_reinterpret,
109 NULL, "!static_field_ok_in_clinit");
110 return;
111 }
112 }
113
215 ciObject* val = mirror->field_value(field).as_object();
216 if (!val->is_null_object()) {
217 type = type->join_speculative(TypePtr::NOTNULL);
218 }
219 }
220 }
221 } else {
222 type = Type::get_const_basic_type(bt);
223 }
224
225 Node* ld = NULL;
226 if (flattened) {
227 // Load flattened value type
228 ld = ValueTypeNode::make_from_flattened(this, field_klass->as_value_klass(), obj, obj, field->holder(), offset);
229 } else {
230 DecoratorSet decorators = IN_HEAP;
231 decorators |= is_vol ? MO_SEQ_CST : MO_UNORDERED;
232 ld = access_load_at(obj, adr, adr_type, type, bt, decorators);
233 if (bt == T_VALUETYPE) {
234 // Load a non-flattened value type from memory
235 if (field_klass->as_value_klass()->is_scalarizable()) {
236 ld = ValueTypeNode::make_from_oop(this, ld, field_klass->as_value_klass(), /* buffer_check */ false, /* null2default */ flattenable, iter().next_bci());
237 } else if (gvn().type(ld)->maybe_null()){
238 ld = filter_null(ld, flattenable, field_klass->as_value_klass(), iter().next_bci());
239 }
240 }
241 }
242
243 // Adjust Java stack
244 if (type2size[bt] == 1)
245 push(ld);
246 else
247 push_pair(ld);
248
249 if (must_assert_null) {
250 // Do not take a trap here. It's possible that the program
251 // will never load the field's class, and will happily see
252 // null values in this field forever. Don't stumble into a
253 // trap for such a program, or we might get a long series
254 // of useless recompilations. (Or, we might load a class
255 // which should not be loaded.) If we ever see a non-null
256 // value, we will then trap and recompile. (The trap will
257 // not need to mention the class index, since the class will
258 // already have been loaded if we ever see a non-null value.)
259 // uncommon_trap(iter().get_field_signature_index());
279 const TypePtr* adr_type = C->alias_type(field)->adr_type();
280 Node* adr = basic_plus_adr(obj, obj, offset);
281 BasicType bt = field->layout_type();
282 // Value to be stored
283 Node* val = type2size[bt] == 1 ? pop() : pop_pair();
284
285 DecoratorSet decorators = IN_HEAP;
286 decorators |= is_vol ? MO_SEQ_CST : MO_UNORDERED;
287
288 // Store the value.
289 const Type* field_type;
290 if (!field->type()->is_loaded()) {
291 field_type = TypeInstPtr::BOTTOM;
292 } else {
293 if (bt == T_OBJECT || bt == T_ARRAY || bt == T_VALUETYPE) {
294 field_type = TypeOopPtr::make_from_klass(field->type()->as_klass());
295 } else {
296 field_type = Type::BOTTOM;
297 }
298 }
299 if (field->is_flattenable() && !val->is_ValueType() && gvn().type(val)->maybe_null()) {
300 // We can see a null constant here
301 assert(val->bottom_type()->remove_speculative() == TypePtr::NULL_PTR, "Anything other than null?");
302 push(null());
303 uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
304 assert(stopped(), "dead path");
305 return;
306 } else if (field->is_flattened()) {
307 if (!val->is_ValueType()) {
308 assert(!gvn().type(val)->maybe_null(), "should never be null");
309 val = ValueTypeNode::make_from_oop(this, val, field->type()->as_value_klass());
310 }
311 // Store flattened value type to a non-static field
312 assert(bt == T_VALUETYPE, "flattening is only supported for value type fields");
313 val->as_ValueType()->store_flattened(this, obj, obj, field->holder(), offset);
314 } else {
315 access_store_at(control(), obj, adr, adr_type, val, field_type, bt, decorators);
316 }
317
318 if (is_field) {
319 // Remember we wrote a volatile field.
320 // For not multiple copy atomic cpu (ppc64) a barrier should be issued
321 // in constructors which have such stores. See do_exits() in parse1.cpp.
322 if (is_vol) {
323 set_wrote_volatile(true);
324 }
325 set_wrote_fields(true);
326
327 // If the field is final, the rules of Java say we are in <init> or <clinit>.
328 // Note the presence of writes to final non-static fields, so that we
329 // can insert a memory barrier later on to keep the writes from floating
330 // out of the constructor.
|