< prev index next >

src/hotspot/share/opto/valuetypenode.cpp

Print this page




 331         assert(field != NULL, "field not found");
 332         ciConstant constant = constant_oop->as_instance()->field_value(field);
 333         const Type* con_type = Type::make_from_constant(constant, /*require_const=*/ true);
 334         assert(con_type != NULL, "type not found");
 335         value = kit->gvn().transform(kit->makecon(con_type));
 336       } else {
 337         // Load field value from memory
 338         const TypePtr* adr_type = field_adr_type(base, offset, holder, kit->gvn());
 339         Node* adr = kit->basic_plus_adr(base, ptr, offset);
 340         BasicType bt = type2field[ft->basic_type()];
 341         assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
 342         const Type* val_type = Type::get_const_type(ft);
 343         DecoratorSet decorators = IN_HEAP | MO_UNORDERED;
 344         if (is_array) {
 345           decorators |= IS_ARRAY;
 346         }
 347         value = kit->access_load_at(base, adr, adr_type, val_type, bt, decorators);
 348       }
 349       if (ft->is_valuetype()) {
 350         // Loading a non-flattened value type from memory
 351         value = ValueTypeNode::make_from_oop(kit, value, ft->as_value_klass(), /* buffer_check */ false, /* null2default */ field_is_flattenable(i), trap_bci);
 352       }
 353     }
 354     set_field_value(i, value);
 355   }
 356 }
 357 
 358 void ValueTypeBaseNode::store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) const {
 359   // The value type is embedded into the object without an oop header. Subtract the
 360   // offset of the first field to account for the missing header when storing the values.
 361   if (holder == NULL) {
 362     holder = value_klass();
 363   }
 364   holder_offset -= value_klass()->first_field_offset();
 365   store(kit, base, ptr, holder, holder_offset);
 366 }
 367 
 368 void ValueTypeBaseNode::store(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset, bool deoptimize_on_exception) const {
 369   // Write field values to memory
 370   for (uint i = 0; i < field_count(); ++i) {
 371     int offset = holder_offset + field_offset(i);


 506     }
 507     vt->set_field_value(i, value);
 508   }
 509   vt = gvn.transform(vt)->as_ValueType();
 510   assert(vt->is_default(gvn), "must be the default value type");
 511   return vt;
 512 }
 513 
 514 
 515 bool ValueTypeNode::is_default(PhaseGVN& gvn) const {
 516   for (uint i = 0; i < field_count(); ++i) {
 517     Node* value = field_value(i);
 518     if (!gvn.type(value)->is_zero_type() &&
 519         !(value->is_ValueType() && value->as_ValueType()->is_default(gvn))) {
 520       return false;
 521     }
 522   }
 523   return true;
 524 }
 525 
 526 ValueTypeNode* ValueTypeNode::make_from_oop(GraphKit* kit, Node* oop, ciValueKlass* vk, bool buffer_check, bool null2default, int trap_bci) {
 527   PhaseGVN& gvn = kit->gvn();
 528   const TypePtr* oop_type = gvn.type(oop)->is_ptr();
 529   bool null_check = oop_type->maybe_null();
 530 
 531   // Create and initialize a ValueTypeNode by loading all field
 532   // values from a heap-allocated version and also save the oop.
 533   ValueTypeNode* vt = new ValueTypeNode(TypeValueType::make(vk), oop);
 534 
 535   if (null_check) {
 536     // Add a null check because the oop may be null
 537     Node* null_ctl = kit->top();
 538     Node* not_null_oop = kit->null_check_oop(oop, &null_ctl);
 539     if (kit->stopped()) {
 540       // Constant null
 541       if (null2default) {
 542         kit->set_control(null_ctl);
 543         return make_default(gvn, vk);
 544       } else {
 545         int bci = kit->bci();
 546         if (trap_bci != -1) {


 572       PreserveJVMState pjvms(kit);
 573       kit->set_control(null_ctl);
 574       int bci = kit->bci();
 575       if (trap_bci != -1) {
 576         // Put trap at different bytecode
 577         kit->push(kit->null());
 578         kit->set_bci(trap_bci);
 579       }
 580       kit->replace_in_map(oop, kit->null());
 581       kit->uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
 582       kit->set_bci(bci);
 583     }
 584   } else {
 585     // Oop can never be null
 586     Node* init_ctl = kit->control();
 587     vt->load(kit, oop, oop, vk, /* holder_offset */ 0, trap_bci);
 588     assert(init_ctl != kit->control() || oop->is_Con() || oop->is_CheckCastPP() || oop->Opcode() == Op_ValueTypePtr ||
 589            vt->is_loaded(&gvn) == oop, "value type should be loaded");
 590   }
 591 
 592   if (buffer_check && vk->is_bufferable()) {
 593     // Check if oop is in heap bounds or if it points into the vtBuffer:
 594     // base <= oop < (base + size)  <=>  (oop - base) <U size
 595     // Discard buffer oops to avoid storing them into fields or arrays.
 596     assert(!gvn.type(oop)->isa_narrowoop(), "should not be a narrow oop");
 597     Node* heap_base = gvn.MakeConX((intptr_t)Universe::heap()->base());
 598     Node* heap_size = gvn.MakeConX(Universe::heap()->max_capacity());
 599     Node* sub = gvn.transform(new SubXNode(gvn.transform(new CastP2XNode(NULL, oop)), heap_base));
 600     Node* chk = gvn.transform(new CmpUXNode(sub, heap_size));
 601     Node* tst = gvn.transform(new BoolNode(chk, BoolTest::lt));
 602     IfNode* iff = gvn.transform(new IfNode(kit->control(), tst, PROB_MAX, COUNT_UNKNOWN))->as_If();
 603 
 604     Node* region = new RegionNode(3);
 605     region->init_req(1, gvn.transform(new IfTrueNode(iff)));
 606     region->init_req(2, gvn.transform(new IfFalseNode(iff)));
 607     Node* new_oop = new PhiNode(region, vt->value_ptr());
 608     new_oop->init_req(1, oop);
 609     new_oop->init_req(2, gvn.zerocon(T_VALUETYPE));
 610 
 611     gvn.hash_delete(vt);
 612     vt->set_oop(gvn.transform(new_oop));
 613     kit->set_control(gvn.transform(region));
 614   }
 615 
 616   assert(vt->is_allocated(&gvn), "value type should be allocated");
 617   return gvn.transform(vt)->as_ValueType();
 618 }
 619 
 620 // GraphKit wrapper for the 'make_from_flattened' method
 621 ValueTypeNode* ValueTypeNode::make_from_flattened(GraphKit* kit, ciValueKlass* vk, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
 622   // Create and initialize a ValueTypeNode by loading all field values from
 623   // a flattened value type field at 'holder_offset' or from a value type array.
 624   ValueTypeNode* vt = make_uninitialized(kit->gvn(), vk);
 625   // The value type is flattened into the object without an oop header. Subtract the
 626   // offset of the first field to account for the missing header when loading the values.
 627   holder_offset -= vk->first_field_offset();
 628   vt->load(kit, obj, ptr, holder, holder_offset);
 629   assert(vt->is_loaded(&kit->gvn()) != obj, "holder oop should not be used as flattened value type oop");
 630   return kit->gvn().transform(vt)->as_ValueType();
 631 }
 632 
 633 ValueTypeNode* ValueTypeNode::make_from_multi(GraphKit* kit, MultiNode* multi, ciValueKlass* vk, int base_input, bool in) {
 634   ValueTypeNode* vt = ValueTypeNode::make_uninitialized(kit->gvn(), vk);
 635   vt->initialize(kit, multi, vk, 0, base_input, in);


 752       n->init_req(base_input + j + extra, arg);
 753       edges++;
 754       BasicType bt = field_type(i)->basic_type();
 755       if (bt == T_LONG || bt == T_DOUBLE) {
 756         n->init_req(base_input + j + extra + 1, kit.top());
 757         edges++;
 758       }
 759     }
 760   }
 761   return edges;
 762 }
 763 
 764 Node* ValueTypeNode::Ideal(PhaseGVN* phase, bool can_reshape) {
 765   Node* oop = get_oop();
 766   if (is_default(*phase) && (!oop->is_Con() || phase->type(oop)->is_zero_type())) {
 767     // Use the pre-allocated oop for default value types
 768     set_oop(default_oop(*phase, value_klass()));
 769     return this;
 770   }
 771 
 772   if (!is_allocated(phase) && !value_klass()->is_bufferable()) {
 773     // Save base oop if fields are loaded from memory and the value
 774     // type is not buffered (in this case we should not use the oop).
 775     Node* base = is_loaded(phase);
 776     if (base != NULL) {
 777       set_oop(base);
 778       assert(is_allocated(phase), "should now be allocated");
 779       return this;
 780     }
 781   }
 782 
 783   if (can_reshape) {
 784     PhaseIterGVN* igvn = phase->is_IterGVN();
 785 
 786     if (is_default(*phase)) {
 787       // Search for users of the default value type
 788       for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
 789         Node* user = fast_out(i);
 790         AllocateNode* alloc = user->isa_Allocate();
 791         if (alloc != NULL && alloc->result_cast() != NULL && alloc->in(AllocateNode::ValueNode) == this) {
 792           // Found an allocation of the default value type.




 331         assert(field != NULL, "field not found");
 332         ciConstant constant = constant_oop->as_instance()->field_value(field);
 333         const Type* con_type = Type::make_from_constant(constant, /*require_const=*/ true);
 334         assert(con_type != NULL, "type not found");
 335         value = kit->gvn().transform(kit->makecon(con_type));
 336       } else {
 337         // Load field value from memory
 338         const TypePtr* adr_type = field_adr_type(base, offset, holder, kit->gvn());
 339         Node* adr = kit->basic_plus_adr(base, ptr, offset);
 340         BasicType bt = type2field[ft->basic_type()];
 341         assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
 342         const Type* val_type = Type::get_const_type(ft);
 343         DecoratorSet decorators = IN_HEAP | MO_UNORDERED;
 344         if (is_array) {
 345           decorators |= IS_ARRAY;
 346         }
 347         value = kit->access_load_at(base, adr, adr_type, val_type, bt, decorators);
 348       }
 349       if (ft->is_valuetype()) {
 350         // Loading a non-flattened value type from memory
 351         value = ValueTypeNode::make_from_oop(kit, value, ft->as_value_klass(), /* null2default */ field_is_flattenable(i), trap_bci);
 352       }
 353     }
 354     set_field_value(i, value);
 355   }
 356 }
 357 
 358 void ValueTypeBaseNode::store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) const {
 359   // The value type is embedded into the object without an oop header. Subtract the
 360   // offset of the first field to account for the missing header when storing the values.
 361   if (holder == NULL) {
 362     holder = value_klass();
 363   }
 364   holder_offset -= value_klass()->first_field_offset();
 365   store(kit, base, ptr, holder, holder_offset);
 366 }
 367 
 368 void ValueTypeBaseNode::store(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset, bool deoptimize_on_exception) const {
 369   // Write field values to memory
 370   for (uint i = 0; i < field_count(); ++i) {
 371     int offset = holder_offset + field_offset(i);


 506     }
 507     vt->set_field_value(i, value);
 508   }
 509   vt = gvn.transform(vt)->as_ValueType();
 510   assert(vt->is_default(gvn), "must be the default value type");
 511   return vt;
 512 }
 513 
 514 
 515 bool ValueTypeNode::is_default(PhaseGVN& gvn) const {
 516   for (uint i = 0; i < field_count(); ++i) {
 517     Node* value = field_value(i);
 518     if (!gvn.type(value)->is_zero_type() &&
 519         !(value->is_ValueType() && value->as_ValueType()->is_default(gvn))) {
 520       return false;
 521     }
 522   }
 523   return true;
 524 }
 525 
 526 ValueTypeNode* ValueTypeNode::make_from_oop(GraphKit* kit, Node* oop, ciValueKlass* vk, bool null2default, int trap_bci) {
 527   PhaseGVN& gvn = kit->gvn();
 528   const TypePtr* oop_type = gvn.type(oop)->is_ptr();
 529   bool null_check = oop_type->maybe_null();
 530 
 531   // Create and initialize a ValueTypeNode by loading all field
 532   // values from a heap-allocated version and also save the oop.
 533   ValueTypeNode* vt = new ValueTypeNode(TypeValueType::make(vk), oop);
 534 
 535   if (null_check) {
 536     // Add a null check because the oop may be null
 537     Node* null_ctl = kit->top();
 538     Node* not_null_oop = kit->null_check_oop(oop, &null_ctl);
 539     if (kit->stopped()) {
 540       // Constant null
 541       if (null2default) {
 542         kit->set_control(null_ctl);
 543         return make_default(gvn, vk);
 544       } else {
 545         int bci = kit->bci();
 546         if (trap_bci != -1) {


 572       PreserveJVMState pjvms(kit);
 573       kit->set_control(null_ctl);
 574       int bci = kit->bci();
 575       if (trap_bci != -1) {
 576         // Put trap at different bytecode
 577         kit->push(kit->null());
 578         kit->set_bci(trap_bci);
 579       }
 580       kit->replace_in_map(oop, kit->null());
 581       kit->uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
 582       kit->set_bci(bci);
 583     }
 584   } else {
 585     // Oop can never be null
 586     Node* init_ctl = kit->control();
 587     vt->load(kit, oop, oop, vk, /* holder_offset */ 0, trap_bci);
 588     assert(init_ctl != kit->control() || oop->is_Con() || oop->is_CheckCastPP() || oop->Opcode() == Op_ValueTypePtr ||
 589            vt->is_loaded(&gvn) == oop, "value type should be loaded");
 590   }
 591 
























 592   assert(vt->is_allocated(&gvn), "value type should be allocated");
 593   return gvn.transform(vt)->as_ValueType();
 594 }
 595 
 596 // GraphKit wrapper for the 'make_from_flattened' method
 597 ValueTypeNode* ValueTypeNode::make_from_flattened(GraphKit* kit, ciValueKlass* vk, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
 598   // Create and initialize a ValueTypeNode by loading all field values from
 599   // a flattened value type field at 'holder_offset' or from a value type array.
 600   ValueTypeNode* vt = make_uninitialized(kit->gvn(), vk);
 601   // The value type is flattened into the object without an oop header. Subtract the
 602   // offset of the first field to account for the missing header when loading the values.
 603   holder_offset -= vk->first_field_offset();
 604   vt->load(kit, obj, ptr, holder, holder_offset);
 605   assert(vt->is_loaded(&kit->gvn()) != obj, "holder oop should not be used as flattened value type oop");
 606   return kit->gvn().transform(vt)->as_ValueType();
 607 }
 608 
 609 ValueTypeNode* ValueTypeNode::make_from_multi(GraphKit* kit, MultiNode* multi, ciValueKlass* vk, int base_input, bool in) {
 610   ValueTypeNode* vt = ValueTypeNode::make_uninitialized(kit->gvn(), vk);
 611   vt->initialize(kit, multi, vk, 0, base_input, in);


 728       n->init_req(base_input + j + extra, arg);
 729       edges++;
 730       BasicType bt = field_type(i)->basic_type();
 731       if (bt == T_LONG || bt == T_DOUBLE) {
 732         n->init_req(base_input + j + extra + 1, kit.top());
 733         edges++;
 734       }
 735     }
 736   }
 737   return edges;
 738 }
 739 
 740 Node* ValueTypeNode::Ideal(PhaseGVN* phase, bool can_reshape) {
 741   Node* oop = get_oop();
 742   if (is_default(*phase) && (!oop->is_Con() || phase->type(oop)->is_zero_type())) {
 743     // Use the pre-allocated oop for default value types
 744     set_oop(default_oop(*phase, value_klass()));
 745     return this;
 746   }
 747 
 748   if (!is_allocated(phase)) {
 749     // Save base oop if fields are loaded from memory and the value
 750     // type is not buffered (in this case we should not use the oop).
 751     Node* base = is_loaded(phase);
 752     if (base != NULL) {
 753       set_oop(base);
 754       assert(is_allocated(phase), "should now be allocated");
 755       return this;
 756     }
 757   }
 758 
 759   if (can_reshape) {
 760     PhaseIterGVN* igvn = phase->is_IterGVN();
 761 
 762     if (is_default(*phase)) {
 763       // Search for users of the default value type
 764       for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
 765         Node* user = fast_out(i);
 766         AllocateNode* alloc = user->isa_Allocate();
 767         if (alloc != NULL && alloc->result_cast() != NULL && alloc->in(AllocateNode::ValueNode) == this) {
 768           // Found an allocation of the default value type.


< prev index next >