< prev index next >
src/share/vm/opto/parse1.cpp
Print this page
@@ -125,11 +125,11 @@
case T_OBJECT: l = new LoadPNode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM, MemNode::unordered); break;
case T_VALUETYPE: {
// Load oop and create a new ValueTypeNode
const TypeValueTypePtr* vtptr_type = TypeValueTypePtr::make(type->is_valuetype(), TypePtr::NotNull);
l = _gvn.transform(new LoadPNode(ctl, mem, adr, TypeRawPtr::BOTTOM, vtptr_type, MemNode::unordered));
- l = ValueTypeNode::make(gvn(), mem, l);
+ l = ValueTypeNode::make(this, l);
break;
}
case T_VALUETYPEPTR: {
l = new LoadPNode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeValueTypePtr::NOTNULL, MemNode::unordered);
break;
@@ -203,11 +203,10 @@
void Parse::load_interpreter_state(Node* osr_buf) {
int index;
int max_locals = jvms()->loc_size();
int max_stack = jvms()->stk_size();
-
// Mismatch between method and jvms can occur since map briefly held
// an OSR entry state (which takes up one RawPtr word).
assert(max_locals == method()->max_locals(), "sanity");
assert(max_stack >= method()->max_stack(), "sanity");
assert((int)jvms()->endoff() == TypeFunc::Parms + max_locals + max_stack, "sanity");
@@ -241,19 +240,17 @@
Node *monitors_addr = basic_plus_adr(osr_buf, osr_buf, (max_locals+mcnt*2-1)*wordSize);
for (index = 0; index < mcnt; index++) {
// Make a BoxLockNode for the monitor.
Node *box = _gvn.transform(new BoxLockNode(next_monitor()));
-
// Displaced headers and locked objects are interleaved in the
// temp OSR buffer. We only copy the locked objects out here.
// Fetch the locked object from the OSR temp buffer and copy to our fastlock node.
Node* lock_object = fetch_interpreter_state(index*2, Type::get_const_basic_type(T_OBJECT), monitors_addr, osr_buf);
// Try and copy the displaced header to the BoxNode
Node* displaced_hdr = fetch_interpreter_state((index*2) + 1, Type::get_const_basic_type(T_ADDRESS), monitors_addr, osr_buf);
-
store_to_memory(control(), box, displaced_hdr, T_ADDRESS, Compile::AliasIdxRaw, MemNode::unordered);
// Build a bogus FastLockNode (no code will be generated) and push the
// monitor into our debug info.
const FastLockNode *flock = _gvn.transform(new FastLockNode( 0, lock_object, box ))->as_FastLock();
@@ -806,11 +803,11 @@
if (ret_oop_type && !ret_oop_type->klass()->is_loaded()) {
ret_type = TypeOopPtr::BOTTOM;
}
if ((_caller->has_method() || tf()->returns_value_type_as_fields()) &&
ret_type->isa_valuetypeptr() &&
- ret_type->is_valuetypeptr()->klass() != C->env()->___Value_klass()) {
+ !ret_type->is_valuetypeptr()->is__Value()) {
// When inlining or with multiple return values: return value
// type as ValueTypeNode not as oop
ret_type = ret_type->is_valuetypeptr()->value_type();
}
int ret_size = type2size[ret_type->basic_type()];
@@ -858,13 +855,15 @@
} else {
// Value type arguments are not passed by reference: we get an
// argument per field of the value type. Build ValueTypeNodes
// from the value type arguments.
const Type* t = tf->domain_sig()->field_at(i);
- if (t->isa_valuetypeptr() && t->is_valuetypeptr()->klass() != C->env()->___Value_klass()) {
+ if (t->isa_valuetypeptr() && !t->is_valuetypeptr()->is__Value()) {
ciValueKlass* vk = t->is_valuetypeptr()->value_type()->value_klass();
- Node* vt = ValueTypeNode::make(gvn, start, vk, j, true);
+ Node* ctl = map->control();
+ Node* vt = ValueTypeNode::make(gvn, ctl, map->memory(), start, vk, j, true);
+ map->set_control(ctl);
map->init_req(i, gvn.transform(vt));
j += vk->value_arg_slots();
} else {
Node* parm = gvn.transform(new ParmNode(start, j));
map->init_req(i, parm);
@@ -876,11 +875,13 @@
} else {
Node* parm = gvn.transform(new ParmNode(start, i));
// Check if parameter is a value type pointer
if (gvn.type(parm)->isa_valuetypeptr()) {
// Create ValueTypeNode from the oop and replace the parameter
- parm = ValueTypeNode::make(gvn, map->memory(), parm);
+ Node* ctl = map->control();
+ parm = ValueTypeNode::make(gvn, ctl, map->memory(), parm);
+ map->set_control(ctl);
}
map->init_req(i, parm);
// Record all these guys for later GVN.
record_for_igvn(parm);
j++;
@@ -929,11 +930,11 @@
// to the Return node as returned values.
assert(res->is_ValueType(), "what else supports multi value return");
ValueTypeNode* vt = res->as_ValueType();
ret->add_req_batch(NULL, tf()->range_cc()->cnt() - TypeFunc::Parms);
vt->pass_klass(ret, TypeFunc::Parms, kit);
- vt->pass_fields(ret, TypeFunc::Parms+1, kit);
+ vt->pass_fields(ret, TypeFunc::Parms+1, kit, /* assert_allocated */ true);
} else {
ret->add_req(res);
// Note: The second dummy edge is not needed by a ReturnNode.
}
}
@@ -2270,15 +2271,19 @@
}
//------------------------------return_current---------------------------------
// Append current _map to _exit_return
void Parse::return_current(Node* value) {
- if (value != NULL && value->is_ValueType() && !_caller->has_method() &&
- !tf()->returns_value_type_as_fields()) {
- // Returning from root JVMState without multiple returned values,
- // make sure value type is allocated
- value = value->as_ValueType()->allocate(this);
+ if (value != NULL && value->is_ValueType() && !_caller->has_method()) {
+ // Returning a value type from root JVMState
+ if (tf()->returns_value_type_as_fields()) {
+ // Value type is returned as fields, make sure non-flattened value type fields are allocated
+ value = value->as_ValueType()->allocate_fields(this);
+ } else {
+ // Value type is returned as oop, make sure it's allocated
+ value = value->as_ValueType()->allocate(this)->get_oop();
+ }
}
if (RegisterFinalizersAtInit &&
method()->intrinsic_id() == vmIntrinsics::_Object_init) {
call_register_finalizer();
< prev index next >