118 } 119 } 120 set_field_value(i, gvn.transform(value)); 121 } 122 } 123 124 Node* ValueTypeNode::is_loaded(PhaseGVN* phase, const TypeValueType* t, Node* base, int holder_offset) { 125 if (field_count() == 0) { 126 assert(t->value_klass() == phase->C->env()->___Value_klass(), "unexpected value type klass"); 127 assert(is_allocated(phase), "must be allocated"); 128 return get_oop(); 129 } 130 for (uint i = 0; i < field_count(); ++i) { 131 int offset = holder_offset + field_offset(i); 132 Node* value = field_value(i); 133 if (value->isa_DecodeN()) { 134 // Skip DecodeN 135 value = value->in(1); 136 } 137 if (value->isa_Load()) { 138 AddPNode* load_addr = value->in(MemNode::Address)->as_AddP(); 139 if (base == NULL) { 140 // Set base and check if pointer type matches 141 base = load_addr->base_node(); 142 const TypeValueTypePtr* vtptr = phase->type(base)->isa_valuetypeptr(); 143 if (vtptr == NULL || !vtptr->value_type()->eq(t)) { 144 return NULL; 145 } 146 } 147 // Check if base and offset of field load matches 148 Node* off = load_addr->in(AddPNode::Offset); 149 int load_offset = LP64_ONLY(off->get_long()) NOT_LP64(off->get_int()); 150 if (base != load_addr->base_node() || offset != load_offset) { 151 return NULL; 152 } 153 } else if (value->isa_ValueType()) { 154 // Check value type field load recursively 155 ValueTypeNode* vt = value->as_ValueType(); 156 base = vt->is_loaded(phase, t, base, offset - vt->value_klass()->first_field_offset()); 157 if (base == NULL) { 158 return NULL; 159 } 160 } else { 161 return NULL; 162 } 163 } 164 return base; 165 } 166 167 void ValueTypeNode::store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) const { 168 // The value type is embedded into the object without an oop header. Subtract the 169 // offset of the first field to account for the missing header when storing the values. 170 holder_offset -= value_klass()->first_field_offset(); 171 store(kit, base, ptr, holder, holder_offset); | 118 } 119 } 120 set_field_value(i, gvn.transform(value)); 121 } 122 } 123 124 Node* ValueTypeNode::is_loaded(PhaseGVN* phase, const TypeValueType* t, Node* base, int holder_offset) { 125 if (field_count() == 0) { 126 assert(t->value_klass() == phase->C->env()->___Value_klass(), "unexpected value type klass"); 127 assert(is_allocated(phase), "must be allocated"); 128 return get_oop(); 129 } 130 for (uint i = 0; i < field_count(); ++i) { 131 int offset = holder_offset + field_offset(i); 132 Node* value = field_value(i); 133 if (value->isa_DecodeN()) { 134 // Skip DecodeN 135 value = value->in(1); 136 } 137 if (value->isa_Load()) { 138 // Check if base and offset of field load matches value type layout 139 intptr_t loffset = 0; 140 Node* lbase = AddPNode::Ideal_base_and_offset(value->in(MemNode::Address), phase, loffset); 141 if (lbase == NULL || (lbase != base && base != NULL) || loffset != offset) { 142 return NULL; 143 } else if (base == NULL) { 144 // Set base and check if pointer type matches 145 base = lbase; 146 const TypeValueTypePtr* vtptr = phase->type(base)->isa_valuetypeptr(); 147 if (vtptr == NULL || !vtptr->value_type()->eq(t)) { 148 return NULL; 149 } 150 } 151 } else if (value->isa_ValueType()) { 152 // Check value type field load recursively 153 ValueTypeNode* vt = value->as_ValueType(); 154 base = vt->is_loaded(phase, t, base, offset - vt->value_klass()->first_field_offset()); 155 if (base == NULL) { 156 return NULL; 157 } 158 } else { 159 return NULL; 160 } 161 } 162 return base; 163 } 164 165 void ValueTypeNode::store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) const { 166 // The value type is embedded into the object without an oop header. Subtract the 167 // offset of the first field to account for the missing header when storing the values. 168 holder_offset -= value_klass()->first_field_offset(); 169 store(kit, base, ptr, holder, holder_offset); |