21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "ci/ciValueKlass.hpp"
27 #include "opto/addnode.hpp"
28 #include "opto/castnode.hpp"
29 #include "opto/graphKit.hpp"
30 #include "opto/rootnode.hpp"
31 #include "opto/valuetypenode.hpp"
32 #include "opto/phaseX.hpp"
33
34 // Clones the values type to handle control flow merges involving multiple value types.
35 // The inputs are replaced by PhiNodes to represent the merged values for the given region.
36 ValueTypeBaseNode* ValueTypeBaseNode::clone_with_phis(PhaseGVN* gvn, Node* region) {
37 assert(!has_phi_inputs(region), "already cloned with phis");
38 ValueTypeBaseNode* vt = clone()->as_ValueTypeBase();
39
40 // Create a PhiNode for merging the oop values
41 const TypeValueTypePtr* vtptr = value_type_ptr();
42 vtptr = vtptr->cast_to_ptr_type(TypePtr::BotPTR)->is_valuetypeptr();
43 PhiNode* oop = PhiNode::make(region, vt->get_oop(), vtptr);
44 gvn->set_type(oop, vtptr);
45 vt->set_oop(oop);
46
47 // Create a PhiNode each for merging the field values
48 for (uint i = 0; i < vt->field_count(); ++i) {
49 ciType* type = vt->field_type(i);
50 Node* value = vt->field_value(i);
51 if (type->is_valuetype()) {
52 // Handle flattened value type fields recursively
53 value = value->as_ValueType()->clone_with_phis(gvn, region);
54 } else {
55 const Type* phi_type = Type::get_const_type(type);
56 value = PhiNode::make(region, value, phi_type);
57 gvn->set_type(value, phi_type);
58 }
59 vt->set_field_value(i, value);
60 }
61 gvn->set_type(vt, vt->bottom_type());
62 return vt;
63 }
64
65 // Checks if the inputs of the ValueBaseTypeNode were replaced by PhiNodes
66 // for the given region (see ValueBaseTypeNode::clone_with_phis).
67 bool ValueTypeBaseNode::has_phi_inputs(Node* region) {
68 // Check oop input
69 bool result = get_oop()->is_Phi() && get_oop()->as_Phi()->region() == region;
70 #ifdef ASSERT
71 if (result) {
72 // Check all field value inputs for consistency
73 for (uint i = Oop; i < field_count(); ++i) {
74 Node* n = in(i);
75 if (n->is_ValueTypeBase()) {
141 return value;
142 }
143
144 void ValueTypeBaseNode::set_field_value(uint index, Node* value) {
145 assert(index < field_count(), "index out of bounds");
146 set_req(Values + index, value);
147 }
148
149 int ValueTypeBaseNode::field_offset(uint index) const {
150 assert(index < field_count(), "index out of bounds");
151 return value_klass()->declared_nonstatic_field_at(index)->offset();
152 }
153
154 ciType* ValueTypeBaseNode::field_type(uint index) const {
155 assert(index < field_count(), "index out of bounds");
156 return value_klass()->declared_nonstatic_field_at(index)->type();
157 }
158
159 bool ValueTypeBaseNode::field_is_flattened(uint index) const {
160 assert(index < field_count(), "index out of bounds");
161 return value_klass()->declared_nonstatic_field_at(index)->is_flattened();
162 }
163
164 int ValueTypeBaseNode::make_scalar_in_safepoint(Unique_Node_List& worklist, SafePointNode* sfpt, Node* root, PhaseGVN* gvn) {
165 ciValueKlass* vk = value_klass();
166 uint nfields = vk->nof_nonstatic_fields();
167 JVMState* jvms = sfpt->jvms();
168 int start = jvms->debug_start();
169 int end = jvms->debug_end();
170 // Replace safepoint edge by SafePointScalarObjectNode and add field values
171 assert(jvms != NULL, "missing JVMS");
172 uint first_ind = (sfpt->req() - jvms->scloff());
173 const TypeValueTypePtr* res_type = value_type_ptr();
174 SafePointScalarObjectNode* sobj = new SafePointScalarObjectNode(res_type,
175 #ifdef ASSERT
176 NULL,
177 #endif
178 first_ind, nfields);
179 sobj->init_req(0, root);
180 // Iterate over the value type fields in order of increasing
181 // offset and add the field values to the safepoint.
204 // Process all safepoint uses and scalarize value type
205 Unique_Node_List worklist;
206 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
207 Node* u = fast_out(i);
208 if (u->is_SafePoint() && (!u->is_Call() || u->as_Call()->has_debug_use(this))) {
209 SafePointNode* sfpt = u->as_SafePoint();
210 Node* in_oop = get_oop();
211 const Type* oop_type = in_oop->bottom_type();
212 assert(Opcode() == Op_ValueTypePtr || !isa_ValueType()->is_allocated(gvn), "already heap allocated value types should be linked directly");
213 int nb = make_scalar_in_safepoint(worklist, sfpt, root, gvn);
214 --i; imax -= nb;
215 }
216 }
217 // Now scalarize non-flattened fields
218 for (uint i = 0; i < worklist.size(); ++i) {
219 Node* vt = worklist.at(i);
220 vt->as_ValueType()->make_scalar_in_safepoints(root, gvn);
221 }
222 }
223
224 void ValueTypeBaseNode::make(PhaseGVN* gvn, Node*& ctl, Node* mem, Node* n, ValueTypeBaseNode* vt, ciValueKlass* base_vk, int base_offset, int base_input, bool in) {
225 assert(base_offset >= 0, "offset in value type always positive");
226 for (uint i = 0; i < vt->field_count(); i++) {
227 ciType* field_type = vt->field_type(i);
228 int offset = base_offset + vt->field_offset(i);
229 if (field_type->is_valuetype() && vt->field_is_flattened(i)) {
230 ciValueKlass* embedded_vk = field_type->as_value_klass();
231 ValueTypeNode* embedded_vt = ValueTypeNode::make(*gvn, embedded_vk);
232 ValueTypeBaseNode::make(gvn, ctl, mem, n, embedded_vt, base_vk, offset - vt->value_klass()->first_field_offset(), base_input, in);
233 vt->set_field_value(i, gvn->transform(embedded_vt));
234 } else {
235 int j = 0; int extra = 0;
236 for (; j < base_vk->nof_nonstatic_fields(); j++) {
237 ciField* f = base_vk->nonstatic_field_at(j);
238 if (offset == f->offset()) {
239 assert(f->type() == field_type, "inconsistent field type");
240 break;
241 }
242 BasicType bt = f->type()->basic_type();
243 if (bt == T_LONG || bt == T_DOUBLE) {
244 extra++;
245 }
246 }
247 assert(j != base_vk->nof_nonstatic_fields(), "must find");
248 Node* parm = NULL;
249 if (n->is_Start()) {
250 assert(in, "return from start?");
251 parm = gvn->transform(new ParmNode(n->as_Start(), base_input + j + extra));
252 } else {
253 if (in) {
254 assert(n->is_Call(), "nothing else here");
255 parm = n->in(base_input + j + extra);
256 } else {
257 parm = gvn->transform(new ProjNode(n->as_Call(), base_input + j + extra));
258 }
259 }
260 if (field_type->is_valuetype()) {
261 // Non-flattened value type field, check for null
262 parm = ValueTypeNode::make(*gvn, ctl, mem, parm, /* null_check */ true);
263
264 }
265 vt->set_field_value(i, parm);
266 // Record all these guys for later GVN.
267 gvn->record_for_igvn(parm);
268 }
269 }
270 }
271
272 void ValueTypeBaseNode::load(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
273 // Initialize the value type by loading its field values from
274 // memory and adding the values as input edges to the node.
275 for (uint i = 0; i < field_count(); ++i) {
276 int offset = holder_offset + field_offset(i);
277 ciType* ftype = field_type(i);
278 Node* value = NULL;
279 if (ftype->is_valuetype() && field_is_flattened(i)) {
280 // Recursively load the flattened value type field
281 value = ValueTypeNode::make(gvn, ftype->as_value_klass(), ctl, mem, base, ptr, holder, offset);
282 } else {
283 const Type* con_type = NULL;
284 if (base->is_Con()) {
285 // If the oop to the value type is constant (static final field), we can
286 // also treat the fields as constants because the value type is immutable.
287 const TypeOopPtr* oop_ptr = base->bottom_type()->isa_oopptr();
288 ciObject* constant_oop = oop_ptr->const_oop();
289 ciField* field = holder->get_field_by_offset(offset, false);
290 ciConstant constant = constant_oop->as_instance()->field_value(field);
291 con_type = Type::make_from_constant(constant, /*require_const=*/ true);
292 }
293 if (con_type != NULL) {
294 // Found a constant field value
295 value = gvn.transform(gvn.makecon(con_type));
296 if (con_type->isa_valuetypeptr()) {
297 // Constant, non-flattened value type field
298 value = ValueTypeNode::make(gvn, ctl, mem, value);
299 }
300 } else {
301 // Load field value from memory
302 const Type* base_type = gvn.type(base);
303 const TypePtr* adr_type = NULL;
304 if (base_type->isa_aryptr()) {
305 // In the case of a flattened value type array, each field has its own slice
306 adr_type = base_type->is_aryptr()->with_field_offset(offset)->add_offset(Type::OffsetBot);
307 } else {
308 ciField* field = holder->get_field_by_offset(offset, false);
309 adr_type = gvn.C->alias_type(field)->adr_type();
310 }
311 Node* adr = gvn.transform(new AddPNode(base, ptr, gvn.MakeConX(offset)));
312 BasicType bt = type2field[ftype->basic_type()];
313 const Type* ft = Type::get_const_type(ftype);
314 if (bt == T_VALUETYPE) {
315 ft = ft->is_valuetypeptr()->cast_to_ptr_type(TypePtr::BotPTR);
316 }
317 assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
318 value = gvn.transform(LoadNode::make(gvn, NULL, mem, adr, adr_type, ft, bt, MemNode::unordered));
319 if (bt == T_VALUETYPE) {
320 // Non-flattened value type field, check for null
321 value = ValueTypeNode::make(gvn, ctl, mem, value, /* null_check */ true);
322 }
323 }
324 }
325 set_field_value(i, value);
326 }
327 }
328
329 void ValueTypeBaseNode::store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) const {
330 // The value type is embedded into the object without an oop header. Subtract the
331 // offset of the first field to account for the missing header when storing the values.
332 holder_offset -= value_klass()->first_field_offset();
333 store(kit, base, ptr, holder, holder_offset);
334 }
335
336 void ValueTypeBaseNode::store(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) const {
337 if (holder == NULL) {
338 holder = value_klass();
339 }
340 // Write field values to memory
341 for (uint i = 0; i < field_count(); ++i) {
342 int offset = holder_offset + field_offset(i);
343 Node* value = field_value(i);
344 if (value->is_ValueType() && field_is_flattened(i)) {
345 // Recursively store the flattened value type field
346 value->isa_ValueType()->store_flattened(kit, base, ptr, holder, offset);
347 } else {
348 const Type* base_type = kit->gvn().type(base);
349 const TypePtr* adr_type = NULL;
350 if (base_type->isa_aryptr()) {
351 // In the case of a flattened value type array, each field has its own slice
352 adr_type = base_type->is_aryptr()->with_field_offset(offset)->add_offset(Type::OffsetBot);
353 } else {
354 ciField* field = holder->get_field_by_offset(offset, false);
355 adr_type = kit->C->alias_type(field)->adr_type();
356 }
357 Node* adr = kit->basic_plus_adr(base, ptr, offset);
358 BasicType bt = type2field[field_type(i)->basic_type()];
359 if (is_java_primitive(bt)) {
360 kit->store_to_memory(kit->control(), adr, value, bt, adr_type, MemNode::unordered);
361 } else {
362 const TypeOopPtr* ft = TypeOopPtr::make_from_klass(field_type(i)->as_klass());
363 // Field may be NULL
364 ft = ft->cast_to_ptr_type(TypePtr::BotPTR)->is_oopptr();
365 assert(adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
366 bool is_array = base_type->isa_aryptr() != NULL;
367 kit->store_oop(kit->control(), base, adr, adr_type, value, ft, bt, is_array, MemNode::unordered);
368 }
369 }
370 }
371 }
372
373 ValueTypeBaseNode* ValueTypeBaseNode::allocate(GraphKit* kit) {
374 Node* in_oop = get_oop();
375 Node* null_ctl = kit->top();
376 // Check if value type is already allocated
377 Node* not_null_oop = kit->null_check_oop(in_oop, &null_ctl);
378 if (null_ctl->is_top()) {
379 // Value type is allocated
380 return this;
381 }
382 // Not able to prove that value type is allocated.
383 // Emit runtime check that may be folded later.
384 assert(!is_allocated(&kit->gvn()), "should not be allocated");
385 const TypeValueTypePtr* vtptr_type = bottom_type()->isa_valuetypeptr();
386 if (vtptr_type == NULL) {
387 vtptr_type = TypeValueTypePtr::make(bottom_type()->isa_valuetype(), TypePtr::NotNull);
388 }
389 RegionNode* region = new RegionNode(3);
390 PhiNode* oop = new PhiNode(region, vtptr_type);
391 PhiNode* io = new PhiNode(region, Type::ABIO);
392 PhiNode* mem = new PhiNode(region, Type::MEMORY, TypePtr::BOTTOM);
393
394 // Oop is non-NULL, use it
395 region->init_req(1, kit->control());
396 oop ->init_req(1, not_null_oop);
397 io ->init_req(1, kit->i_o());
398 mem ->init_req(1, kit->merged_memory());
399
400 // Oop is NULL, allocate value type
401 kit->set_control(null_ctl);
402 kit->kill_dead_locals();
403 ciValueKlass* vk = value_klass();
404 Node* klass_node = kit->makecon(TypeKlassPtr::make(vk));
405 Node* alloc_oop = kit->new_instance(klass_node, NULL, NULL, false, this);
406 // Write field values to memory
407 store(kit, alloc_oop, alloc_oop, vk);
408 region->init_req(2, kit->control());
409 oop ->init_req(2, alloc_oop);
410 io ->init_req(2, kit->i_o());
450 ciField* f = vk->nonstatic_field_at(j);
451 BasicType bt = f->type()->basic_type();
452 if (bt == T_LONG || bt == T_DOUBLE) {
453 extra++;
454 }
455 }
456 ciField* f = vk->nonstatic_field_at(field_nb - extra);
457 Node* field = field_value_by_offset(f->offset(), true);
458 if (field->is_ValueType()) {
459 assert(f->is_flattened(), "should be flattened");
460 field = field->as_ValueType()->allocate(kit)->get_oop();
461 }
462 C->gvn_replace_by(pn, field);
463 C->initial_gvn()->hash_delete(pn);
464 pn->set_req(0, C->top());
465 --i; --imax;
466 }
467 }
468 }
469
470 ValueTypeNode* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* klass) {
471 // Create a new ValueTypeNode with uninitialized values and NULL oop
472 const TypeValueType* type = TypeValueType::make(klass);
473 return new ValueTypeNode(type, gvn.zerocon(T_VALUETYPE), gvn.C);
474 }
475
476 Node* ValueTypeNode::make_default(PhaseGVN& gvn, ciValueKlass* vk) {
477 // TODO re-use constant oop of pre-allocated default value type here?
478 // Create a new ValueTypeNode with default values
479 ValueTypeNode* vt = ValueTypeNode::make(gvn, vk);
480 for (uint i = 0; i < vt->field_count(); ++i) {
481 ciType* field_type = vt->field_type(i);
482 Node* value = NULL;
483 if (field_type->is_valuetype()) {
484 value = ValueTypeNode::make_default(gvn, field_type->as_value_klass());
485 } else {
486 value = gvn.zerocon(field_type->basic_type());
487 }
488 vt->set_field_value(i, value);
489 }
490 return gvn.transform(vt);
491 }
492
493 Node* ValueTypeNode::make(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* oop, bool null_check) {
494 // Create and initialize a ValueTypeNode by loading all field
495 // values from a heap-allocated version and also save the oop.
496 const TypeValueType* type = gvn.type(oop)->is_valuetypeptr()->value_type();
497 ValueTypeNode* vt = new ValueTypeNode(type, oop, gvn.C);
498
499 if (null_check && !vt->is_allocated(&gvn)) {
500 // Add oop null check
501 Node* chk = gvn.transform(new CmpPNode(oop, gvn.zerocon(T_VALUETYPE)));
502 Node* tst = gvn.transform(new BoolNode(chk, BoolTest::ne));
503 IfNode* iff = gvn.transform(new IfNode(ctl, tst, PROB_MAX, COUNT_UNKNOWN))->as_If();
504 Node* not_null = gvn.transform(new IfTrueNode(iff));
505 Node* null = gvn.transform(new IfFalseNode(iff));
506 Node* region = new RegionNode(3);
507
508 // Load value type from memory if oop is non-null
509 oop = new CastPPNode(oop, TypePtr::NOTNULL);
510 oop->set_req(0, not_null);
511 oop = gvn.transform(oop);
512 vt->load(gvn, not_null, mem, oop, oop, type->value_klass());
513 region->init_req(1, not_null);
514
515 // Use default value type if oop is null
516 Node* def = make_default(gvn, type->value_klass());
517 region->init_req(2, null);
518
519 // Merge the two value types and update control
520 vt = vt->clone_with_phis(&gvn, region)->as_ValueType();
521 vt->merge_with(&gvn, def->as_ValueType(), 2, true);
522 ctl = gvn.transform(region);
523 } else {
524 Node* init_ctl = ctl;
525 vt->load(gvn, ctl, mem, oop, oop, type->value_klass());
526 vt = gvn.transform(vt)->as_ValueType();
527 assert(vt->is_allocated(&gvn), "value type should be allocated");
528 assert(init_ctl != ctl || oop->is_Con() || oop->is_CheckCastPP() || oop->Opcode() == Op_ValueTypePtr ||
529 vt->is_loaded(&gvn, type) == oop, "value type should be loaded");
530 }
531 return vt;
532 }
533
534 Node* ValueTypeNode::make(GraphKit* kit, Node* oop, bool null_check) {
535 Node* ctl = kit->control();
536 Node* vt = make(kit->gvn(), ctl, kit->merged_memory(), oop, null_check);
537 kit->set_control(ctl);
538 return vt;
539 }
540
541 Node* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* vk, Node*& ctl, Node* mem, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
542 // Create and initialize a ValueTypeNode by loading all field values from
543 // a flattened value type field at 'holder_offset' or from a value type array.
544 ValueTypeNode* vt = make(gvn, vk);
545 // The value type is flattened into the object without an oop header. Subtract the
546 // offset of the first field to account for the missing header when loading the values.
547 holder_offset -= vk->first_field_offset();
548 vt->load(gvn, ctl, mem, obj, ptr, holder, holder_offset);
549 assert(vt->is_loaded(&gvn, vt->type()->isa_valuetype()) != obj, "holder oop should not be used as flattened value type oop");
550 return gvn.transform(vt)->as_ValueType();
551 }
552
553 Node* ValueTypeNode::make(GraphKit* kit, ciValueKlass* vk, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
554 Node* ctl = kit->control();
555 Node* vt = make(kit->gvn(), vk, ctl, kit->merged_memory(), obj, ptr, holder, holder_offset);
556 kit->set_control(ctl);
557 return vt;
558 }
559
560 Node* ValueTypeNode::make(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* n, ciValueKlass* vk, int base_input, bool in) {
561 ValueTypeNode* vt = ValueTypeNode::make(gvn, vk);
562 ValueTypeBaseNode::make(&gvn, ctl, mem, n, vt, vk, 0, base_input, in);
563 return gvn.transform(vt);
564 }
565
566 Node* ValueTypeNode::is_loaded(PhaseGVN* phase, const TypeValueType* t, Node* base, int holder_offset) {
567 if (field_count() == 0) {
568 assert(t->value_klass()->is__Value(), "unexpected value type klass");
569 assert(is_allocated(phase), "must be allocated");
570 return get_oop();
571 }
572 for (uint i = 0; i < field_count(); ++i) {
573 int offset = holder_offset + field_offset(i);
574 Node* value = field_value(i);
575 if (value->isa_DecodeN()) {
576 // Skip DecodeN
577 value = value->in(1);
578 }
579 if (value->isa_Load()) {
580 // Check if base and offset of field load matches value type layout
581 intptr_t loffset = 0;
582 Node* lbase = AddPNode::Ideal_base_and_offset(value->in(MemNode::Address), phase, loffset);
583 if (lbase == NULL || (lbase != base && base != NULL) || loffset != offset) {
584 return NULL;
585 } else if (base == NULL) {
586 // Set base and check if pointer type matches
587 base = lbase;
588 const TypeValueTypePtr* vtptr = phase->type(base)->isa_valuetypeptr();
589 if (vtptr == NULL || !vtptr->value_type()->eq(t)) {
590 return NULL;
591 }
592 }
593 } else if (value->isa_ValueType()) {
594 // Check value type field load recursively
595 ValueTypeNode* vt = value->as_ValueType();
596 base = vt->is_loaded(phase, t, base, offset - vt->value_klass()->first_field_offset());
597 if (base == NULL) {
598 return NULL;
599 }
600 } else {
601 return NULL;
602 }
603 }
604 return base;
605 }
606
607 Node* ValueTypeNode::allocate_fields(GraphKit* kit) {
608 ValueTypeNode* vt = clone()->as_ValueType();
609 for (uint i = 0; i < field_count(); i++) {
610 Node* value = field_value(i);
611 if (value->is_ValueType()) {
612 if (field_is_flattened(i)) {
613 value = value->as_ValueType()->allocate_fields(kit);
614 } else {
615 // Non-flattened value type field
616 value = value->as_ValueType()->allocate(kit);
617 }
618 vt->set_field_value(i, value);
619 }
620 }
621 vt = kit->gvn().transform(vt)->as_ValueType();
622 kit->replace_in_map(this, vt);
623 return vt;
624 }
625
626 Node* ValueTypeNode::tagged_klass(PhaseGVN& gvn) {
627 ciValueKlass* vk = value_klass();
628 const TypeKlassPtr* tk = TypeKlassPtr::make(vk);
629 intptr_t bits = tk->get_con();
630 set_nth_bit(bits, 0);
631 return gvn.makecon(TypeRawPtr::make((address)bits));
632 }
633
634 void ValueTypeNode::pass_klass(Node* n, uint pos, const GraphKit& kit) {
635 n->init_req(pos, tagged_klass(kit.gvn()));
636 }
637
638 uint ValueTypeNode::pass_fields(Node* n, int base_input, GraphKit& kit, bool assert_allocated, ciValueKlass* base_vk, int base_offset) {
639 ciValueKlass* vk = value_klass();
640 if (base_vk == NULL) {
641 base_vk = vk;
642 }
643 uint edges = 0;
644 for (uint i = 0; i < field_count(); i++) {
645 ciType* f_type = field_type(i);
646 int offset = base_offset + field_offset(i) - (base_offset > 0 ? vk->first_field_offset() : 0);
647 Node* arg = field_value(i);
648 if (f_type->is_valuetype() && field_is_flattened(i)) {
649 ciValueKlass* embedded_vk = f_type->as_value_klass();
650 edges += arg->as_ValueType()->pass_fields(n, base_input, kit, assert_allocated, base_vk, offset);
651 } else {
652 int j = 0; int extra = 0;
653 for (; j < base_vk->nof_nonstatic_fields(); j++) {
654 ciField* f = base_vk->nonstatic_field_at(j);
655 if (offset == f->offset()) {
656 assert(f->type() == f_type, "inconsistent field type");
657 break;
658 }
659 BasicType bt = f->type()->basic_type();
660 if (bt == T_LONG || bt == T_DOUBLE) {
661 extra++;
662 }
663 }
664 if (arg->is_ValueType()) {
665 // non-flattened value type field
666 ValueTypeNode* vt = arg->as_ValueType();
667 assert(!assert_allocated || vt->is_allocated(&kit.gvn()), "value type field should be allocated");
668 arg = vt->allocate(&kit)->get_oop();
669 }
670 n->init_req(base_input + j + extra, arg);
671 edges++;
672 BasicType bt = f_type->basic_type();
673 if (bt == T_LONG || bt == T_DOUBLE) {
674 n->init_req(base_input + j + extra + 1, kit.top());
675 edges++;
676 }
677 }
678 }
679 return edges;
680 }
681
682 Node* ValueTypeNode::Ideal(PhaseGVN* phase, bool can_reshape) {
683 if (!is_allocated(phase)) {
684 // Check if this value type is loaded from memory
685 Node* base = is_loaded(phase, type()->is_valuetype());
686 if (base != NULL) {
687 // Save the oop
688 set_oop(base);
689 assert(is_allocated(phase), "should now be allocated");
690 return this;
691 }
692 }
693
694 if (can_reshape) {
695 PhaseIterGVN* igvn = phase->is_IterGVN();
696 if (is_allocated(igvn)) {
697 // Value type is heap allocated, search for safepoint uses
698 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
699 Node* out = fast_out(i);
700 if (out->is_SafePoint()) {
701 // Let SafePointNode::Ideal() take care of re-wiring the
702 // safepoint to the oop input instead of the value type node.
703 igvn->rehash_node_delayed(out);
704 }
705 }
779 out->as_ValueType()->remove_redundant_allocations(igvn, phase);
780 --i; --imax;
781 } else if (out->isa_Allocate() != NULL) {
782 // Unlink AllocateNode
783 assert(out->in(AllocateNode::ValueNode) == this, "should be linked");
784 igvn->replace_input_of(out, AllocateNode::ValueNode, NULL);
785 --i; --imax;
786 } else {
787 #ifdef ASSERT
788 // The value type should not have any other users at this time
789 out->dump();
790 assert(false, "unexpected user of value type");
791 #endif
792 }
793 }
794
795 // Should be dead now
796 igvn->remove_dead_node(this);
797 }
798
799 #ifndef PRODUCT
800
801 void ValueTypeNode::dump_spec(outputStream* st) const {
802 TypeNode::dump_spec(st);
803 }
804
805 #endif
806
807 ValueTypePtrNode* ValueTypePtrNode::make(GraphKit* kit, ciValueKlass* vk, CallNode* call) {
808 ValueTypePtrNode* vt = new ValueTypePtrNode(vk, kit->zerocon(T_VALUETYPE), kit->C);
809 Node* ctl = kit->control();
810 ValueTypeBaseNode::make(&kit->gvn(), ctl, kit->merged_memory(), call, vt, vk, 0, TypeFunc::Parms+1, false);
811 kit->set_control(ctl);
812 return vt;
813 }
814
815 ValueTypePtrNode* ValueTypePtrNode::make(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* oop) {
816 // Create and initialize a ValueTypePtrNode by loading all field
817 // values from a heap-allocated version and also save the oop.
818 ciValueKlass* vk = gvn.type(oop)->is_valuetypeptr()->value_type()->value_klass();
819 ValueTypePtrNode* vtptr = new ValueTypePtrNode(vk, oop, gvn.C);
820 vtptr->load(gvn, ctl, mem, oop, oop, vk);
821 return vtptr;
822 }
|
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "ci/ciValueKlass.hpp"
27 #include "opto/addnode.hpp"
28 #include "opto/castnode.hpp"
29 #include "opto/graphKit.hpp"
30 #include "opto/rootnode.hpp"
31 #include "opto/valuetypenode.hpp"
32 #include "opto/phaseX.hpp"
33
34 // Clones the values type to handle control flow merges involving multiple value types.
35 // The inputs are replaced by PhiNodes to represent the merged values for the given region.
36 ValueTypeBaseNode* ValueTypeBaseNode::clone_with_phis(PhaseGVN* gvn, Node* region) {
37 assert(!has_phi_inputs(region), "already cloned with phis");
38 ValueTypeBaseNode* vt = clone()->as_ValueTypeBase();
39
40 // Create a PhiNode for merging the oop values
41 const Type* phi_type = Type::get_const_type(value_klass());
42 PhiNode* oop = PhiNode::make(region, vt->get_oop(), phi_type);
43 gvn->set_type(oop, phi_type);
44 vt->set_oop(oop);
45
46 // Create a PhiNode each for merging the field values
47 for (uint i = 0; i < vt->field_count(); ++i) {
48 ciType* type = vt->field_type(i);
49 Node* value = vt->field_value(i);
50 if (type->is_valuetype()) {
51 // Handle flattened value type fields recursively
52 value = value->as_ValueType()->clone_with_phis(gvn, region);
53 } else {
54 phi_type = Type::get_const_type(type);
55 value = PhiNode::make(region, value, phi_type);
56 gvn->set_type(value, phi_type);
57 }
58 vt->set_field_value(i, value);
59 }
60 gvn->set_type(vt, vt->bottom_type());
61 return vt;
62 }
63
64 // Checks if the inputs of the ValueBaseTypeNode were replaced by PhiNodes
65 // for the given region (see ValueBaseTypeNode::clone_with_phis).
66 bool ValueTypeBaseNode::has_phi_inputs(Node* region) {
67 // Check oop input
68 bool result = get_oop()->is_Phi() && get_oop()->as_Phi()->region() == region;
69 #ifdef ASSERT
70 if (result) {
71 // Check all field value inputs for consistency
72 for (uint i = Oop; i < field_count(); ++i) {
73 Node* n = in(i);
74 if (n->is_ValueTypeBase()) {
140 return value;
141 }
142
143 void ValueTypeBaseNode::set_field_value(uint index, Node* value) {
144 assert(index < field_count(), "index out of bounds");
145 set_req(Values + index, value);
146 }
147
148 int ValueTypeBaseNode::field_offset(uint index) const {
149 assert(index < field_count(), "index out of bounds");
150 return value_klass()->declared_nonstatic_field_at(index)->offset();
151 }
152
153 ciType* ValueTypeBaseNode::field_type(uint index) const {
154 assert(index < field_count(), "index out of bounds");
155 return value_klass()->declared_nonstatic_field_at(index)->type();
156 }
157
158 bool ValueTypeBaseNode::field_is_flattened(uint index) const {
159 assert(index < field_count(), "index out of bounds");
160 ciField* field = value_klass()->declared_nonstatic_field_at(index);
161 assert(!field->is_flattened() || field->type()->is_valuetype(), "must be a value type");
162 return field->is_flattened();
163 }
164
165 int ValueTypeBaseNode::make_scalar_in_safepoint(Unique_Node_List& worklist, SafePointNode* sfpt, Node* root, PhaseGVN* gvn) {
166 ciValueKlass* vk = value_klass();
167 uint nfields = vk->nof_nonstatic_fields();
168 JVMState* jvms = sfpt->jvms();
169 int start = jvms->debug_start();
170 int end = jvms->debug_end();
171 // Replace safepoint edge by SafePointScalarObjectNode and add field values
172 assert(jvms != NULL, "missing JVMS");
173 uint first_ind = (sfpt->req() - jvms->scloff());
174 const TypeValueTypePtr* res_type = value_type_ptr();
175 SafePointScalarObjectNode* sobj = new SafePointScalarObjectNode(res_type,
176 #ifdef ASSERT
177 NULL,
178 #endif
179 first_ind, nfields);
180 sobj->init_req(0, root);
181 // Iterate over the value type fields in order of increasing
182 // offset and add the field values to the safepoint.
205 // Process all safepoint uses and scalarize value type
206 Unique_Node_List worklist;
207 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
208 Node* u = fast_out(i);
209 if (u->is_SafePoint() && (!u->is_Call() || u->as_Call()->has_debug_use(this))) {
210 SafePointNode* sfpt = u->as_SafePoint();
211 Node* in_oop = get_oop();
212 const Type* oop_type = in_oop->bottom_type();
213 assert(Opcode() == Op_ValueTypePtr || !isa_ValueType()->is_allocated(gvn), "already heap allocated value types should be linked directly");
214 int nb = make_scalar_in_safepoint(worklist, sfpt, root, gvn);
215 --i; imax -= nb;
216 }
217 }
218 // Now scalarize non-flattened fields
219 for (uint i = 0; i < worklist.size(); ++i) {
220 Node* vt = worklist.at(i);
221 vt->as_ValueType()->make_scalar_in_safepoints(root, gvn);
222 }
223 }
224
225 void ValueTypeBaseNode::initialize(PhaseGVN* gvn, Node*& ctl, Node* mem, MultiNode* multi, ciValueKlass* vk, int base_offset, int base_input, bool in) {
226 assert(base_offset >= 0, "offset in value type must be positive");
227 for (uint i = 0; i < field_count(); i++) {
228 ciType* ft = field_type(i);
229 int offset = base_offset + field_offset(i);
230 if (field_is_flattened(i)) {
231 // Flattened value type field
232 ValueTypeNode* vt = ValueTypeNode::make_uninitialized(*gvn, ft->as_value_klass());
233 vt->initialize(gvn, ctl, mem, multi, vk, offset - value_klass()->first_field_offset(), base_input, in);
234 set_field_value(i, gvn->transform(vt));
235 } else {
236 int j = 0; int extra = 0;
237 for (; j < vk->nof_nonstatic_fields(); j++) {
238 ciField* f = vk->nonstatic_field_at(j);
239 if (offset == f->offset()) {
240 assert(f->type() == ft, "inconsistent field type");
241 break;
242 }
243 BasicType bt = f->type()->basic_type();
244 if (bt == T_LONG || bt == T_DOUBLE) {
245 extra++;
246 }
247 }
248 assert(j != vk->nof_nonstatic_fields(), "must find");
249 Node* parm = NULL;
250 if (multi->is_Start()) {
251 assert(in, "return from start?");
252 parm = gvn->transform(new ParmNode(multi->as_Start(), base_input + j + extra));
253 } else {
254 if (in) {
255 parm = multi->as_Call()->in(base_input + j + extra);
256 } else {
257 parm = gvn->transform(new ProjNode(multi->as_Call(), base_input + j + extra));
258 }
259 }
260 if (ft->is_valuetype()) {
261 // Non-flattened value type field, check for null
262 parm = ValueTypeNode::make_from_oop(*gvn, ctl, mem, parm, /* null_check */ true);
263 }
264 set_field_value(i, parm);
265 // Record all these guys for later GVN.
266 gvn->record_for_igvn(parm);
267 }
268 }
269 }
270
271 void ValueTypeBaseNode::load(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
272 // Initialize the value type by loading its field values from
273 // memory and adding the values as input edges to the node.
274 for (uint i = 0; i < field_count(); ++i) {
275 int offset = holder_offset + field_offset(i);
276 Node* value = NULL;
277 ciType* ft = field_type(i);
278 if (field_is_flattened(i)) {
279 // Recursively load the flattened value type field
280 value = ValueTypeNode::make_from_flattened(gvn, ft->as_value_klass(), ctl, mem, base, ptr, holder, offset);
281 } else {
282 const Type* con_type = NULL;
283 if (base->is_Con()) {
284 // If the oop to the value type is constant (static final field), we can
285 // also treat the fields as constants because the value type is immutable.
286 const TypeOopPtr* oop_ptr = base->bottom_type()->isa_oopptr();
287 ciObject* constant_oop = oop_ptr->const_oop();
288 ciField* field = holder->get_field_by_offset(offset, false);
289 ciConstant constant = constant_oop->as_instance()->field_value(field);
290 con_type = Type::make_from_constant(constant, /*require_const=*/ true);
291 }
292 if (con_type != NULL) {
293 // Found a constant field value
294 value = gvn.transform(gvn.makecon(con_type));
295 if (con_type->isa_valuetypeptr()) {
296 // Constant, non-flattened value type field
297 value = ValueTypeNode::make_from_oop(gvn, ctl, mem, value);
298 }
299 } else {
300 // Load field value from memory
301 const TypeAryPtr* ary_type = gvn.type(base)->isa_aryptr();
302 const TypePtr* adr_type = NULL;
303 bool is_array = ary_type != NULL;
304 if (is_array) {
305 // In the case of a flattened value type array, each field has its own slice
306 adr_type = ary_type->with_field_offset(offset)->add_offset(Type::OffsetBot);
307 } else {
308 ciField* field = holder->get_field_by_offset(offset, false);
309 adr_type = gvn.C->alias_type(field)->adr_type();
310 }
311 Node* adr = gvn.transform(new AddPNode(base, ptr, gvn.MakeConX(offset)));
312 BasicType bt = type2field[ft->basic_type()];
313 assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
314 const Type* rt = Type::get_const_type(ft);
315 value = gvn.transform(LoadNode::make(gvn, is_array ? ctl : NULL, mem, adr, adr_type, rt, bt, MemNode::unordered));
316 if (bt == T_VALUETYPE) {
317 // Non-flattened value type field, check for null
318 value = ValueTypeNode::make_from_oop(gvn, ctl, mem, value, /* null_check */ true);
319 }
320 }
321 }
322 set_field_value(i, value);
323 }
324 }
325
326 void ValueTypeBaseNode::store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) const {
327 // The value type is embedded into the object without an oop header. Subtract the
328 // offset of the first field to account for the missing header when storing the values.
329 holder_offset -= value_klass()->first_field_offset();
330 store(kit, base, ptr, holder, holder_offset);
331 }
332
333 void ValueTypeBaseNode::store(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) const {
334 if (holder == NULL) {
335 holder = value_klass();
336 }
337 // Write field values to memory
338 for (uint i = 0; i < field_count(); ++i) {
339 int offset = holder_offset + field_offset(i);
340 Node* value = field_value(i);
341 ciType* ft = field_type(i);
342 if (field_is_flattened(i)) {
343 // Recursively store the flattened value type field
344 value->as_ValueType()->store_flattened(kit, base, ptr, holder, offset);
345 } else {
346 const TypeAryPtr* ary_type = kit->gvn().type(base)->isa_aryptr();
347 const TypePtr* adr_type = NULL;
348 bool is_array = ary_type != NULL;
349 if (is_array) {
350 // In the case of a flattened value type array, each field has its own slice
351 adr_type = ary_type->with_field_offset(offset)->add_offset(Type::OffsetBot);
352 } else {
353 ciField* field = holder->get_field_by_offset(offset, false);
354 adr_type = kit->C->alias_type(field)->adr_type();
355 }
356 Node* adr = kit->basic_plus_adr(base, ptr, offset);
357 BasicType bt = type2field[ft->basic_type()];
358 if (is_java_primitive(bt)) {
359 kit->store_to_memory(kit->control(), adr, value, bt, adr_type, MemNode::unordered);
360 } else {
361 const TypeOopPtr* val_type = Type::get_const_type(ft)->is_oopptr();
362 assert(adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
363 kit->store_oop(kit->control(), base, adr, adr_type, value, val_type, bt, is_array, MemNode::unordered);
364 }
365 }
366 }
367 }
368
369 ValueTypeBaseNode* ValueTypeBaseNode::allocate(GraphKit* kit) {
370 Node* in_oop = get_oop();
371 Node* null_ctl = kit->top();
372 // Check if value type is already allocated
373 Node* not_null_oop = kit->null_check_oop(in_oop, &null_ctl);
374 if (null_ctl->is_top()) {
375 // Value type is allocated
376 return this;
377 }
378 // Not able to prove that value type is allocated.
379 // Emit runtime check that may be folded later.
380 assert(!is_allocated(&kit->gvn()), "should not be allocated");
381 RegionNode* region = new RegionNode(3);
382 PhiNode* oop = new PhiNode(region, value_type_ptr());
383 PhiNode* io = new PhiNode(region, Type::ABIO);
384 PhiNode* mem = new PhiNode(region, Type::MEMORY, TypePtr::BOTTOM);
385
386 // Oop is non-NULL, use it
387 region->init_req(1, kit->control());
388 oop ->init_req(1, not_null_oop);
389 io ->init_req(1, kit->i_o());
390 mem ->init_req(1, kit->merged_memory());
391
392 // Oop is NULL, allocate value type
393 kit->set_control(null_ctl);
394 kit->kill_dead_locals();
395 ciValueKlass* vk = value_klass();
396 Node* klass_node = kit->makecon(TypeKlassPtr::make(vk));
397 Node* alloc_oop = kit->new_instance(klass_node, NULL, NULL, false, this);
398 // Write field values to memory
399 store(kit, alloc_oop, alloc_oop, vk);
400 region->init_req(2, kit->control());
401 oop ->init_req(2, alloc_oop);
402 io ->init_req(2, kit->i_o());
442 ciField* f = vk->nonstatic_field_at(j);
443 BasicType bt = f->type()->basic_type();
444 if (bt == T_LONG || bt == T_DOUBLE) {
445 extra++;
446 }
447 }
448 ciField* f = vk->nonstatic_field_at(field_nb - extra);
449 Node* field = field_value_by_offset(f->offset(), true);
450 if (field->is_ValueType()) {
451 assert(f->is_flattened(), "should be flattened");
452 field = field->as_ValueType()->allocate(kit)->get_oop();
453 }
454 C->gvn_replace_by(pn, field);
455 C->initial_gvn()->hash_delete(pn);
456 pn->set_req(0, C->top());
457 --i; --imax;
458 }
459 }
460 }
461
462 ValueTypeNode* ValueTypeNode::make_uninitialized(PhaseGVN& gvn, ciValueKlass* klass) {
463 // Create a new ValueTypeNode with uninitialized values and NULL oop
464 const TypeValueType* type = TypeValueType::make(klass);
465 return new ValueTypeNode(type, gvn.zerocon(T_VALUETYPE));
466 }
467
468 ValueTypeNode* ValueTypeNode::make_default(PhaseGVN& gvn, ciValueKlass* vk) {
469 // Create a new ValueTypeNode with default values
470 ValueTypeNode* vt = ValueTypeNode::make_uninitialized(gvn, vk);
471 for (uint i = 0; i < vt->field_count(); ++i) {
472 ciType* field_type = vt->field_type(i);
473 Node* value = NULL;
474 if (field_type->is_valuetype()) {
475 value = ValueTypeNode::make_default(gvn, field_type->as_value_klass());
476 } else {
477 value = gvn.zerocon(field_type->basic_type());
478 }
479 vt->set_field_value(i, value);
480 }
481 return gvn.transform(vt)->as_ValueType();
482 }
483
484 ValueTypeNode* ValueTypeNode::make_from_oop(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* oop, bool null_check) {
485 // Create and initialize a ValueTypeNode by loading all field
486 // values from a heap-allocated version and also save the oop.
487 ciValueKlass* vk = gvn.type(oop)->is_valuetypeptr()->value_klass();
488 ValueTypeNode* vt = new ValueTypeNode(TypeValueType::make(vk), oop);
489
490 if (null_check && !vt->is_allocated(&gvn)) {
491 // Add oop null check
492 Node* chk = gvn.transform(new CmpPNode(oop, gvn.zerocon(T_VALUETYPE)));
493 Node* tst = gvn.transform(new BoolNode(chk, BoolTest::ne));
494 IfNode* iff = gvn.transform(new IfNode(ctl, tst, PROB_MAX, COUNT_UNKNOWN))->as_If();
495 Node* not_null = gvn.transform(new IfTrueNode(iff));
496 Node* null = gvn.transform(new IfFalseNode(iff));
497 Node* region = new RegionNode(3);
498
499 // Load value type from memory if oop is non-null
500 oop = new CastPPNode(oop, TypePtr::NOTNULL);
501 oop->set_req(0, not_null);
502 oop = gvn.transform(oop);
503 vt->load(gvn, not_null, mem, oop, oop, vk);
504 region->init_req(1, not_null);
505
506 // Use default value type if oop is null
507 ValueTypeNode* def = make_default(gvn, vk);
508 region->init_req(2, null);
509
510 // Merge the two value types and update control
511 vt = vt->clone_with_phis(&gvn, region)->as_ValueType();
512 vt->merge_with(&gvn, def, 2, true);
513 ctl = gvn.transform(region);
514 } else {
515 Node* init_ctl = ctl;
516 vt->load(gvn, ctl, mem, oop, oop, vk);
517 vt = gvn.transform(vt)->as_ValueType();
518 assert(vt->is_allocated(&gvn), "value type should be allocated");
519 assert(init_ctl != ctl || oop->is_Con() || oop->is_CheckCastPP() || oop->Opcode() == Op_ValueTypePtr ||
520 vt->is_loaded(&gvn) == oop, "value type should be loaded");
521 }
522 return vt;
523 }
524
525 // GraphKit wrapper for the 'make_from_oop' method
526 ValueTypeNode* ValueTypeNode::make_from_oop(GraphKit* kit, Node* oop, bool null_check) {
527 Node* ctl = kit->control();
528 ValueTypeNode* vt = make_from_oop(kit->gvn(), ctl, kit->merged_memory(), oop, null_check);
529 kit->set_control(ctl);
530 return vt;
531 }
532
533 ValueTypeNode* ValueTypeNode::make_from_flattened(PhaseGVN& gvn, ciValueKlass* vk, Node*& ctl, Node* mem, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
534 // Create and initialize a ValueTypeNode by loading all field values from
535 // a flattened value type field at 'holder_offset' or from a value type array.
536 ValueTypeNode* vt = make_uninitialized(gvn, vk);
537 // The value type is flattened into the object without an oop header. Subtract the
538 // offset of the first field to account for the missing header when loading the values.
539 holder_offset -= vk->first_field_offset();
540 vt->load(gvn, ctl, mem, obj, ptr, holder, holder_offset);
541 assert(vt->is_loaded(&gvn) != obj, "holder oop should not be used as flattened value type oop");
542 return gvn.transform(vt)->as_ValueType();
543 }
544
545 // GraphKit wrapper for the 'make_from_flattened' method
546 ValueTypeNode* ValueTypeNode::make_from_flattened(GraphKit* kit, ciValueKlass* vk, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
547 Node* ctl = kit->control();
548 ValueTypeNode* vt = make_from_flattened(kit->gvn(), vk, ctl, kit->merged_memory(), obj, ptr, holder, holder_offset);
549 kit->set_control(ctl);
550 return vt;
551 }
552
553 ValueTypeNode* ValueTypeNode::make_from_multi(PhaseGVN& gvn, Node*& ctl, Node* mem, MultiNode* multi, ciValueKlass* vk, int base_input, bool in) {
554 ValueTypeNode* vt = ValueTypeNode::make_uninitialized(gvn, vk);
555 vt->initialize(&gvn, ctl, mem, multi, vk, 0, base_input, in);
556 return gvn.transform(vt)->as_ValueType();
557 }
558
559 Node* ValueTypeNode::is_loaded(PhaseGVN* phase, ciValueKlass* vk, Node* base, int holder_offset) {
560 if (vk == NULL) {
561 vk = value_klass();
562 }
563 if (field_count() == 0) {
564 assert(vk->is__Value(), "unexpected value type klass");
565 assert(is_allocated(phase), "must be allocated");
566 return get_oop();
567 }
568 for (uint i = 0; i < field_count(); ++i) {
569 int offset = holder_offset + field_offset(i);
570 Node* value = field_value(i);
571 if (value->isa_DecodeN()) {
572 // Skip DecodeN
573 value = value->in(1);
574 }
575 if (value->isa_Load()) {
576 // Check if base and offset of field load matches value type layout
577 intptr_t loffset = 0;
578 Node* lbase = AddPNode::Ideal_base_and_offset(value->in(MemNode::Address), phase, loffset);
579 if (lbase == NULL || (lbase != base && base != NULL) || loffset != offset) {
580 return NULL;
581 } else if (base == NULL) {
582 // Set base and check if pointer type matches
583 base = lbase;
584 const TypeValueTypePtr* vtptr = phase->type(base)->isa_valuetypeptr();
585 if (vtptr == NULL || !vtptr->value_klass()->equals(vk)) {
586 return NULL;
587 }
588 }
589 } else if (value->isa_ValueType()) {
590 // Check value type field load recursively
591 ValueTypeNode* vt = value->as_ValueType();
592 base = vt->is_loaded(phase, vk, base, offset - vt->value_klass()->first_field_offset());
593 if (base == NULL) {
594 return NULL;
595 }
596 } else {
597 return NULL;
598 }
599 }
600 return base;
601 }
602
603 Node* ValueTypeNode::allocate_fields(GraphKit* kit) {
604 ValueTypeNode* vt = clone()->as_ValueType();
605 for (uint i = 0; i < field_count(); i++) {
606 ValueTypeNode* value = field_value(i)->isa_ValueType();
607 if (field_is_flattened(i)) {
608 // Flattened value type field
609 vt->set_field_value(i, value->allocate_fields(kit));
610 } else if (value != NULL){
611 // Non-flattened value type field
612 vt->set_field_value(i, value->allocate(kit));
613 }
614 }
615 vt = kit->gvn().transform(vt)->as_ValueType();
616 kit->replace_in_map(this, vt);
617 return vt;
618 }
619
620 Node* ValueTypeNode::tagged_klass(PhaseGVN& gvn) {
621 ciValueKlass* vk = value_klass();
622 const TypeKlassPtr* tk = TypeKlassPtr::make(vk);
623 intptr_t bits = tk->get_con();
624 set_nth_bit(bits, 0);
625 return gvn.makecon(TypeRawPtr::make((address)bits));
626 }
627
628 void ValueTypeNode::pass_klass(Node* n, uint pos, const GraphKit& kit) {
629 n->init_req(pos, tagged_klass(kit.gvn()));
630 }
631
632 uint ValueTypeNode::pass_fields(Node* n, int base_input, GraphKit& kit, bool assert_allocated, ciValueKlass* base_vk, int base_offset) {
633 ciValueKlass* vk = value_klass();
634 if (base_vk == NULL) {
635 base_vk = vk;
636 }
637 uint edges = 0;
638 for (uint i = 0; i < field_count(); i++) {
639 int offset = base_offset + field_offset(i) - (base_offset > 0 ? vk->first_field_offset() : 0);
640 Node* arg = field_value(i);
641 if (field_is_flattened(i)) {
642 // Flattened value type field
643 edges += arg->as_ValueType()->pass_fields(n, base_input, kit, assert_allocated, base_vk, offset);
644 } else {
645 int j = 0; int extra = 0;
646 for (; j < base_vk->nof_nonstatic_fields(); j++) {
647 ciField* field = base_vk->nonstatic_field_at(j);
648 if (offset == field->offset()) {
649 assert(field->type() == field_type(i), "inconsistent field type");
650 break;
651 }
652 BasicType bt = field->type()->basic_type();
653 if (bt == T_LONG || bt == T_DOUBLE) {
654 extra++;
655 }
656 }
657 if (arg->is_ValueType()) {
658 // non-flattened value type field
659 ValueTypeNode* vt = arg->as_ValueType();
660 assert(!assert_allocated || vt->is_allocated(&kit.gvn()), "value type field should be allocated");
661 arg = vt->allocate(&kit)->get_oop();
662 }
663 n->init_req(base_input + j + extra, arg);
664 edges++;
665 BasicType bt = field_type(i)->basic_type();
666 if (bt == T_LONG || bt == T_DOUBLE) {
667 n->init_req(base_input + j + extra + 1, kit.top());
668 edges++;
669 }
670 }
671 }
672 return edges;
673 }
674
675 Node* ValueTypeNode::Ideal(PhaseGVN* phase, bool can_reshape) {
676 if (!is_allocated(phase)) {
677 // Check if this value type is loaded from memory
678 Node* base = is_loaded(phase);
679 if (base != NULL) {
680 // Save the oop
681 set_oop(base);
682 assert(is_allocated(phase), "should now be allocated");
683 return this;
684 }
685 }
686
687 if (can_reshape) {
688 PhaseIterGVN* igvn = phase->is_IterGVN();
689 if (is_allocated(igvn)) {
690 // Value type is heap allocated, search for safepoint uses
691 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
692 Node* out = fast_out(i);
693 if (out->is_SafePoint()) {
694 // Let SafePointNode::Ideal() take care of re-wiring the
695 // safepoint to the oop input instead of the value type node.
696 igvn->rehash_node_delayed(out);
697 }
698 }
772 out->as_ValueType()->remove_redundant_allocations(igvn, phase);
773 --i; --imax;
774 } else if (out->isa_Allocate() != NULL) {
775 // Unlink AllocateNode
776 assert(out->in(AllocateNode::ValueNode) == this, "should be linked");
777 igvn->replace_input_of(out, AllocateNode::ValueNode, NULL);
778 --i; --imax;
779 } else {
780 #ifdef ASSERT
781 // The value type should not have any other users at this time
782 out->dump();
783 assert(false, "unexpected user of value type");
784 #endif
785 }
786 }
787
788 // Should be dead now
789 igvn->remove_dead_node(this);
790 }
791
792 ValueTypePtrNode* ValueTypePtrNode::make_from_value_type(PhaseGVN& gvn, ValueTypeNode* vt) {
793 ValueTypePtrNode* vtptr = new ValueTypePtrNode(vt->value_klass(), vt->get_oop());
794 for (uint i = Oop+1; i < vt->req(); i++) {
795 vtptr->init_req(i, vt->in(i));
796 }
797 return gvn.transform(vtptr)->as_ValueTypePtr();
798 }
799
800 ValueTypePtrNode* ValueTypePtrNode::make_from_call(GraphKit* kit, ciValueKlass* vk, CallNode* call) {
801 ValueTypePtrNode* vtptr = new ValueTypePtrNode(vk, kit->zerocon(T_VALUETYPE));
802 Node* ctl = kit->control();
803 vtptr->initialize(&kit->gvn(), ctl, kit->merged_memory(), call, vk);
804 kit->set_control(ctl);
805 return vtptr;
806 }
807
808 ValueTypePtrNode* ValueTypePtrNode::make_from_oop(PhaseGVN& gvn, Node*& ctl, Node* mem, Node* oop) {
809 // Create and initialize a ValueTypePtrNode by loading all field
810 // values from a heap-allocated version and also save the oop.
811 ciValueKlass* vk = gvn.type(oop)->is_valuetypeptr()->value_klass();
812 ValueTypePtrNode* vtptr = new ValueTypePtrNode(vk, oop);
813 vtptr->load(gvn, ctl, mem, oop, oop, vk);
814 return vtptr;
815 }
|