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 "ci/ciValueKlass.hpp"
26 #include "opto/addnode.hpp"
27 #include "opto/graphKit.hpp"
28 #include "opto/rootnode.hpp"
29 #include "opto/valuetypenode.hpp"
30 #include "opto/phaseX.hpp"
31
32 Node* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* klass) {
33 // Create a new ValueTypeNode with uninitialized values and NULL oop
34 const TypeValueType* type = TypeValueType::make(klass);
35 return new ValueTypeNode(type, gvn.zerocon(T_VALUETYPE));
36 }
37
38 Node* ValueTypeNode::make(PhaseGVN& gvn, Node* mem, Node* oop) {
39 // Create and initialize a ValueTypeNode by loading all field
40 // values from a heap-allocated version and also save the oop.
41 const TypeValueTypePtr* vtptr = gvn.type(oop)->is_valuetypeptr();
42 ValueTypeNode* vt = new ValueTypeNode(vtptr->value_type(), oop);
43 vt->load_values(gvn, mem, vt->value_klass(), oop);
44 return gvn.transform(vt);
45 }
46
47 Node* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* klass, Node* mem, ciInstanceKlass* holder, Node* obj, int field_offset) {
48 // Create and initialize a ValueTypeNode by loading all field
49 // values from a flattened value type field at 'field_offset' in 'obj'.
50 ValueTypeNode* vt = make(gvn, klass)->as_ValueType();
51 // The value type is flattened into the object without an oop header. Subtract the
52 // offset of the first field to account for the missing header when loading the values.
281 }
282
283 void ValueTypeNode::set_field_value(uint index, Node* value) {
284 assert(index < field_count(), "index out of bounds");
285 set_req(Values + index, value);
286 }
287
288 int ValueTypeNode::get_field_offset(uint index) const {
289 assert(index < field_count(), "index out of bounds");
290 return value_klass()->field_offset_by_index(index);
291 }
292
293 ciType* ValueTypeNode::get_field_type(uint index) const {
294 assert(index < field_count(), "index out of bounds");
295 return value_klass()->field_type_by_index(index);
296 }
297
298 void ValueTypeNode::make_scalar_in_safepoints(Compile* C) {
299 const TypeValueTypePtr* res_type = TypeValueTypePtr::make(bottom_type()->isa_valuetype(), TypePtr::NotNull);
300 ciValueKlass* vk = value_klass();
301 uint nfields = vk->field_count();
302 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
303 Node* u = fast_out(i);
304 if (u->is_SafePoint() && (!u->is_Call() || u->as_Call()->has_debug_use(this))) {
305 Node* in_oop = get_oop();
306 const Type* oop_type = in_oop->bottom_type();
307 SafePointNode* sfpt = u->as_SafePoint();
308 JVMState* jvms = sfpt->jvms();
309 int start = jvms->debug_start();
310 int end = jvms->debug_end();
311 if (oop_type->meet(TypePtr::NULL_PTR) != oop_type) {
312 // Replace safepoint edge by oop
313 int nb = sfpt->replace_edges_in_range(this, in_oop, start, end);
314 --i; imax -= nb;
315 } else {
316 // Replace safepoint edge by SafePointScalarObjectNode and add field values
317 assert(jvms != NULL, "missing JVMS");
318 uint first_ind = (sfpt->req() - jvms->scloff());
319 SafePointScalarObjectNode* sobj = new SafePointScalarObjectNode(res_type,
320 #ifdef ASSERT
321 NULL,
322 #endif
323 first_ind, nfields);
324 sobj->init_req(0, C->root());
325 // Iterate over the value type fields in order of increasing
326 // offset and add the field values to the safepoint.
327 for (uint j = 0; j < nfields; ++j) {
328 int offset = vk->nonstatic_field_at(j)->offset();
329 Node* value = get_field_value_by_offset(offset, true /* include flattened value type fields */);
330 sfpt->add_req(value);
331 }
332 jvms->set_endoff(sfpt->req());
333 int nb = sfpt->replace_edges_in_range(this, sobj, start, end);
334 --i; imax -= nb;
335 }
336 }
337 }
338 }
339
340 Node* ValueTypeNode::Ideal(PhaseGVN* phase, bool can_reshape) {
341 // No optimizations for now
342 return NULL;
343 }
344
345 #ifndef PRODUCT
346
347 void ValueTypeNode::dump_spec(outputStream* st) const {
348 TypeNode::dump_spec(st);
349 }
350
351 #endif
|
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 "ci/ciValueKlass.hpp"
26 #include "opto/addnode.hpp"
27 #include "opto/graphKit.hpp"
28 #include "opto/rootnode.hpp"
29 #include "opto/valuetypenode.hpp"
30 #include "opto/phaseX.hpp"
31
32 ValueTypeNode* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* klass) {
33 // Create a new ValueTypeNode with uninitialized values and NULL oop
34 const TypeValueType* type = TypeValueType::make(klass);
35 return new ValueTypeNode(type, gvn.zerocon(T_VALUETYPE));
36 }
37
38 Node* ValueTypeNode::make(PhaseGVN& gvn, Node* mem, Node* oop) {
39 // Create and initialize a ValueTypeNode by loading all field
40 // values from a heap-allocated version and also save the oop.
41 const TypeValueTypePtr* vtptr = gvn.type(oop)->is_valuetypeptr();
42 ValueTypeNode* vt = new ValueTypeNode(vtptr->value_type(), oop);
43 vt->load_values(gvn, mem, vt->value_klass(), oop);
44 return gvn.transform(vt);
45 }
46
47 Node* ValueTypeNode::make(PhaseGVN& gvn, ciValueKlass* klass, Node* mem, ciInstanceKlass* holder, Node* obj, int field_offset) {
48 // Create and initialize a ValueTypeNode by loading all field
49 // values from a flattened value type field at 'field_offset' in 'obj'.
50 ValueTypeNode* vt = make(gvn, klass)->as_ValueType();
51 // The value type is flattened into the object without an oop header. Subtract the
52 // offset of the first field to account for the missing header when loading the values.
281 }
282
283 void ValueTypeNode::set_field_value(uint index, Node* value) {
284 assert(index < field_count(), "index out of bounds");
285 set_req(Values + index, value);
286 }
287
288 int ValueTypeNode::get_field_offset(uint index) const {
289 assert(index < field_count(), "index out of bounds");
290 return value_klass()->field_offset_by_index(index);
291 }
292
293 ciType* ValueTypeNode::get_field_type(uint index) const {
294 assert(index < field_count(), "index out of bounds");
295 return value_klass()->field_type_by_index(index);
296 }
297
298 void ValueTypeNode::make_scalar_in_safepoints(Compile* C) {
299 const TypeValueTypePtr* res_type = TypeValueTypePtr::make(bottom_type()->isa_valuetype(), TypePtr::NotNull);
300 ciValueKlass* vk = value_klass();
301 uint nfields = vk->flattened_field_count();
302 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
303 Node* u = fast_out(i);
304 if (u->is_SafePoint() && (!u->is_Call() || u->as_Call()->has_debug_use(this))) {
305 Node* in_oop = get_oop();
306 const Type* oop_type = in_oop->bottom_type();
307 SafePointNode* sfpt = u->as_SafePoint();
308 JVMState* jvms = sfpt->jvms();
309 int start = jvms->debug_start();
310 int end = jvms->debug_end();
311 if (oop_type->meet(TypePtr::NULL_PTR) != oop_type) {
312 // Replace safepoint edge by oop
313 int nb = sfpt->replace_edges_in_range(this, in_oop, start, end);
314 --i; imax -= nb;
315 } else {
316 // Replace safepoint edge by SafePointScalarObjectNode and add field values
317 assert(jvms != NULL, "missing JVMS");
318 uint first_ind = (sfpt->req() - jvms->scloff());
319 SafePointScalarObjectNode* sobj = new SafePointScalarObjectNode(res_type,
320 #ifdef ASSERT
321 NULL,
322 #endif
323 first_ind, nfields);
324 sobj->init_req(0, C->root());
325 // Iterate over the value type fields in order of increasing
326 // offset and add the field values to the safepoint.
327 for (uint j = 0; j < nfields; ++j) {
328 int offset = vk->nonstatic_field_at(j)->offset();
329 Node* value = get_field_value_by_offset(offset, true /* include flattened value type fields */);
330 sfpt->add_req(value);
331 }
332 jvms->set_endoff(sfpt->req());
333 int nb = sfpt->replace_edges_in_range(this, sobj, start, end);
334 --i; imax -= nb;
335 }
336 }
337 }
338 }
339
340 uint ValueTypeNode::set_arguments_for_java_call(CallJavaNode* call, int base_input, const GraphKit& kit, ciValueKlass* base_vk, int base_offset) {
341 ciValueKlass* vk = value_klass();
342 if (base_vk == NULL) {
343 base_vk = vk;
344 }
345 uint edges = 0;
346 for (uint i = 0; i < field_count(); i++) {
347 ciType* field_type = get_field_type(i);
348 int offset = base_offset + get_field_offset(i) - (base_offset > 0 ? vk->first_field_offset() : 0);
349 Node* arg = get_field_value(i);
350 if (field_type->is_valuetype()) {
351 ciValueKlass* embedded_vk = field_type->as_value_klass();
352 edges += arg->as_ValueType()->set_arguments_for_java_call(call, base_input, kit, base_vk, offset);
353 } else {
354 int j = 0; int extra = 0;
355 for (; j < base_vk->nof_nonstatic_fields(); j++) {
356 ciField* f = base_vk->nonstatic_field_at(j);
357 if (offset == f->offset()) {
358 assert(f->type() == field_type, "inconsistent field type");
359 break;
360 }
361 BasicType bt = f->type()->basic_type();
362 if (bt == T_LONG || bt == T_DOUBLE) {
363 extra++;
364 }
365 }
366 call->init_req(base_input + j + extra, arg);
367 edges++;
368 BasicType bt = field_type->basic_type();
369 if (bt == T_LONG || bt == T_DOUBLE) {
370 call->init_req(base_input + j + extra + 1, kit.top());
371 edges++;
372 }
373 }
374 }
375 return edges;
376 }
377
378 Node* ValueTypeNode::Ideal(PhaseGVN* phase, bool can_reshape) {
379 // No optimizations for now
380 return NULL;
381 }
382
383 #ifndef PRODUCT
384
385 void ValueTypeNode::dump_spec(outputStream* st) const {
386 TypeNode::dump_spec(st);
387 }
388
389 #endif
|