< prev index next >

src/hotspot/share/opto/parse3.cpp

Print this page




 117 
 118   assert(field->will_link(method(), bc()), "getfield: typeflow responsibility");
 119 
 120   // Note:  We do not check for an unloaded field type here any more.
 121 
 122   // Generate code for the object pointer.
 123   Node* obj;
 124   if (is_field) {
 125     int obj_depth = is_get ? 0 : field->type()->size();
 126     obj = null_check(peek(obj_depth));
 127     // Compile-time detect of null-exception?
 128     if (stopped())  return;
 129 
 130 #ifdef ASSERT
 131     const TypeInstPtr *tjp = TypeInstPtr::make(TypePtr::NotNull, iter().get_declared_field_holder());
 132     assert(_gvn.type(obj)->higher_equal(tjp), "cast_up is no longer needed");
 133 #endif
 134 
 135     if (is_get) {
 136       (void) pop();  // pop receiver before getting
 137       do_get_xxx(obj, field, is_field);
 138     } else {
 139       do_put_xxx(obj, field, is_field);
 140       if (stopped()) {
 141         return;
 142       }
 143       (void) pop();  // pop receiver after putting
 144     }
 145   } else {
 146     const TypeInstPtr* tip = TypeInstPtr::make(field_holder->java_mirror());
 147     obj = _gvn.makecon(tip);
 148     if (is_get) {
 149       do_get_xxx(obj, field, is_field);
 150     } else {
 151       do_put_xxx(obj, field, is_field);
 152     }
 153   }
 154 }
 155 
 156 void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) {
 157   BasicType bt = field->layout_type();
 158 
 159   // Does this field have a constant value?  If so, just push the value.
 160   if (field->is_constant() &&
 161       // Keep consistent with types found by ciTypeFlow: for an
 162       // unloaded field type, ciTypeFlow::StateVector::do_getstatic()
 163       // speculates the field is null. The code in the rest of this
 164       // method does the same. We must not bypass it and use a non
 165       // null constant here.
 166       (bt != T_OBJECT || field->type()->is_loaded())) {
 167     // final or stable field
 168     Node* con = make_constant_from_field(field, obj);
 169     if (con != NULL) {
 170       push_node(field->layout_type(), con);
 171       return;
 172     }
 173   }
 174 
 175   ciType* field_klass = field->type();
 176   bool is_vol = field->is_volatile();


 194     } else if (field->is_static_constant()) {
 195       // This can happen if the constant oop is non-perm.
 196       ciObject* con = field->constant_value().as_object();
 197       // Do not "join" in the previous type; it doesn't add value,
 198       // and may yield a vacuous result if the field is of interface type.
 199       if (con->is_null_object()) {
 200         type = TypePtr::NULL_PTR;
 201       } else {
 202         type = TypeOopPtr::make_from_constant(con)->isa_oopptr();
 203       }
 204       assert(type != NULL, "field singleton type must be consistent");
 205     } else {
 206       type = TypeOopPtr::make_from_klass(field_klass->as_klass());
 207       if (bt == T_VALUETYPE && field->is_static()) {
 208         // Check if static value type field is already initialized
 209         assert(!flattened, "static fields should not be flattened");
 210         ciInstance* mirror = field->holder()->java_mirror();
 211         ciObject* val = mirror->field_value(field).as_object();
 212         if (!val->is_null_object()) {
 213           type = type->join_speculative(TypePtr::NOTNULL);

 214         }
 215       }
 216     }
 217   } else {
 218     type = Type::get_const_basic_type(bt);
 219   }
 220 
 221   Node* ld = NULL;
 222   if (flattened) {
 223     // Load flattened value type
 224     ld = ValueTypeNode::make_from_flattened(this, field_klass->as_value_klass(), obj, obj, field->holder(), offset);
 225   } else {
 226     DecoratorSet decorators = IN_HEAP;
 227     decorators |= is_vol ? MO_SEQ_CST : MO_UNORDERED;
 228     ld = access_load_at(obj, adr, adr_type, type, bt, decorators);
 229     if (flattenable) {
 230       // Load a non-flattened but flattenable value type from memory
 231       if (field_klass->as_value_klass()->is_scalarizable()) {
 232         ld = ValueTypeNode::make_from_oop(this, ld, field_klass->as_value_klass());
 233       } else {




 117 
 118   assert(field->will_link(method(), bc()), "getfield: typeflow responsibility");
 119 
 120   // Note:  We do not check for an unloaded field type here any more.
 121 
 122   // Generate code for the object pointer.
 123   Node* obj;
 124   if (is_field) {
 125     int obj_depth = is_get ? 0 : field->type()->size();
 126     obj = null_check(peek(obj_depth));
 127     // Compile-time detect of null-exception?
 128     if (stopped())  return;
 129 
 130 #ifdef ASSERT
 131     const TypeInstPtr *tjp = TypeInstPtr::make(TypePtr::NotNull, iter().get_declared_field_holder());
 132     assert(_gvn.type(obj)->higher_equal(tjp), "cast_up is no longer needed");
 133 #endif
 134 
 135     if (is_get) {
 136       (void) pop();  // pop receiver before getting
 137       do_get_xxx(obj, field);
 138     } else {
 139       do_put_xxx(obj, field, is_field);
 140       if (stopped()) {
 141         return;
 142       }
 143       (void) pop();  // pop receiver after putting
 144     }
 145   } else {
 146     const TypeInstPtr* tip = TypeInstPtr::make(field_holder->java_mirror());
 147     obj = _gvn.makecon(tip);
 148     if (is_get) {
 149       do_get_xxx(obj, field);
 150     } else {
 151       do_put_xxx(obj, field, is_field);
 152     }
 153   }
 154 }
 155 
 156 void Parse::do_get_xxx(Node* obj, ciField* field) {
 157   BasicType bt = field->layout_type();
 158 
 159   // Does this field have a constant value?  If so, just push the value.
 160   if (field->is_constant() &&
 161       // Keep consistent with types found by ciTypeFlow: for an
 162       // unloaded field type, ciTypeFlow::StateVector::do_getstatic()
 163       // speculates the field is null. The code in the rest of this
 164       // method does the same. We must not bypass it and use a non
 165       // null constant here.
 166       (bt != T_OBJECT || field->type()->is_loaded())) {
 167     // final or stable field
 168     Node* con = make_constant_from_field(field, obj);
 169     if (con != NULL) {
 170       push_node(field->layout_type(), con);
 171       return;
 172     }
 173   }
 174 
 175   ciType* field_klass = field->type();
 176   bool is_vol = field->is_volatile();


 194     } else if (field->is_static_constant()) {
 195       // This can happen if the constant oop is non-perm.
 196       ciObject* con = field->constant_value().as_object();
 197       // Do not "join" in the previous type; it doesn't add value,
 198       // and may yield a vacuous result if the field is of interface type.
 199       if (con->is_null_object()) {
 200         type = TypePtr::NULL_PTR;
 201       } else {
 202         type = TypeOopPtr::make_from_constant(con)->isa_oopptr();
 203       }
 204       assert(type != NULL, "field singleton type must be consistent");
 205     } else {
 206       type = TypeOopPtr::make_from_klass(field_klass->as_klass());
 207       if (bt == T_VALUETYPE && field->is_static()) {
 208         // Check if static value type field is already initialized
 209         assert(!flattened, "static fields should not be flattened");
 210         ciInstance* mirror = field->holder()->java_mirror();
 211         ciObject* val = mirror->field_value(field).as_object();
 212         if (!val->is_null_object()) {
 213           type = type->join_speculative(TypePtr::NOTNULL);
 214           flattenable = true; // Null-free, treat as flattenable
 215         }
 216       }
 217     }
 218   } else {
 219     type = Type::get_const_basic_type(bt);
 220   }
 221 
 222   Node* ld = NULL;
 223   if (flattened) {
 224     // Load flattened value type
 225     ld = ValueTypeNode::make_from_flattened(this, field_klass->as_value_klass(), obj, obj, field->holder(), offset);
 226   } else {
 227     DecoratorSet decorators = IN_HEAP;
 228     decorators |= is_vol ? MO_SEQ_CST : MO_UNORDERED;
 229     ld = access_load_at(obj, adr, adr_type, type, bt, decorators);
 230     if (flattenable) {
 231       // Load a non-flattened but flattenable value type from memory
 232       if (field_klass->as_value_klass()->is_scalarizable()) {
 233         ld = ValueTypeNode::make_from_oop(this, ld, field_klass->as_value_klass());
 234       } else {


< prev index next >