< prev index next >

src/hotspot/share/opto/parse2.cpp

Print this page




  50 #ifndef PRODUCT
  51 extern int explicit_null_checks_inserted,
  52            explicit_null_checks_elided;
  53 #endif
  54 
  55 //---------------------------------array_load----------------------------------
  56 void Parse::array_load(BasicType bt) {
  57   const Type* elemtype = Type::TOP;
  58   Node* adr = array_addressing(bt, 0, &elemtype);
  59   if (stopped())  return;     // guaranteed null or range check
  60 
  61   Node* idx = pop();
  62   Node* ary = pop();
  63 
  64   // Handle value type arrays
  65   const TypeOopPtr* elemptr = elemtype->make_oopptr();
  66   const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr();
  67   if (elemtype->isa_valuetype() != NULL) {
  68     // Load from flattened value type array
  69     ciValueKlass* vk = elemtype->is_valuetype()->value_klass();
  70     ValueTypeNode* vt = ValueTypeNode::make_from_flattened(this, vk, ary, adr);
  71     push(vt);
  72     return;
  73   } else if (elemptr != NULL && elemptr->is_valuetypeptr()) {
  74     // Load from non-flattened value type array (elements can never be null)
  75     bt = T_VALUETYPE;
  76     assert(elemptr->meet(TypePtr::NULL_PTR) != elemptr, "value type array elements should never be null");
  77   } else if (ValueArrayFlatten && elemptr != NULL && elemptr->can_be_value_type() &&
  78              !ary_t->klass_is_exact()) {
  79     // Cannot statically determine if array is flattened, emit runtime check
  80     IdealKit ideal(this);
  81     IdealVariable res(ideal);
  82     ideal.declarations_done();
  83     Node* kls = load_object_klass(ary);
  84     Node* tag = load_lh_array_tag(kls);
  85     ideal.if_then(tag, BoolTest::ne, intcon(Klass::_lh_array_tag_vt_value)); {
  86       // non flattened
  87       sync_kit(ideal);
  88       const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);
  89       elemtype = ary_t->elem()->make_oopptr();
  90       Node* ld = access_load_at(ary, adr, adr_type, elemtype, bt,


 137 
 138       ideal.sync_kit(this);
 139       ideal.set(res, alloc_obj);
 140     } ideal.end_if();
 141     sync_kit(ideal);
 142     push_node(bt, ideal.value(res));
 143     return;
 144   }
 145 
 146   if (elemtype == TypeInt::BOOL) {
 147     bt = T_BOOLEAN;
 148   } else if (bt == T_OBJECT) {
 149     elemtype = ary_t->elem()->make_oopptr();
 150   }
 151 
 152   const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);
 153   Node* ld = access_load_at(ary, adr, adr_type, elemtype, bt,
 154                             IN_HEAP | IS_ARRAY | C2_CONTROL_DEPENDENT_LOAD);
 155   if (bt == T_VALUETYPE) {
 156     // Loading a non-flattened (but flattenable) value type from an array
 157     assert(!gvn().type(ld)->is_ptr()->maybe_null(), "value type array elements should never be null");

 158     ld = ValueTypeNode::make_from_oop(this, ld, elemptr->value_klass());
 159   }

 160 
 161   push_node(bt, ld);
 162 }
 163 
 164 
 165 //--------------------------------array_store----------------------------------
 166 void Parse::array_store(BasicType bt) {
 167   const Type* elemtype = Type::TOP;
 168   Node* adr = array_addressing(bt, type2size[bt], &elemtype);
 169   if (stopped())  return;     // guaranteed null or range check
 170   Node* cast_val = NULL;
 171   if (bt == T_OBJECT) {
 172     cast_val = array_store_check();
 173     if (stopped()) return;
 174   }
 175   Node* val = pop_node(bt); // Value to store
 176   Node* idx = pop();        // Index in the array
 177   Node* ary = pop();        // The array itself
 178 
 179   const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr();
 180   if (bt == T_OBJECT) {
 181     const TypeOopPtr* elemptr = elemtype->make_oopptr();
 182     const Type* val_t = _gvn.type(val);
 183     if (elemtype->isa_valuetype() != NULL) {
 184       // Store to flattened value type array
 185       if (!val->is_ValueType() && val_t == TypePtr::NULL_PTR) {


 186         // Can not store null into a value type array

 187         inc_sp(3);
 188         uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
 189         return;
 190       }



 191       cast_val->as_ValueType()->store_flattened(this, ary, adr);
 192       return;
 193     } else if (elemptr->is_valuetypeptr()) {
 194       // Store to non-flattened value type array
 195       if (!val->is_ValueType() && val_t == TypePtr::NULL_PTR) {

 196         // Can not store null into a value type array

 197         inc_sp(3);
 198         uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
 199         return;
 200       }
 201     } else if (elemptr->can_be_value_type() && !ary_t->klass_is_exact() &&
 202                (val->is_ValueType() || val_t == TypePtr::NULL_PTR || val_t->is_oopptr()->can_be_value_type())) {
 203       if (ValueArrayFlatten) {
 204         IdealKit ideal(this);
 205         Node* kls = load_object_klass(ary);
 206         Node* layout_val = load_lh_array_tag(kls);
 207         ideal.if_then(layout_val, BoolTest::ne, intcon(Klass::_lh_array_tag_vt_value)); {
 208           // non flattened
 209           sync_kit(ideal);
 210 
 211           if (!val->is_ValueType() && TypePtr::NULL_PTR->higher_equal(val_t)) {
 212             gen_value_type_array_guard(ary, val, 3);
 213           }
 214 
 215           const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);
 216           elemtype = ary_t->elem()->make_oopptr();
 217           access_store_at(control(), ary, adr, adr_type, val, elemtype, bt, MO_UNORDERED | IN_HEAP | IS_ARRAY);
 218           ideal.sync_kit(this);
 219         } ideal.else_(); {
 220           // flattened
 221           // Object/interface array must be flattened, cast it
 222           if (val->is_ValueType()) {
 223             sync_kit(ideal);
 224             const TypeValueType* vt = _gvn.type(val)->is_valuetype();
 225             ciArrayKlass* array_klass = ciArrayKlass::make(vt->value_klass());
 226             const TypeAryPtr* arytype = TypeOopPtr::make_from_klass(array_klass)->isa_aryptr();
 227             ary = _gvn.transform(new CheckCastPPNode(control(), ary, arytype));
 228             adr = array_element_address(ary, idx, T_OBJECT, arytype->size(), control());
 229             val->as_ValueType()->store_flattened(this, ary, adr);
 230             ideal.sync_kit(this);
 231           } else {
 232             if (TypePtr::NULL_PTR->higher_equal(val_t)) {
 233               sync_kit(ideal);
 234               Node* null_ctl = top();
 235               val = null_check_oop(val, &null_ctl);
 236               {
 237                 assert(null_ctl != top(), "expected to possibly be null");
 238                 PreserveJVMState pjvms(this);
 239                 set_control(null_ctl);
 240                 inc_sp(3);
 241                 uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
 242               }
 243               ideal.sync_kit(this);
 244             }
 245 
 246             if (!ideal.ctrl()->is_top()) {
 247               ideal.make_leaf_call(OptoRuntime::store_unknown_value_Type(),
 248                                    CAST_FROM_FN_PTR(address, OptoRuntime::store_unknown_value),
 249                                    "store_unknown_value",
 250                                    val, ary, idx);
 251             }
 252           }
 253         } ideal.end_if();
 254         sync_kit(ideal);
 255         return;
 256       } else {
 257         if (!val->is_ValueType() && TypePtr::NULL_PTR->higher_equal(val_t)) {
 258           gen_value_type_array_guard(ary, val, 3);
 259         }
 260       }
 261     }
 262   }




  50 #ifndef PRODUCT
  51 extern int explicit_null_checks_inserted,
  52            explicit_null_checks_elided;
  53 #endif
  54 
  55 //---------------------------------array_load----------------------------------
  56 void Parse::array_load(BasicType bt) {
  57   const Type* elemtype = Type::TOP;
  58   Node* adr = array_addressing(bt, 0, &elemtype);
  59   if (stopped())  return;     // guaranteed null or range check
  60 
  61   Node* idx = pop();
  62   Node* ary = pop();
  63 
  64   // Handle value type arrays
  65   const TypeOopPtr* elemptr = elemtype->make_oopptr();
  66   const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr();
  67   if (elemtype->isa_valuetype() != NULL) {
  68     // Load from flattened value type array
  69     ciValueKlass* vk = elemtype->is_valuetype()->value_klass();
  70     Node* vt = ValueTypeNode::make_from_flattened(this, vk, ary, adr);
  71     push(vt);
  72     return;
  73   } else if (elemptr != NULL && elemptr->is_valuetypeptr()) {
  74     // Load from non-flattened value type array (elements can never be null)
  75     bt = T_VALUETYPE;
  76     assert(elemptr->meet(TypePtr::NULL_PTR) != elemptr, "value type array elements should never be null");
  77   } else if (ValueArrayFlatten && elemptr != NULL && elemptr->can_be_value_type() &&
  78              !ary_t->klass_is_exact()) {
  79     // Cannot statically determine if array is flattened, emit runtime check
  80     IdealKit ideal(this);
  81     IdealVariable res(ideal);
  82     ideal.declarations_done();
  83     Node* kls = load_object_klass(ary);
  84     Node* tag = load_lh_array_tag(kls);
  85     ideal.if_then(tag, BoolTest::ne, intcon(Klass::_lh_array_tag_vt_value)); {
  86       // non flattened
  87       sync_kit(ideal);
  88       const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);
  89       elemtype = ary_t->elem()->make_oopptr();
  90       Node* ld = access_load_at(ary, adr, adr_type, elemtype, bt,


 137 
 138       ideal.sync_kit(this);
 139       ideal.set(res, alloc_obj);
 140     } ideal.end_if();
 141     sync_kit(ideal);
 142     push_node(bt, ideal.value(res));
 143     return;
 144   }
 145 
 146   if (elemtype == TypeInt::BOOL) {
 147     bt = T_BOOLEAN;
 148   } else if (bt == T_OBJECT) {
 149     elemtype = ary_t->elem()->make_oopptr();
 150   }
 151 
 152   const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);
 153   Node* ld = access_load_at(ary, adr, adr_type, elemtype, bt,
 154                             IN_HEAP | IS_ARRAY | C2_CONTROL_DEPENDENT_LOAD);
 155   if (bt == T_VALUETYPE) {
 156     // Loading a non-flattened (but flattenable) value type from an array
 157     assert(!gvn().type(ld)->maybe_null(), "value type array elements should never be null");
 158     if (elemptr->value_klass()->is_scalarizable()) {
 159       ld = ValueTypeNode::make_from_oop(this, ld, elemptr->value_klass());
 160     }
 161   }
 162 
 163   push_node(bt, ld);
 164 }
 165 
 166 
 167 //--------------------------------array_store----------------------------------
 168 void Parse::array_store(BasicType bt) {
 169   const Type* elemtype = Type::TOP;
 170   Node* adr = array_addressing(bt, type2size[bt], &elemtype);
 171   if (stopped())  return;     // guaranteed null or range check
 172   Node* cast_val = NULL;
 173   if (bt == T_OBJECT) {
 174     cast_val = array_store_check();
 175     if (stopped()) return;
 176   }
 177   Node* val = pop_node(bt); // Value to store
 178   Node* idx = pop();        // Index in the array
 179   Node* ary = pop();        // The array itself
 180 
 181   const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr();
 182   if (bt == T_OBJECT) {
 183     const TypeOopPtr* elemptr = elemtype->make_oopptr();
 184     const Type* val_t = _gvn.type(val);
 185     if (elemtype->isa_valuetype() != NULL) {
 186       // Store to flattened value type array
 187       val_t = _gvn.type(cast_val);
 188       if (!cast_val->is_ValueType()) {
 189         if (val_t->maybe_null()) {
 190           // Can not store null into a value type array
 191           assert(val_t == TypePtr::NULL_PTR, "Anything other than null?");
 192           inc_sp(3);
 193           uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
 194           return;
 195         }
 196         assert(!val_t->maybe_null(), "should never be null");
 197         cast_val = ValueTypeNode::make_from_oop(this, cast_val, elemtype->is_valuetype()->value_klass());
 198       }
 199       cast_val->as_ValueType()->store_flattened(this, ary, adr);
 200       return;
 201     } else if (elemptr->is_valuetypeptr()) {
 202       // Store to non-flattened value type array
 203       val_t = _gvn.type(cast_val);
 204       if (!cast_val->is_ValueType() && val_t->maybe_null()) {
 205         // Can not store null into a value type array
 206         assert(val_t == TypePtr::NULL_PTR, "Anything other than null?");
 207         inc_sp(3);
 208         uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
 209         return;
 210       }
 211     } else if (elemptr->can_be_value_type() && !ary_t->klass_is_exact() &&
 212                (val->is_ValueType() || val_t == TypePtr::NULL_PTR || val_t->is_oopptr()->can_be_value_type())) {
 213       if (ValueArrayFlatten) {
 214         IdealKit ideal(this);
 215         Node* kls = load_object_klass(ary);
 216         Node* layout_val = load_lh_array_tag(kls);
 217         ideal.if_then(layout_val, BoolTest::ne, intcon(Klass::_lh_array_tag_vt_value)); {
 218           // non flattened
 219           sync_kit(ideal);
 220 
 221           if (!val->is_ValueType() && TypePtr::NULL_PTR->higher_equal(val_t)) {
 222             gen_value_type_array_guard(ary, val, 3);
 223           }
 224 
 225           const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);
 226           elemtype = ary_t->elem()->make_oopptr();
 227           access_store_at(control(), ary, adr, adr_type, val, elemtype, bt, MO_UNORDERED | IN_HEAP | IS_ARRAY);
 228           ideal.sync_kit(this);
 229         } ideal.else_(); {
 230           // flattened
 231           // Object/interface array must be flattened, cast it
 232           if (val->is_ValueType()) {
 233             sync_kit(ideal);
 234             const TypeValueType* vt = _gvn.type(val)->is_valuetype();
 235             ciArrayKlass* array_klass = ciArrayKlass::make(vt->value_klass());
 236             const TypeAryPtr* arytype = TypeOopPtr::make_from_klass(array_klass)->isa_aryptr();
 237             ary = _gvn.transform(new CheckCastPPNode(control(), ary, arytype));
 238             adr = array_element_address(ary, idx, T_OBJECT, arytype->size(), control());
 239             val->as_ValueType()->store_flattened(this, ary, adr);
 240             ideal.sync_kit(this);
 241           } else {
 242             if (TypePtr::NULL_PTR->higher_equal(val_t)) {
 243               sync_kit(ideal);






 244               inc_sp(3);
 245               val = filter_null(val);
 246               dec_sp(3);
 247               ideal.sync_kit(this);
 248             }
 249 
 250             if (!ideal.ctrl()->is_top()) {
 251               ideal.make_leaf_call(OptoRuntime::store_unknown_value_Type(),
 252                                    CAST_FROM_FN_PTR(address, OptoRuntime::store_unknown_value),
 253                                    "store_unknown_value",
 254                                    val, ary, idx);
 255             }
 256           }
 257         } ideal.end_if();
 258         sync_kit(ideal);
 259         return;
 260       } else {
 261         if (!val->is_ValueType() && TypePtr::NULL_PTR->higher_equal(val_t)) {
 262           gen_value_type_array_guard(ary, val, 3);
 263         }
 264       }
 265     }
 266   }


< prev index next >