8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "ci/ciValueKlass.hpp"
27 #include "opto/addnode.hpp"
28 #include "opto/graphKit.hpp"
29 #include "opto/rootnode.hpp"
30 #include "opto/valuetypenode.hpp"
31 #include "opto/phaseX.hpp"
32
33 // Clones the values type to handle control flow merges involving multiple value types.
34 // The inputs are replaced by PhiNodes to represent the merged values for the given region.
35 ValueTypeBaseNode* ValueTypeBaseNode::clone_with_phis(PhaseGVN* gvn, Node* region) {
36 assert(!has_phi_inputs(region), "already cloned with phis");
37 ValueTypeBaseNode* vt = clone()->as_ValueTypeBase();
38
39 // Create a PhiNode for merging the oop values
40 const TypeValueTypePtr* vtptr = value_type_ptr();
41 PhiNode* oop = PhiNode::make(region, vt->get_oop(), vtptr);
42 gvn->set_type(oop, vtptr);
43 vt->set_oop(oop);
44
45 // Create a PhiNode each for merging the field values
46 for (uint i = 0; i < vt->field_count(); ++i) {
47 ciType* type = vt->field_type(i);
177 sobj = gvn->transform(sobj)->as_SafePointScalarObject();
178 gvn->igvn_rehash_node_delayed(sfpt);
179 }
180 return sfpt->replace_edges_in_range(this, sobj, start, end);
181 }
182
183 void ValueTypeBaseNode::make_scalar_in_safepoints(Node* root, PhaseGVN* gvn) {
184 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
185 Node* u = fast_out(i);
186 if (u->is_SafePoint() && (!u->is_Call() || u->as_Call()->has_debug_use(this))) {
187 SafePointNode* sfpt = u->as_SafePoint();
188 Node* in_oop = get_oop();
189 const Type* oop_type = in_oop->bottom_type();
190 assert(Opcode() == Op_ValueTypePtr || TypePtr::NULL_PTR->higher_equal(oop_type), "already heap allocated value type should be linked directly");
191 int nb = make_scalar_in_safepoint(sfpt, root, gvn);
192 --i; imax -= nb;
193 }
194 }
195 }
196
197 ValueTypeNode* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* klass) {
198 // Create a new ValueTypeNode with uninitialized values and NULL oop
199 const TypeValueType* type = TypeValueType::make(klass);
200 return new ValueTypeNode(type, gvn.zerocon(T_VALUETYPE));
201 }
202
203 Node* ValueTypeNode::make_default(PhaseGVN& gvn, ciValueKlass* vk) {
204 // TODO re-use constant oop of pre-allocated default value type here?
205 // Create a new ValueTypeNode with default values
206 ValueTypeNode* vt = ValueTypeNode::make(gvn, vk);
207 for (uint i = 0; i < vt->field_count(); ++i) {
208 ciType* field_type = vt->field_type(i);
209 Node* value = NULL;
210 if (field_type->is_valuetype()) {
211 value = ValueTypeNode::make_default(gvn, field_type->as_value_klass());
212 } else {
213 value = gvn.zerocon(field_type->basic_type());
214 }
215 vt->set_field_value(i, value);
216 }
217 return gvn.transform(vt);
218 }
219
220 Node* ValueTypeNode::make(PhaseGVN& gvn, Node* mem, Node* oop) {
221 // Create and initialize a ValueTypeNode by loading all field
222 // values from a heap-allocated version and also save the oop.
223 const TypeValueType* type = gvn.type(oop)->is_valuetypeptr()->value_type();
224 ValueTypeNode* vt = new ValueTypeNode(type, oop);
225 vt->load(gvn, mem, oop, oop, type->value_klass());
226 assert(vt->is_allocated(&gvn), "value type should be allocated");
227 assert(oop->is_Con() || oop->is_CheckCastPP() || oop->Opcode() == Op_ValueTypePtr || vt->is_loaded(&gvn, type) == oop, "value type should be loaded");
228 return gvn.transform(vt);
229 }
230
231 Node* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* vk, Node* mem, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
232 // Create and initialize a ValueTypeNode by loading all field values from
233 // a flattened value type field at 'holder_offset' or from a value type array.
234 ValueTypeNode* vt = make(gvn, vk);
235 // The value type is flattened into the object without an oop header. Subtract the
236 // offset of the first field to account for the missing header when loading the values.
237 holder_offset -= vk->first_field_offset();
238 vt->load(gvn, mem, obj, ptr, holder, holder_offset);
239 assert(vt->is_loaded(&gvn, vt->type()->isa_valuetype()) != obj, "holder oop should not be used as flattened value type oop");
240 return gvn.transform(vt)->as_ValueType();
241 }
242
243 void ValueTypeNode::load(PhaseGVN& gvn, Node* mem, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
244 // Initialize the value type by loading its field values from
245 // memory and adding the values as input edges to the node.
246 for (uint i = 0; i < field_count(); ++i) {
247 int offset = holder_offset + field_offset(i);
248 ciType* ftype = field_type(i);
249 Node* value = NULL;
250 if (ftype->is_valuetype()) {
251 // Recursively load the flattened value type field
252 value = ValueTypeNode::make(gvn, ftype->as_value_klass(), mem, base, ptr, holder, offset);
253 } else {
254 const Type* con_type = NULL;
255 if (base->is_Con()) {
256 // If the oop to the value type is constant (static final field), we can
257 // also treat the fields as constants because the value type is immutable.
258 const TypeOopPtr* oop_ptr = base->bottom_type()->isa_oopptr();
259 ciObject* constant_oop = oop_ptr->const_oop();
260 ciField* field = holder->get_field_by_offset(offset, false);
261 ciConstant constant = constant_oop->as_instance()->field_value(field);
262 con_type = Type::make_from_constant(constant, /*require_const=*/ true);
263 }
268 // Load field value from memory
269 const Type* base_type = gvn.type(base);
270 const TypePtr* adr_type = NULL;
271 if (base_type->isa_aryptr()) {
272 // In the case of a flattened value type array, each field
273 // has its own slice
274 adr_type = base_type->is_aryptr()->with_field_offset(offset)->add_offset(Type::OffsetBot);
275 } else {
276 ciField* field = holder->get_field_by_offset(offset, false);
277 adr_type = gvn.C->alias_type(field)->adr_type();
278 }
279 Node* adr = gvn.transform(new AddPNode(base, ptr, gvn.MakeConX(offset)));
280 BasicType bt = type2field[ftype->basic_type()];
281 value = LoadNode::make(gvn, NULL, mem, adr, adr_type, Type::get_const_type(ftype), bt, MemNode::unordered);
282 }
283 }
284 set_field_value(i, gvn.transform(value));
285 }
286 }
287
288 Node* ValueTypeNode::is_loaded(PhaseGVN* phase, const TypeValueType* t, Node* base, int holder_offset) {
289 if (field_count() == 0) {
290 assert(t->value_klass() == phase->C->env()->___Value_klass(), "unexpected value type klass");
291 assert(is_allocated(phase), "must be allocated");
292 return get_oop();
293 }
294 for (uint i = 0; i < field_count(); ++i) {
295 int offset = holder_offset + field_offset(i);
296 Node* value = field_value(i);
297 if (value->isa_DecodeN()) {
298 // Skip DecodeN
299 value = value->in(1);
300 }
301 if (value->isa_Load()) {
302 // Check if base and offset of field load matches value type layout
303 intptr_t loffset = 0;
304 Node* lbase = AddPNode::Ideal_base_and_offset(value->in(MemNode::Address), phase, loffset);
305 if (lbase == NULL || (lbase != base && base != NULL) || loffset != offset) {
306 return NULL;
307 } else if (base == NULL) {
550 }
551 }
552 }
553
554 // Remove dead value type allocations by replacing the projection nodes
555 for (uint i = 0; i < dead_allocations.size(); ++i) {
556 CallProjections projs;
557 AllocateNode* alloc = dead_allocations.at(i)->as_Allocate();
558 alloc->extract_projections(&projs, true);
559 // Use lazy_replace to avoid corrupting the dominator tree of PhaseIdealLoop
560 phase->lazy_replace(projs.fallthrough_catchproj, alloc->in(TypeFunc::Control));
561 phase->lazy_replace(projs.fallthrough_memproj, alloc->in(TypeFunc::Memory));
562 phase->lazy_replace(projs.catchall_memproj, phase->C->top());
563 phase->lazy_replace(projs.fallthrough_ioproj, alloc->in(TypeFunc::I_O));
564 phase->lazy_replace(projs.catchall_ioproj, phase->C->top());
565 phase->lazy_replace(projs.catchall_catchproj, phase->C->top());
566 phase->lazy_replace(projs.resproj, phase->C->top());
567 }
568 }
569
570 // When a call returns multiple values, it has several result
571 // projections, one per field. Replacing the result of the call by a
572 // value type node (after late inlining) requires that for each result
573 // projection, we find the corresponding value type field.
574 void ValueTypeNode::replace_call_results(Node* call, Compile* C) {
575 ciValueKlass* vk = value_klass();
576 for (DUIterator_Fast imax, i = call->fast_outs(imax); i < imax; i++) {
577 ProjNode *pn = call->fast_out(i)->as_Proj();
578 uint con = pn->_con;
579 if (con >= TypeFunc::Parms+1) {
580 uint field_nb = con - (TypeFunc::Parms+1);
581 int extra = 0;
582 for (uint j = 0; j < field_nb - extra; j++) {
583 ciField* f = vk->nonstatic_field_at(j);
584 BasicType bt = f->type()->basic_type();
585 if (bt == T_LONG || bt == T_DOUBLE) {
586 extra++;
587 }
588 }
589 ciField* f = vk->nonstatic_field_at(field_nb - extra);
590 Node* field = field_value_by_offset(f->offset(), true);
591
592 C->gvn_replace_by(pn, field);
593 C->initial_gvn()->hash_delete(pn);
594 pn->set_req(0, C->top());
595 --i; --imax;
596 }
597 }
598 }
599
600
601 #ifndef PRODUCT
602
603 void ValueTypeNode::dump_spec(outputStream* st) const {
604 TypeNode::dump_spec(st);
605 }
606
607 #endif
|
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
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 PhiNode* oop = PhiNode::make(region, vt->get_oop(), vtptr);
43 gvn->set_type(oop, vtptr);
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);
178 sobj = gvn->transform(sobj)->as_SafePointScalarObject();
179 gvn->igvn_rehash_node_delayed(sfpt);
180 }
181 return sfpt->replace_edges_in_range(this, sobj, start, end);
182 }
183
184 void ValueTypeBaseNode::make_scalar_in_safepoints(Node* root, PhaseGVN* gvn) {
185 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
186 Node* u = fast_out(i);
187 if (u->is_SafePoint() && (!u->is_Call() || u->as_Call()->has_debug_use(this))) {
188 SafePointNode* sfpt = u->as_SafePoint();
189 Node* in_oop = get_oop();
190 const Type* oop_type = in_oop->bottom_type();
191 assert(Opcode() == Op_ValueTypePtr || TypePtr::NULL_PTR->higher_equal(oop_type), "already heap allocated value type should be linked directly");
192 int nb = make_scalar_in_safepoint(sfpt, root, gvn);
193 --i; imax -= nb;
194 }
195 }
196 }
197
198 void ValueTypeBaseNode::make(PhaseGVN* gvn, Node* n, ValueTypeBaseNode* vt, ciValueKlass* base_vk, int base_offset, int base_input, bool in) {
199 assert(base_offset >= 0, "offset in value type always positive");
200 for (uint i = 0; i < vt->field_count(); i++) {
201 ciType* field_type = vt->field_type(i);
202 int offset = base_offset + vt->field_offset(i);
203 if (field_type->is_valuetype()) {
204 ciValueKlass* embedded_vk = field_type->as_value_klass();
205 ValueTypeNode* embedded_vt = ValueTypeNode::make(*gvn, embedded_vk);
206 ValueTypeBaseNode::make(gvn, n, embedded_vt, base_vk, offset - vt->value_klass()->first_field_offset(), base_input, in);
207 vt->set_field_value(i, gvn->transform(embedded_vt));
208 } else {
209 int j = 0; int extra = 0;
210 for (; j < base_vk->nof_nonstatic_fields(); j++) {
211 ciField* f = base_vk->nonstatic_field_at(j);
212 if (offset == f->offset()) {
213 assert(f->type() == field_type, "inconsistent field type");
214 break;
215 }
216 BasicType bt = f->type()->basic_type();
217 if (bt == T_LONG || bt == T_DOUBLE) {
218 extra++;
219 }
220 }
221 assert(j != base_vk->nof_nonstatic_fields(), "must find");
222 Node* parm = NULL;
223 if (n->is_Start()) {
224 assert(in, "return from start?");
225 parm = gvn->transform(new ParmNode(n->as_Start(), base_input + j + extra));
226 } else {
227 if (in) {
228 assert(n->is_Call(), "nothing else here");
229 parm = n->in(base_input + j + extra);
230 } else {
231 parm = gvn->transform(new ProjNode(n->as_Call(), base_input + j + extra));
232 }
233 }
234 vt->set_field_value(i, parm);
235 // Record all these guys for later GVN.
236 gvn->record_for_igvn(parm);
237 }
238 }
239 }
240
241 void ValueTypeBaseNode::load(PhaseGVN& gvn, Node* mem, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
242 // Initialize the value type by loading its field values from
243 // memory and adding the values as input edges to the node.
244 for (uint i = 0; i < field_count(); ++i) {
245 int offset = holder_offset + field_offset(i);
246 ciType* ftype = field_type(i);
247 Node* value = NULL;
248 if (ftype->is_valuetype()) {
249 // Recursively load the flattened value type field
250 value = ValueTypeNode::make(gvn, ftype->as_value_klass(), mem, base, ptr, holder, offset);
251 } else {
252 const Type* con_type = NULL;
253 if (base->is_Con()) {
254 // If the oop to the value type is constant (static final field), we can
255 // also treat the fields as constants because the value type is immutable.
256 const TypeOopPtr* oop_ptr = base->bottom_type()->isa_oopptr();
257 ciObject* constant_oop = oop_ptr->const_oop();
258 ciField* field = holder->get_field_by_offset(offset, false);
259 ciConstant constant = constant_oop->as_instance()->field_value(field);
260 con_type = Type::make_from_constant(constant, /*require_const=*/ true);
261 }
266 // Load field value from memory
267 const Type* base_type = gvn.type(base);
268 const TypePtr* adr_type = NULL;
269 if (base_type->isa_aryptr()) {
270 // In the case of a flattened value type array, each field
271 // has its own slice
272 adr_type = base_type->is_aryptr()->with_field_offset(offset)->add_offset(Type::OffsetBot);
273 } else {
274 ciField* field = holder->get_field_by_offset(offset, false);
275 adr_type = gvn.C->alias_type(field)->adr_type();
276 }
277 Node* adr = gvn.transform(new AddPNode(base, ptr, gvn.MakeConX(offset)));
278 BasicType bt = type2field[ftype->basic_type()];
279 value = LoadNode::make(gvn, NULL, mem, adr, adr_type, Type::get_const_type(ftype), bt, MemNode::unordered);
280 }
281 }
282 set_field_value(i, gvn.transform(value));
283 }
284 }
285
286 void ValueTypeBaseNode::store_flattened(PhaseGVN* gvn, Node* ctl, MergeMemNode* mem, Node* base, ciValueKlass* holder, int holder_offset) const {
287 // The value type is embedded into the object without an oop header. Subtract the
288 // offset of the first field to account for the missing header when storing the values.
289 holder_offset -= value_klass()->first_field_offset();
290 store(gvn, ctl, mem, base, holder, holder_offset);
291 }
292
293 void ValueTypeBaseNode::store(PhaseGVN* gvn, Node* ctl, MergeMemNode* mem, Node* base, ciValueKlass* holder, int holder_offset) const {
294 if (holder == NULL) {
295 holder = value_klass();
296 }
297 // Write field values to memory
298 for (uint i = 0; i < field_count(); ++i) {
299 int offset = holder_offset + field_offset(i);
300 Node* value = field_value(i);
301 if (value->is_ValueType()) {
302 // Recursively store the flattened value type field
303 value->isa_ValueTypeBase()->store_flattened(gvn, ctl, mem, base, holder, offset);
304 } else {
305 const Type* base_type = gvn->type(base);
306 const TypePtr* adr_type = NULL;
307 if (base_type->isa_aryptr()) {
308 // In the case of a flattened value type array, each field has its own slice
309 adr_type = base_type->is_aryptr()->with_field_offset(offset)->add_offset(Type::OffsetBot);
310 } else {
311 ciField* field = holder->get_field_by_offset(offset, false);
312 adr_type = gvn->C->alias_type(field)->adr_type();
313 }
314 Node* adr = gvn->transform(new AddPNode(base, base, gvn->MakeConX(offset)));
315 BasicType bt = type2field[field_type(i)->basic_type()];
316 uint alias_idx = gvn->C->get_alias_index(adr_type);
317 Node* st = StoreNode::make(*gvn, ctl, mem->memory_at(alias_idx), adr, adr_type, value, bt, MemNode::unordered);
318 mem->set_memory_at(alias_idx, gvn->transform(st));
319 }
320 }
321 }
322
323 // When a call returns multiple values, it has several result
324 // projections, one per field. Replacing the result of the call by a
325 // value type node (after late inlining) requires that for each result
326 // projection, we find the corresponding value type field.
327 void ValueTypeBaseNode::replace_call_results(Node* call, Compile* C) {
328 ciValueKlass* vk = value_klass();
329 for (DUIterator_Fast imax, i = call->fast_outs(imax); i < imax; i++) {
330 ProjNode *pn = call->fast_out(i)->as_Proj();
331 uint con = pn->_con;
332 if (con >= TypeFunc::Parms+1) {
333 uint field_nb = con - (TypeFunc::Parms+1);
334 int extra = 0;
335 for (uint j = 0; j < field_nb - extra; j++) {
336 ciField* f = vk->nonstatic_field_at(j);
337 BasicType bt = f->type()->basic_type();
338 if (bt == T_LONG || bt == T_DOUBLE) {
339 extra++;
340 }
341 }
342 ciField* f = vk->nonstatic_field_at(field_nb - extra);
343 Node* field = field_value_by_offset(f->offset(), true);
344
345 C->gvn_replace_by(pn, field);
346 C->initial_gvn()->hash_delete(pn);
347 pn->set_req(0, C->top());
348 --i; --imax;
349 }
350 }
351 }
352
353 Node* ValueTypeBaseNode::allocate(const Type* type, Node*& ctl, Node*& mem, Node*& io, Node* frameptr, Node*& ex_ctl, Node*& ex_mem, Node*& ex_io, JVMState* jvms, PhaseIterGVN *igvn) {
354 ciValueKlass* vk = type->is_valuetypeptr()->value_type()->value_klass();
355 Node* initial_mem = mem;
356 uint last = igvn->C->unique();
357 MergeMemNode* all_mem = MergeMemNode::make(mem);
358 jint lhelper = vk->layout_helper();
359 assert(lhelper != Klass::_lh_neutral_value, "unsupported");
360
361 AllocateNode* alloc = new AllocateNode(igvn->C,
362 AllocateNode::alloc_type(Type::TOP),
363 ctl,
364 mem,
365 io,
366 igvn->MakeConX(Klass::layout_helper_size_in_bytes(lhelper)),
367 igvn->makecon(TypeKlassPtr::make(vk)),
368 igvn->intcon(0),
369 NULL);
370 alloc->set_req(TypeFunc::FramePtr, frameptr);
371 igvn->C->add_safepoint_edges(alloc, jvms);
372 Node* n = igvn->transform(alloc);
373 assert(n == alloc, "node shouldn't go away");
374
375 ctl = igvn->transform(new ProjNode(alloc, TypeFunc::Control));
376 mem = igvn->transform(new ProjNode(alloc, TypeFunc::Memory, true));
377 all_mem->set_memory_at(Compile::AliasIdxRaw, mem);
378
379 io = igvn->transform(new ProjNode(alloc, TypeFunc::I_O, true));
380 Node* catc = igvn->transform(new CatchNode(ctl, io, 2));
381 Node* norm = igvn->transform(new CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci));
382 Node* excp = igvn->transform(new CatchProjNode(catc, CatchProjNode::catch_all_index, CatchProjNode::no_handler_bci));
383
384 ex_ctl = excp;
385 ex_mem = igvn->transform(all_mem);
386 ex_io = io;
387
388 ctl = norm;
389 mem = igvn->transform(new ProjNode(alloc, TypeFunc::Memory));
390 io = igvn->transform(new ProjNode(alloc, TypeFunc::I_O, false));
391 Node* rawoop = igvn->transform(new ProjNode(alloc, TypeFunc::Parms));
392
393 MemBarNode* membar = MemBarNode::make(igvn->C, Op_Initialize, Compile::AliasIdxRaw, rawoop);
394 membar->set_req(TypeFunc::Control, ctl);
395
396 InitializeNode* init = membar->as_Initialize();
397
398 const TypeOopPtr* oop_type = type->is_oopptr();
399 MergeMemNode* minit_in = MergeMemNode::make(mem);
400 init->set_req(InitializeNode::Memory, minit_in);
401 n = igvn->transform(membar);
402 assert(n == membar, "node shouldn't go away");
403 ctl = igvn->transform(new ProjNode(membar, TypeFunc::Control));
404 mem = igvn->transform(new ProjNode(membar, TypeFunc::Memory));
405
406 MergeMemNode* out_mem_merge = MergeMemNode::make(initial_mem);
407 for (int i = 0, len = vk->nof_nonstatic_fields(); i < len; i++) {
408 ciField* field = vk->nonstatic_field_at(i);
409 if (field->offset() >= TrackedInitializationLimit * HeapWordSize)
410 continue;
411 int fieldidx = igvn->C->alias_type(field)->index();
412 minit_in->set_memory_at(fieldidx, initial_mem);
413 out_mem_merge->set_memory_at(fieldidx, mem);
414 }
415
416 n = igvn->transform(minit_in);
417 assert(n == minit_in, "node shouldn't go away");
418 out_mem_merge->set_memory_at(Compile::AliasIdxRaw, mem);
419
420 Node* javaoop = igvn->transform(new CheckCastPPNode(ctl, rawoop, oop_type));
421 mem = igvn->transform(out_mem_merge);
422
423 return javaoop;
424 }
425
426 ValueTypeNode* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* klass) {
427 // Create a new ValueTypeNode with uninitialized values and NULL oop
428 const TypeValueType* type = TypeValueType::make(klass);
429 return new ValueTypeNode(type, gvn.zerocon(T_VALUETYPE));
430 }
431
432 Node* ValueTypeNode::make_default(PhaseGVN& gvn, ciValueKlass* vk) {
433 // TODO re-use constant oop of pre-allocated default value type here?
434 // Create a new ValueTypeNode with default values
435 ValueTypeNode* vt = ValueTypeNode::make(gvn, vk);
436 for (uint i = 0; i < vt->field_count(); ++i) {
437 ciType* field_type = vt->field_type(i);
438 Node* value = NULL;
439 if (field_type->is_valuetype()) {
440 value = ValueTypeNode::make_default(gvn, field_type->as_value_klass());
441 } else {
442 value = gvn.zerocon(field_type->basic_type());
443 }
444 vt->set_field_value(i, value);
445 }
446 return gvn.transform(vt);
447 }
448
449 Node* ValueTypeNode::make(PhaseGVN& gvn, Node* mem, Node* oop) {
450 // Create and initialize a ValueTypeNode by loading all field
451 // values from a heap-allocated version and also save the oop.
452 const TypeValueType* type = gvn.type(oop)->is_valuetypeptr()->value_type();
453 ValueTypeNode* vt = new ValueTypeNode(type, oop);
454 vt->load(gvn, mem, oop, oop, type->value_klass());
455 assert(vt->is_allocated(&gvn), "value type should be allocated");
456 assert(oop->is_Con() || oop->is_CheckCastPP() || oop->Opcode() == Op_ValueTypePtr || vt->is_loaded(&gvn, type) == oop, "value type should be loaded");
457 return gvn.transform(vt);
458 }
459
460 Node* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* vk, Node* mem, Node* obj, Node* ptr, ciInstanceKlass* holder, int holder_offset) {
461 // Create and initialize a ValueTypeNode by loading all field values from
462 // a flattened value type field at 'holder_offset' or from a value type array.
463 ValueTypeNode* vt = make(gvn, vk);
464 // The value type is flattened into the object without an oop header. Subtract the
465 // offset of the first field to account for the missing header when loading the values.
466 holder_offset -= vk->first_field_offset();
467 vt->load(gvn, mem, obj, ptr, holder, holder_offset);
468 assert(vt->is_loaded(&gvn, vt->type()->isa_valuetype()) != obj, "holder oop should not be used as flattened value type oop");
469 return gvn.transform(vt)->as_ValueType();
470 }
471
472 Node* ValueTypeNode::make(PhaseGVN& gvn, Node* n, ciValueKlass* vk, int base_input, bool in) {
473 ValueTypeNode* vt = ValueTypeNode::make(gvn, vk);
474 ValueTypeBaseNode::make(&gvn, n, vt, vk, 0, base_input, in);
475 return gvn.transform(vt);
476 }
477
478 Node* ValueTypeNode::is_loaded(PhaseGVN* phase, const TypeValueType* t, Node* base, int holder_offset) {
479 if (field_count() == 0) {
480 assert(t->value_klass() == phase->C->env()->___Value_klass(), "unexpected value type klass");
481 assert(is_allocated(phase), "must be allocated");
482 return get_oop();
483 }
484 for (uint i = 0; i < field_count(); ++i) {
485 int offset = holder_offset + field_offset(i);
486 Node* value = field_value(i);
487 if (value->isa_DecodeN()) {
488 // Skip DecodeN
489 value = value->in(1);
490 }
491 if (value->isa_Load()) {
492 // Check if base and offset of field load matches value type layout
493 intptr_t loffset = 0;
494 Node* lbase = AddPNode::Ideal_base_and_offset(value->in(MemNode::Address), phase, loffset);
495 if (lbase == NULL || (lbase != base && base != NULL) || loffset != offset) {
496 return NULL;
497 } else if (base == NULL) {
740 }
741 }
742 }
743
744 // Remove dead value type allocations by replacing the projection nodes
745 for (uint i = 0; i < dead_allocations.size(); ++i) {
746 CallProjections projs;
747 AllocateNode* alloc = dead_allocations.at(i)->as_Allocate();
748 alloc->extract_projections(&projs, true);
749 // Use lazy_replace to avoid corrupting the dominator tree of PhaseIdealLoop
750 phase->lazy_replace(projs.fallthrough_catchproj, alloc->in(TypeFunc::Control));
751 phase->lazy_replace(projs.fallthrough_memproj, alloc->in(TypeFunc::Memory));
752 phase->lazy_replace(projs.catchall_memproj, phase->C->top());
753 phase->lazy_replace(projs.fallthrough_ioproj, alloc->in(TypeFunc::I_O));
754 phase->lazy_replace(projs.catchall_ioproj, phase->C->top());
755 phase->lazy_replace(projs.catchall_catchproj, phase->C->top());
756 phase->lazy_replace(projs.resproj, phase->C->top());
757 }
758 }
759
760
761 #ifndef PRODUCT
762
763 void ValueTypeNode::dump_spec(outputStream* st) const {
764 TypeNode::dump_spec(st);
765 }
766
767 #endif
768
769 ValueTypePtrNode* ValueTypePtrNode::make(PhaseGVN* gvn, CheckCastPPNode* cast) {
770 ciValueKlass* vk = cast->type()->is_valuetypeptr()->value_type()->value_klass();
771 ValueTypePtrNode* vt = new ValueTypePtrNode(vk, gvn->C);
772 assert(cast->in(1)->is_Proj(), "bad graph shape");
773 ValueTypeBaseNode::make(gvn, cast->in(1)->in(0), vt, vk, 0, TypeFunc::Parms+1, false);
774 return vt;
775 }
776
777 ValueTypePtrNode* ValueTypePtrNode::make(PhaseGVN& gvn, Node* mem, Node* oop) {
778 // Create and initialize a ValueTypePtrNode by loading all field
779 // values from a heap-allocated version and also save the oop.
780 ciValueKlass* vk = gvn.type(oop)->is_valuetypeptr()->value_type()->value_klass();
781 ValueTypePtrNode* vtptr = new ValueTypePtrNode(vk, gvn.C);
782 vtptr->set_oop(oop);
783 vtptr->load(gvn, mem, oop, oop, vk);
784 return vtptr;
785 }
|