< prev index next >

src/hotspot/share/opto/valuetypenode.cpp

Print this page




 298         }
 299       }
 300 
 301       if (field_is_flattenable(i)) {
 302         // Non-flattened but flattenable value type
 303         if (ft->as_value_klass()->is_scalarizable()) {
 304           parm = ValueTypeNode::make_from_oop(kit, parm, ft->as_value_klass());
 305         } else {
 306           parm = kit->null2default(parm, ft->as_value_klass());
 307         }
 308       }
 309 
 310       set_field_value(i, parm);
 311       // Record all these guys for later GVN.
 312       gvn.record_for_igvn(parm);
 313     }
 314   }
 315   base_input += vk->value_arg_slots();
 316 }
 317 
 318 const TypePtr* ValueTypeBaseNode::field_adr_type(Node* base, int offset, ciInstanceKlass* holder, PhaseGVN& gvn) const {
 319   const TypeAryPtr* ary_type = gvn.type(base)->isa_aryptr();
 320   const TypePtr* adr_type = NULL;
 321   bool is_array = ary_type != NULL;
 322   if (is_array) {


 323     // In the case of a flattened value type array, each field has its own slice
 324     adr_type = ary_type->with_field_offset(offset)->add_offset(Type::OffsetBot);
 325   } else {
 326     ciField* field = holder->get_field_by_offset(offset, false);
 327     assert(field != NULL, "field not found");
 328     adr_type = gvn.C->alias_type(field)->adr_type();
 329   }
 330   return adr_type;
 331 }
 332 
 333 void ValueTypeBaseNode::load(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
 334   // Initialize the value type by loading its field values from
 335   // memory and adding the values as input edges to the node.
 336   for (uint i = 0; i < field_count(); ++i) {
 337     int offset = holder_offset + field_offset(i);
 338     Node* value = NULL;
 339     ciType* ft = field_type(i);
 340     if (field_is_flattened(i)) {
 341       // Recursively load the flattened value type field
 342       value = ValueTypeNode::make_from_flattened(kit, ft->as_value_klass(), base, ptr, holder, offset);
 343     } else {
 344       const TypeOopPtr* oop_ptr = kit->gvn().type(base)->isa_oopptr();
 345       bool is_array = (oop_ptr->isa_aryptr() != NULL);
 346       if (base->is_Con() && !is_array) {
 347         // If the oop to the value type is constant (static final field), we can
 348         // also treat the fields as constants because the value type is immutable.
 349         ciObject* constant_oop = oop_ptr->const_oop();
 350         ciField* field = holder->get_field_by_offset(offset, false);
 351         assert(field != NULL, "field not found");
 352         ciConstant constant = constant_oop->as_instance()->field_value(field);
 353         const Type* con_type = Type::make_from_constant(constant, /*require_const=*/ true);
 354         assert(con_type != NULL, "type not found");
 355         value = kit->gvn().transform(kit->makecon(con_type));
 356       } else {
 357         // Load field value from memory
 358         const TypePtr* adr_type = field_adr_type(base, offset, holder, kit->gvn());
 359         Node* adr = kit->basic_plus_adr(base, ptr, offset);
 360         BasicType bt = type2field[ft->basic_type()];
 361         assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
 362         const Type* val_type = Type::get_const_type(ft);
 363         DecoratorSet decorators = IN_HEAP | MO_UNORDERED;
 364         if (is_array) {
 365           decorators |= IS_ARRAY;
 366         }
 367         value = kit->access_load_at(base, adr, adr_type, val_type, bt, decorators);
 368       }
 369       if (field_is_flattenable(i)) {
 370         // Loading a non-flattened but flattenable value type from memory
 371         if (ft->as_value_klass()->is_scalarizable()) {
 372           value = ValueTypeNode::make_from_oop(kit, value, ft->as_value_klass());
 373         } else {
 374           value = kit->null2default(value, ft->as_value_klass());
 375         }
 376       }
 377     }
 378     set_field_value(i, value);
 379   }
 380 }
 381 
 382 void ValueTypeBaseNode::store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) const {
 383   // The value type is embedded into the object without an oop header. Subtract the
 384   // offset of the first field to account for the missing header when storing the values.
 385   if (holder == NULL) {
 386     holder = value_klass();
 387   }
 388   holder_offset -= value_klass()->first_field_offset();
 389   store(kit, base, ptr, holder, holder_offset);
 390 }
 391 
 392 void ValueTypeBaseNode::store(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset, bool deoptimize_on_exception) const {
 393   // Write field values to memory
 394   for (uint i = 0; i < field_count(); ++i) {
 395     int offset = holder_offset + field_offset(i);
 396     Node* value = field_value(i);
 397     ciType* ft = field_type(i);
 398     if (field_is_flattened(i)) {
 399       // Recursively store the flattened value type field
 400       if (!value->is_ValueType()) {
 401         assert(!kit->gvn().type(value)->maybe_null(), "should never be null");
 402         value = ValueTypeNode::make_from_oop(kit, value, ft->as_value_klass());
 403       }
 404       value->as_ValueType()->store_flattened(kit, base, ptr, holder, offset);
 405     } else {
 406       // Store field value to memory
 407       const TypePtr* adr_type = field_adr_type(base, offset, holder, kit->gvn());
 408       Node* adr = kit->basic_plus_adr(base, ptr, offset);
 409       BasicType bt = type2field[ft->basic_type()];
 410       assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
 411       const Type* val_type = Type::get_const_type(ft);
 412       const TypeAryPtr* ary_type = kit->gvn().type(base)->isa_aryptr();
 413       DecoratorSet decorators = IN_HEAP | MO_UNORDERED;
 414       if (ary_type != NULL) {
 415         decorators |= IS_ARRAY;
 416       }
 417       kit->access_store_at(base, adr, adr_type, value, val_type, bt, decorators, deoptimize_on_exception);
 418     }
 419   }
 420 }
 421 
 422 ValueTypeBaseNode* ValueTypeBaseNode::allocate(GraphKit* kit, bool deoptimize_on_exception) {
 423   // Check if value type is already allocated
 424   Node* null_ctl = kit->top();
 425   Node* not_null_oop = kit->null_check_oop(get_oop(), &null_ctl);
 426   if (null_ctl->is_top()) {
 427     // Value type is allocated
 428     return this;
 429   }
 430   assert(!is_allocated(&kit->gvn()), "should not be allocated");
 431   RegionNode* region = new RegionNode(3);
 432 
 433   // Oop is non-NULL, use it


 586       region->init_req(1, kit->control());
 587       region->init_req(2, null_ctl);
 588 
 589       vt = vt->clone_with_phis(&gvn, region)->as_ValueType();
 590       vt->merge_with(&gvn, def, 2, true);
 591       kit->set_control(gvn.transform(region));
 592     }
 593   } else {
 594     // Oop can never be null
 595     Node* init_ctl = kit->control();
 596     vt->load(kit, oop, oop, vk, /* holder_offset */ 0);
 597     assert(init_ctl != kit->control() || oop->is_Con() || oop->is_CheckCastPP() || oop->Opcode() == Op_ValueTypePtr ||
 598            vt->is_loaded(&gvn) == oop, "value type should be loaded");
 599   }
 600 
 601   assert(vt->is_allocated(&gvn), "value type should be allocated");
 602   return gvn.transform(vt)->as_ValueType();
 603 }
 604 
 605 // GraphKit wrapper for the 'make_from_flattened' method
 606 ValueTypeNode* ValueTypeNode::make_from_flattened(GraphKit* kit, ciValueKlass* vk, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
 607   // Create and initialize a ValueTypeNode by loading all field values from
 608   // a flattened value type field at 'holder_offset' or from a value type array.
 609   ValueTypeNode* vt = make_uninitialized(kit->gvn(), vk);
 610   // The value type is flattened into the object without an oop header. Subtract the
 611   // offset of the first field to account for the missing header when loading the values.
 612   holder_offset -= vk->first_field_offset();
 613   vt->load(kit, obj, ptr, holder, holder_offset);
 614   assert(vt->is_loaded(&kit->gvn()) != obj, "holder oop should not be used as flattened value type oop");
 615   return kit->gvn().transform(vt)->as_ValueType();
 616 }
 617 
 618 ValueTypeNode* ValueTypeNode::make_from_multi(GraphKit* kit, MultiNode* multi, ciValueKlass* vk, uint& base_input, bool in) {
 619   ValueTypeNode* vt = ValueTypeNode::make_uninitialized(kit->gvn(), vk);
 620   vt->initialize(kit, multi, vk, 0, base_input, in);
 621   return kit->gvn().transform(vt)->as_ValueType();































 622 }
 623 
 624 Node* ValueTypeNode::is_loaded(PhaseGVN* phase, ciValueKlass* vk, Node* base, int holder_offset) {
 625   if (vk == NULL) {
 626     vk = value_klass();
 627   }
 628   if (field_count() == 0) {
 629     assert(is_allocated(phase), "must be allocated");
 630     return get_oop();
 631   }
 632   for (uint i = 0; i < field_count(); ++i) {
 633     int offset = holder_offset + field_offset(i);
 634     Node* value = field_value(i);
 635     if (value->is_ValueType()) {
 636       ValueTypeNode* vt = value->as_ValueType();
 637       if (field_is_flattened(i)) {
 638         // Check value type field load recursively
 639         base = vt->is_loaded(phase, vk, base, offset - vt->value_klass()->first_field_offset());
 640         if (base == NULL) {
 641           return NULL;




 298         }
 299       }
 300 
 301       if (field_is_flattenable(i)) {
 302         // Non-flattened but flattenable value type
 303         if (ft->as_value_klass()->is_scalarizable()) {
 304           parm = ValueTypeNode::make_from_oop(kit, parm, ft->as_value_klass());
 305         } else {
 306           parm = kit->null2default(parm, ft->as_value_klass());
 307         }
 308       }
 309 
 310       set_field_value(i, parm);
 311       // Record all these guys for later GVN.
 312       gvn.record_for_igvn(parm);
 313     }
 314   }
 315   base_input += vk->value_arg_slots();
 316 }
 317 
 318 const TypePtr* ValueTypeBaseNode::field_adr_type(Node* base, int offset, ciInstanceKlass* holder, DecoratorSet decorators, PhaseGVN& gvn) const {
 319   const TypeAryPtr* ary_type = gvn.type(base)->isa_aryptr();
 320   const TypePtr* adr_type = NULL;
 321   bool is_array = ary_type != NULL;
 322   if ((decorators & C2_MISMATCHED) != 0) {
 323     adr_type = TypeRawPtr::BOTTOM;
 324   } else if (is_array) {
 325     // In the case of a flattened value type array, each field has its own slice
 326     adr_type = ary_type->with_field_offset(offset)->add_offset(Type::OffsetBot);
 327   } else {
 328     ciField* field = holder->get_field_by_offset(offset, false);
 329     assert(field != NULL, "field not found");
 330     adr_type = gvn.C->alias_type(field)->adr_type();
 331   }
 332   return adr_type;
 333 }
 334 
 335 void ValueTypeBaseNode::load(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset, DecoratorSet decorators) {
 336   // Initialize the value type by loading its field values from
 337   // memory and adding the values as input edges to the node.
 338   for (uint i = 0; i < field_count(); ++i) {
 339     int offset = holder_offset + field_offset(i);
 340     Node* value = NULL;
 341     ciType* ft = field_type(i);
 342     if (field_is_flattened(i)) {
 343       // Recursively load the flattened value type field
 344       value = ValueTypeNode::make_from_flattened(kit, ft->as_value_klass(), base, ptr, holder, offset, decorators);
 345     } else {
 346       const TypeOopPtr* oop_ptr = kit->gvn().type(base)->isa_oopptr();
 347       bool is_array = (oop_ptr->isa_aryptr() != NULL);
 348       if (base->is_Con() && !is_array) {
 349         // If the oop to the value type is constant (static final field), we can
 350         // also treat the fields as constants because the value type is immutable.
 351         ciObject* constant_oop = oop_ptr->const_oop();
 352         ciField* field = holder->get_field_by_offset(offset, false);
 353         assert(field != NULL, "field not found");
 354         ciConstant constant = constant_oop->as_instance()->field_value(field);
 355         const Type* con_type = Type::make_from_constant(constant, /*require_const=*/ true);
 356         assert(con_type != NULL, "type not found");
 357         value = kit->gvn().transform(kit->makecon(con_type));
 358       } else {
 359         // Load field value from memory
 360         const TypePtr* adr_type = field_adr_type(base, offset, holder, decorators, kit->gvn());
 361         Node* adr = kit->basic_plus_adr(base, ptr, offset);
 362         BasicType bt = type2field[ft->basic_type()];
 363         assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
 364         const Type* val_type = Type::get_const_type(ft);

 365         if (is_array) {
 366           decorators |= IS_ARRAY;
 367         }
 368         value = kit->access_load_at(base, adr, adr_type, val_type, bt, decorators);
 369       }
 370       if (field_is_flattenable(i)) {
 371         // Loading a non-flattened but flattenable value type from memory
 372         if (ft->as_value_klass()->is_scalarizable()) {
 373           value = ValueTypeNode::make_from_oop(kit, value, ft->as_value_klass());
 374         } else {
 375           value = kit->null2default(value, ft->as_value_klass());
 376         }
 377       }
 378     }
 379     set_field_value(i, value);
 380   }
 381 }
 382 
 383 void ValueTypeBaseNode::store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset, DecoratorSet decorators) const {
 384   // The value type is embedded into the object without an oop header. Subtract the
 385   // offset of the first field to account for the missing header when storing the values.
 386   if (holder == NULL) {
 387     holder = value_klass();
 388   }
 389   holder_offset -= value_klass()->first_field_offset();
 390   store(kit, base, ptr, holder, holder_offset, false, decorators);
 391 }
 392 
 393 void ValueTypeBaseNode::store(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset, bool deoptimize_on_exception, DecoratorSet decorators) const {
 394   // Write field values to memory
 395   for (uint i = 0; i < field_count(); ++i) {
 396     int offset = holder_offset + field_offset(i);
 397     Node* value = field_value(i);
 398     ciType* ft = field_type(i);
 399     if (field_is_flattened(i)) {
 400       // Recursively store the flattened value type field
 401       if (!value->is_ValueType()) {
 402         assert(!kit->gvn().type(value)->maybe_null(), "should never be null");
 403         value = ValueTypeNode::make_from_oop(kit, value, ft->as_value_klass());
 404       }
 405       value->as_ValueType()->store_flattened(kit, base, ptr, holder, offset, decorators);
 406     } else {
 407       // Store field value to memory
 408       const TypePtr* adr_type = field_adr_type(base, offset, holder, decorators, kit->gvn());
 409       Node* adr = kit->basic_plus_adr(base, ptr, offset);
 410       BasicType bt = type2field[ft->basic_type()];
 411       assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
 412       const Type* val_type = Type::get_const_type(ft);
 413       const TypeAryPtr* ary_type = kit->gvn().type(base)->isa_aryptr();

 414       if (ary_type != NULL) {
 415         decorators |= IS_ARRAY;
 416       }
 417       kit->access_store_at(base, adr, adr_type, value, val_type, bt, decorators, deoptimize_on_exception);
 418     }
 419   }
 420 }
 421 
 422 ValueTypeBaseNode* ValueTypeBaseNode::allocate(GraphKit* kit, bool deoptimize_on_exception) {
 423   // Check if value type is already allocated
 424   Node* null_ctl = kit->top();
 425   Node* not_null_oop = kit->null_check_oop(get_oop(), &null_ctl);
 426   if (null_ctl->is_top()) {
 427     // Value type is allocated
 428     return this;
 429   }
 430   assert(!is_allocated(&kit->gvn()), "should not be allocated");
 431   RegionNode* region = new RegionNode(3);
 432 
 433   // Oop is non-NULL, use it


 586       region->init_req(1, kit->control());
 587       region->init_req(2, null_ctl);
 588 
 589       vt = vt->clone_with_phis(&gvn, region)->as_ValueType();
 590       vt->merge_with(&gvn, def, 2, true);
 591       kit->set_control(gvn.transform(region));
 592     }
 593   } else {
 594     // Oop can never be null
 595     Node* init_ctl = kit->control();
 596     vt->load(kit, oop, oop, vk, /* holder_offset */ 0);
 597     assert(init_ctl != kit->control() || oop->is_Con() || oop->is_CheckCastPP() || oop->Opcode() == Op_ValueTypePtr ||
 598            vt->is_loaded(&gvn) == oop, "value type should be loaded");
 599   }
 600 
 601   assert(vt->is_allocated(&gvn), "value type should be allocated");
 602   return gvn.transform(vt)->as_ValueType();
 603 }
 604 
 605 // GraphKit wrapper for the 'make_from_flattened' method
 606 ValueTypeNode* ValueTypeNode::make_from_flattened(GraphKit* kit, ciValueKlass* vk, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset, DecoratorSet decorators) {
 607   // Create and initialize a ValueTypeNode by loading all field values from
 608   // a flattened value type field at 'holder_offset' or from a value type array.
 609   ValueTypeNode* vt = make_uninitialized(kit->gvn(), vk);
 610   // The value type is flattened into the object without an oop header. Subtract the
 611   // offset of the first field to account for the missing header when loading the values.
 612   holder_offset -= vk->first_field_offset();
 613   vt->load(kit, obj, ptr, holder, holder_offset, decorators);
 614   assert(vt->is_loaded(&kit->gvn()) != obj, "holder oop should not be used as flattened value type oop");
 615   return kit->gvn().transform(vt)->as_ValueType();
 616 }
 617 
 618 ValueTypeNode* ValueTypeNode::make_from_multi(GraphKit* kit, MultiNode* multi, ciValueKlass* vk, uint& base_input, bool in) {
 619   ValueTypeNode* vt = ValueTypeNode::make_uninitialized(kit->gvn(), vk);
 620   vt->initialize(kit, multi, vk, 0, base_input, in);
 621   return kit->gvn().transform(vt)->as_ValueType();
 622 }
 623 
 624 ValueTypeNode* ValueTypeNode::make_larval(GraphKit* kit, bool allocate) const {
 625   ciValueKlass* vk = value_klass();
 626   ValueTypeNode* res = clone()->as_ValueType();
 627   if (allocate) {
 628     Node* klass_node = kit->makecon(TypeKlassPtr::make(vk));
 629     Node* alloc_oop  = kit->new_instance(klass_node, NULL, NULL, false);
 630     AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_oop, &kit->gvn());
 631     alloc->_larval = true;
 632 
 633     store(kit, alloc_oop, alloc_oop, vk, 0, false);
 634     res->set_oop(alloc_oop);
 635   }
 636   res->set_type(TypeValueType::make(vk, true));
 637   res = kit->gvn().transform(res)->as_ValueType();
 638   return res;
 639 }
 640 
 641 ValueTypeNode* ValueTypeNode::finish_larval(GraphKit* kit) const {
 642   Node* obj = get_oop();
 643   Node* mark_addr = kit->basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
 644   Node* mark = kit->make_load(NULL, mark_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered);
 645   mark = kit->gvn().transform(new AndXNode(mark, kit->MakeConX(~markOopDesc::larval_mask_in_place)));
 646   kit->store_to_memory(kit->control(), mark_addr, mark, TypeX_X->basic_type(), kit->gvn().type(mark_addr)->is_ptr(), MemNode::unordered);
 647 
 648   ciValueKlass* vk = value_klass();
 649   ValueTypeNode* res = clone()->as_ValueType();
 650   res->set_type(TypeValueType::make(vk, false));
 651   res = kit->gvn().transform(res)->as_ValueType();
 652   return res;
 653 }
 654 
 655 Node* ValueTypeNode::is_loaded(PhaseGVN* phase, ciValueKlass* vk, Node* base, int holder_offset) {
 656   if (vk == NULL) {
 657     vk = value_klass();
 658   }
 659   if (field_count() == 0) {
 660     assert(is_allocated(phase), "must be allocated");
 661     return get_oop();
 662   }
 663   for (uint i = 0; i < field_count(); ++i) {
 664     int offset = holder_offset + field_offset(i);
 665     Node* value = field_value(i);
 666     if (value->is_ValueType()) {
 667       ValueTypeNode* vt = value->as_ValueType();
 668       if (field_is_flattened(i)) {
 669         // Check value type field load recursively
 670         base = vt->is_loaded(phase, vk, base, offset - vt->value_klass()->first_field_offset());
 671         if (base == NULL) {
 672           return NULL;


< prev index next >