< prev index next >

src/hotspot/share/c1/c1_GraphBuilder.cpp

Print this page

        

*** 1644,1653 **** --- 1644,1666 ---- default: return new Constant(value); } } + void GraphBuilder::copy_value_content(ciValueKlass* vk, Value src, int src_off, Value dest, int dest_off, + ValueStack* state_before, bool needs_patching) { + for (int i = 0; i < vk->nof_nonstatic_fields(); i++) { + ciField* inner_field = vk->nonstatic_field_at(i); + assert(!inner_field->is_flattened(), "the iteration over nested fields is handled by the loop itself"); + int off = inner_field->offset() - vk->first_field_offset(); + LoadField* load = new LoadField(src, src_off + off, inner_field, false, state_before, needs_patching); + Value replacement = append(load); + StoreField* store = new StoreField(dest, dest_off + off, inner_field, replacement, false, state_before, needs_patching); + append(store); + } + } + void GraphBuilder::access_field(Bytecodes::Code code) { bool will_link; ciField* field = stream()->get_field(will_link); ciInstanceKlass* holder = field->holder(); BasicType field_type = field->type()->basic_type();
*** 1745,1782 **** push(type, append(constant)); } else { if (state_before == NULL) { state_before = copy_state_for_exception(); } ! // Pb with test below, is_flattened() can return true for fields that are not value types ! // (initialization issue of ciField?) ! if (!(field->type()->is_valuetype() && field->is_flattened())) { LoadField* load = new LoadField(obj, offset, field, false, state_before, needs_patching); Value replacement = !needs_patching ? _memory->load(load) : load; if (replacement != load) { assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked"); push(type, replacement); } else { push(type, append(load)); } } else { // flattened field, not optimized solution: re-instantiate the flattened value ciValueKlass* value_klass = field->type()->as_value_klass(); int flattening_offset = field->offset() - value_klass->first_field_offset(); assert(field->type()->is_valuetype(), "Sanity check"); scope()->set_wrote_final(); scope()->set_wrote_fields(); NewValueTypeInstance* new_instance = new NewValueTypeInstance(value_klass, state_before, false); _memory->new_instance(new_instance); apush(append_split(new_instance)); ! for (int i = 0; i < holder->nof_nonstatic_fields(); i++) { ! ciField* inner_field = holder->nonstatic_field_at(i); ! int off = inner_field->offset(); ! LoadField* load = new LoadField(obj, off + flattening_offset, inner_field, false, state_before, needs_patching); ! Value replacement = append(load); ! StoreField* store = new StoreField(new_instance, off, inner_field, replacement, false, state_before, needs_patching); ! append(store); ! } } } break; } case Bytecodes::_putfield: { --- 1758,1789 ---- push(type, append(constant)); } else { if (state_before == NULL) { state_before = copy_state_for_exception(); } ! ! if (!field->is_flattened()) { LoadField* load = new LoadField(obj, offset, field, false, state_before, needs_patching); Value replacement = !needs_patching ? _memory->load(load) : load; if (replacement != load) { assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked"); push(type, replacement); } else { push(type, append(load)); } } else { // flattened field, not optimized solution: re-instantiate the flattened value + assert(field->type()->is_valuetype(), "Sanity check"); ciValueKlass* value_klass = field->type()->as_value_klass(); int flattening_offset = field->offset() - value_klass->first_field_offset(); assert(field->type()->is_valuetype(), "Sanity check"); scope()->set_wrote_final(); scope()->set_wrote_fields(); NewValueTypeInstance* new_instance = new NewValueTypeInstance(value_klass, state_before, false); _memory->new_instance(new_instance); apush(append_split(new_instance)); ! copy_value_content(value_klass, obj, field->offset() , new_instance, value_klass->first_field_offset(), ! state_before, needs_patching); } } break; } case Bytecodes::_putfield: {
*** 1787,1815 **** } if (field->type()->basic_type() == T_BOOLEAN) { Value mask = append(new Constant(new IntConstant(1))); val = append(new LogicOp(Bytecodes::_iand, val, mask)); } ! // Pb with test below, is_flattened() can return true for fields that are not value types ! // (initialization issue of ciField?) <---- FIXME ! if (!(field->type()->is_valuetype() && field->is_flattened())) { StoreField* store = new StoreField(obj, offset, field, val, false, state_before, needs_patching); if (!needs_patching) store = _memory->store(store); if (store != NULL) { append(store); } } else { ciValueKlass* value_klass = field->type()->as_value_klass(); int flattening_offset = field->offset() - value_klass->first_field_offset(); ! for (int i = 0; i < holder->nof_nonstatic_fields(); i++) { ! ciField* inner_field = holder->nonstatic_field_at(i); ! int off = inner_field->offset(); ! LoadField* load = new LoadField(val, off, inner_field, false, state_before, needs_patching); ! Value replacement = append(load); ! StoreField* store = new StoreField(obj, off + flattening_offset, inner_field, replacement, false, state_before, needs_patching); ! append(store); ! } } break; } default: ShouldNotReachHere(); --- 1794,1816 ---- } if (field->type()->basic_type() == T_BOOLEAN) { Value mask = append(new Constant(new IntConstant(1))); val = append(new LogicOp(Bytecodes::_iand, val, mask)); } ! ! if (!field->is_flattened()) { StoreField* store = new StoreField(obj, offset, field, val, false, state_before, needs_patching); if (!needs_patching) store = _memory->store(store); if (store != NULL) { append(store); } } else { + assert(field->type()->is_valuetype(), "Sanity check"); ciValueKlass* value_klass = field->type()->as_value_klass(); int flattening_offset = field->offset() - value_klass->first_field_offset(); ! copy_value_content(value_klass, val, value_klass->first_field_offset(), obj, field->offset(), ! state_before, needs_patching); } break; } default: ShouldNotReachHere();
*** 1849,1874 **** for (int i = 0; i < holder->nof_nonstatic_fields(); i++) { ciField* field = holder->nonstatic_field_at(i); int off = field->offset(); if (field->offset() != offset) { // Only load those fields who are not modified LoadField* load = new LoadField(obj, off, field, false, state_before, needs_patching); Value replacement = append(load); - StoreField* store = new StoreField(new_instance, off, field, replacement, false, state_before, needs_patching); append(store); } } // Field to modify if (field_modify->type()->basic_type() == T_BOOLEAN) { Value mask = append(new Constant(new IntConstant(1))); val = append(new LogicOp(Bytecodes::_iand, val, mask)); } StoreField* store = new StoreField(new_instance, offset, field_modify, val, false, state_before, needs_patching); append(store); } Dependencies* GraphBuilder::dependency_recorder() const { assert(DeoptC1, "need debug information"); return compilation()->dependency_recorder(); --- 1850,1887 ---- for (int i = 0; i < holder->nof_nonstatic_fields(); i++) { ciField* field = holder->nonstatic_field_at(i); int off = field->offset(); if (field->offset() != offset) { + if (field->is_flattened()) { + assert(field->type()->is_valuetype(), "Sanity check"); + assert(field->type()->is_valuetype(), "Only value types can be flattened"); + ciValueKlass* vk = field->type()->as_value_klass(); + copy_value_content(vk, obj, off, new_instance, vk->first_field_offset(), state_before, needs_patching); + } else { // Only load those fields who are not modified LoadField* load = new LoadField(obj, off, field, false, state_before, needs_patching); Value replacement = append(load); StoreField* store = new StoreField(new_instance, off, field, replacement, false, state_before, needs_patching); append(store); } } + } // Field to modify if (field_modify->type()->basic_type() == T_BOOLEAN) { Value mask = append(new Constant(new IntConstant(1))); val = append(new LogicOp(Bytecodes::_iand, val, mask)); } + if (field_modify->is_flattened()) { + assert(field_modify->type()->is_valuetype(), "Only value types can be flattened"); + ciValueKlass* vk = field_modify->type()->as_value_klass(); + copy_value_content(vk, val, vk->first_field_offset(), new_instance, field_modify->offset(), state_before, needs_patching); + } else { StoreField* store = new StoreField(new_instance, offset, field_modify, val, false, state_before, needs_patching); append(store); + } } Dependencies* GraphBuilder::dependency_recorder() const { assert(DeoptC1, "need debug information"); return compilation()->dependency_recorder();
< prev index next >