342 assert(!kit->gvn().type(value)->maybe_null(), "should never be null");
343 value = ValueTypeNode::make_from_oop(kit, value, ft->as_value_klass());
344 }
345 value->as_ValueType()->store_flattened(kit, base, ptr, holder, offset, decorators);
346 } else {
347 // Store field value to memory
348 const TypePtr* adr_type = field_adr_type(base, offset, holder, decorators, kit->gvn());
349 Node* adr = kit->basic_plus_adr(base, ptr, offset);
350 BasicType bt = type2field[ft->basic_type()];
351 assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
352 const Type* val_type = Type::get_const_type(ft);
353 const TypeAryPtr* ary_type = kit->gvn().type(base)->isa_aryptr();
354 if (ary_type != NULL) {
355 decorators |= IS_ARRAY;
356 }
357 kit->access_store_at(base, adr, adr_type, value, val_type, bt, decorators, deoptimize_on_exception);
358 }
359 }
360 }
361
362 ValueTypeBaseNode* ValueTypeBaseNode::allocate(GraphKit* kit, bool deoptimize_on_exception) {
363 // Check if value type is already allocated
364 Node* null_ctl = kit->top();
365 Node* not_null_oop = kit->null_check_oop(get_oop(), &null_ctl);
366 if (null_ctl->is_top()) {
367 // Value type is allocated
368 return this;
369 }
370 assert(!is_allocated(&kit->gvn()), "should not be allocated");
371 RegionNode* region = new RegionNode(3);
372
373 // Oop is non-NULL, use it
374 region->init_req(1, kit->control());
375 PhiNode* oop = PhiNode::make(region, not_null_oop, value_ptr());
376 PhiNode* io = PhiNode::make(region, kit->i_o(), Type::ABIO);
377 PhiNode* mem = PhiNode::make(region, kit->merged_memory(), Type::MEMORY, TypePtr::BOTTOM);
378
379 {
380 // Oop is NULL, allocate and initialize buffer
381 PreserveJVMState pjvms(kit);
382 kit->set_control(null_ctl);
388 region->init_req(2, kit->control());
389 oop ->init_req(2, alloc_oop);
390 io ->init_req(2, kit->i_o());
391 mem ->init_req(2, kit->merged_memory());
392 }
393
394 // Update GraphKit
395 kit->set_control(kit->gvn().transform(region));
396 kit->set_i_o(kit->gvn().transform(io));
397 kit->set_all_memory(kit->gvn().transform(mem));
398 kit->record_for_igvn(region);
399 kit->record_for_igvn(oop);
400 kit->record_for_igvn(io);
401 kit->record_for_igvn(mem);
402
403 // Use cloned ValueTypeNode to propagate oop from now on
404 Node* res_oop = kit->gvn().transform(oop);
405 ValueTypeBaseNode* vt = clone()->as_ValueTypeBase();
406 vt->set_oop(res_oop);
407 vt = kit->gvn().transform(vt)->as_ValueTypeBase();
408 kit->replace_in_map(this, vt);
409 return vt;
410 }
411
412 bool ValueTypeBaseNode::is_allocated(PhaseGVN* phase) const {
413 Node* oop = get_oop();
414 const Type* oop_type = (phase != NULL) ? phase->type(oop) : oop->bottom_type();
415 return !oop_type->maybe_null();
416 }
417
418 // When a call returns multiple values, it has several result
419 // projections, one per field. Replacing the result of the call by a
420 // value type node (after late inlining) requires that for each result
421 // projection, we find the corresponding value type field.
422 void ValueTypeBaseNode::replace_call_results(GraphKit* kit, Node* call, Compile* C) {
423 ciValueKlass* vk = value_klass();
424 for (DUIterator_Fast imax, i = call->fast_outs(imax); i < imax; i++) {
425 ProjNode* pn = call->fast_out(i)->as_Proj();
426 uint con = pn->_con;
427 if (con >= TypeFunc::Parms+1) {
428 uint field_nb = con - (TypeFunc::Parms+1);
|
342 assert(!kit->gvn().type(value)->maybe_null(), "should never be null");
343 value = ValueTypeNode::make_from_oop(kit, value, ft->as_value_klass());
344 }
345 value->as_ValueType()->store_flattened(kit, base, ptr, holder, offset, decorators);
346 } else {
347 // Store field value to memory
348 const TypePtr* adr_type = field_adr_type(base, offset, holder, decorators, kit->gvn());
349 Node* adr = kit->basic_plus_adr(base, ptr, offset);
350 BasicType bt = type2field[ft->basic_type()];
351 assert(is_java_primitive(bt) || adr->bottom_type()->is_ptr_to_narrowoop() == UseCompressedOops, "inconsistent");
352 const Type* val_type = Type::get_const_type(ft);
353 const TypeAryPtr* ary_type = kit->gvn().type(base)->isa_aryptr();
354 if (ary_type != NULL) {
355 decorators |= IS_ARRAY;
356 }
357 kit->access_store_at(base, adr, adr_type, value, val_type, bt, decorators, deoptimize_on_exception);
358 }
359 }
360 }
361
362 ValueTypeBaseNode* ValueTypeBaseNode::allocate(GraphKit* kit, bool deoptimize_on_exception, bool safe_for_replace) {
363 // Check if value type is already allocated
364 Node* null_ctl = kit->top();
365 Node* not_null_oop = kit->null_check_oop(get_oop(), &null_ctl);
366 if (null_ctl->is_top()) {
367 // Value type is allocated
368 return this;
369 }
370 assert(!is_allocated(&kit->gvn()), "should not be allocated");
371 RegionNode* region = new RegionNode(3);
372
373 // Oop is non-NULL, use it
374 region->init_req(1, kit->control());
375 PhiNode* oop = PhiNode::make(region, not_null_oop, value_ptr());
376 PhiNode* io = PhiNode::make(region, kit->i_o(), Type::ABIO);
377 PhiNode* mem = PhiNode::make(region, kit->merged_memory(), Type::MEMORY, TypePtr::BOTTOM);
378
379 {
380 // Oop is NULL, allocate and initialize buffer
381 PreserveJVMState pjvms(kit);
382 kit->set_control(null_ctl);
388 region->init_req(2, kit->control());
389 oop ->init_req(2, alloc_oop);
390 io ->init_req(2, kit->i_o());
391 mem ->init_req(2, kit->merged_memory());
392 }
393
394 // Update GraphKit
395 kit->set_control(kit->gvn().transform(region));
396 kit->set_i_o(kit->gvn().transform(io));
397 kit->set_all_memory(kit->gvn().transform(mem));
398 kit->record_for_igvn(region);
399 kit->record_for_igvn(oop);
400 kit->record_for_igvn(io);
401 kit->record_for_igvn(mem);
402
403 // Use cloned ValueTypeNode to propagate oop from now on
404 Node* res_oop = kit->gvn().transform(oop);
405 ValueTypeBaseNode* vt = clone()->as_ValueTypeBase();
406 vt->set_oop(res_oop);
407 vt = kit->gvn().transform(vt)->as_ValueTypeBase();
408 if (safe_for_replace) {
409 kit->replace_in_map(this, vt);
410 }
411 return vt;
412 }
413
414 bool ValueTypeBaseNode::is_allocated(PhaseGVN* phase) const {
415 Node* oop = get_oop();
416 const Type* oop_type = (phase != NULL) ? phase->type(oop) : oop->bottom_type();
417 return !oop_type->maybe_null();
418 }
419
420 // When a call returns multiple values, it has several result
421 // projections, one per field. Replacing the result of the call by a
422 // value type node (after late inlining) requires that for each result
423 // projection, we find the corresponding value type field.
424 void ValueTypeBaseNode::replace_call_results(GraphKit* kit, Node* call, Compile* C) {
425 ciValueKlass* vk = value_klass();
426 for (DUIterator_Fast imax, i = call->fast_outs(imax); i < imax; i++) {
427 ProjNode* pn = call->fast_out(i)->as_Proj();
428 uint con = pn->_con;
429 if (con >= TypeFunc::Parms+1) {
430 uint field_nb = con - (TypeFunc::Parms+1);
|