< prev index next >

src/hotspot/share/opto/valuetypenode.cpp

Print this page

        

*** 469,478 **** --- 469,479 ---- return new ValueTypeNode(type, gvn.zerocon(T_VALUETYPE)); } Node* ValueTypeNode::load_default_oop(PhaseGVN& gvn, ciValueKlass* vk) { // Load the default oop from the java mirror of the given ValueKlass + assert(!vk->is__Value(), "__Value has no default oop"); const TypeInstPtr* tip = TypeInstPtr::make(vk->java_mirror()); Node* base = gvn.makecon(tip); Node* adr = gvn.transform(new AddPNode(base, base, gvn.MakeConX(vk->default_value_offset()))); const Type* rt = Type::get_const_type(vk)->join_speculative(TypePtr::NOTNULL); return gvn.transform(LoadNode::make(gvn, NULL, gvn.C->immutable_memory(), adr, tip, rt, T_VALUETYPE, MemNode::unordered));
*** 491,501 **** } else { value = gvn.zerocon(field_type->basic_type()); } vt->set_field_value(i, value); } ! return gvn.transform(vt)->as_ValueType(); } ValueTypeNode* ValueTypeNode::make_from_oop(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* oop, ciValueKlass* vk, bool null_check, bool buffer_check) { assert(!(null_check && buffer_check), "should not both require a null and a buffer check"); --- 492,519 ---- } else { value = gvn.zerocon(field_type->basic_type()); } vt->set_field_value(i, value); } ! vt = gvn.transform(vt)->as_ValueType(); ! assert(vt->is_default(gvn), "must be the default value type"); ! return vt; ! } ! ! ! bool ValueTypeNode::is_default(PhaseGVN& gvn) const { ! if (value_klass()->is__Value()) { ! return false; ! } ! for (uint i = 0; i < field_count(); ++i) { ! Node* value = field_value(i); ! if (!gvn.type(value)->is_zero_type() && ! !(value->is_ValueType() && value->as_ValueType()->is_default(gvn))) { ! return false; ! } ! } ! return true; } ValueTypeNode* ValueTypeNode::make_from_oop(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* oop, ciValueKlass* vk, bool null_check, bool buffer_check) { assert(!(null_check && buffer_check), "should not both require a null and a buffer check");
*** 722,731 **** --- 740,759 ---- } return edges; } Node* ValueTypeNode::Ideal(PhaseGVN* phase, bool can_reshape) { + Node* oop = get_oop(); + + if (is_default(*phase) && !oop->is_Load() && + !(oop->is_DecodeN() && oop->in(1)->is_Load())) { + // Use the pre-allocated oop for default value types + Node* oop = load_default_oop(*phase, value_klass()); + set_oop(oop); + return this; + } + if (!is_allocated(phase) && !value_klass()->is_bufferable()) { // Save base oop if fields are loaded from memory and the value // type is not buffered (in this case we should not use the oop). Node* base = is_loaded(phase); if (base != NULL) {
*** 735,744 **** --- 763,786 ---- } } if (can_reshape) { PhaseIterGVN* igvn = phase->is_IterGVN(); + + if (is_default(*phase)) { + // Search for allocations of the default value type + for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { + AllocateNode* alloc = fast_out(i)->isa_Allocate(); + if (alloc != NULL && alloc->result_cast() != NULL && alloc->in(AllocateNode::ValueNode) == this) { + // Replace allocation be pre-allocated oop + Node* res = alloc->result_cast(); + Node* oop = load_default_oop(*phase, value_klass()); + igvn->replace_node(res, oop); + } + } + } + if (is_allocated(igvn)) { // Value type is heap allocated, search for safepoint uses for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { Node* out = fast_out(i); if (out->is_SafePoint()) {
*** 758,767 **** --- 800,810 ---- assert(EliminateAllocations, "allocation elimination should be enabled"); // Search for allocations of this value type for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { AllocateNode* alloc = fast_out(i)->isa_Allocate(); if (alloc != NULL && alloc->result_cast() != NULL && alloc->in(AllocateNode::ValueNode) == this) { + assert(!is_default(*igvn), "default value type allocation"); Node* res_dom = NULL; if (is_allocated(igvn)) { // The value type is already allocated but still connected to an AllocateNode. // This can happen with late inlining when we first allocate a value type argument // but later decide to inline the call with the callee code also allocating.
< prev index next >