< prev index next >

src/hotspot/share/opto/parse3.cpp

Print this page




  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.


< prev index next >