< prev index next >
src/hotspot/share/opto/output.cpp
Print this page
@@ -69,28 +69,36 @@
Block *broot = _cfg->get_root_block();
const StartNode *start = entry->head()->as_Start();
// Replace StartNode with prolog
- MachPrologNode *prolog = new MachPrologNode();
+ Label verified_entry;
+ MachPrologNode* prolog = new MachPrologNode(&verified_entry);
entry->map_node(prolog, 0);
_cfg->map_node_to_block(prolog, entry);
_cfg->unmap_node_from_block(start); // start is no longer in any block
// Virtual methods need an unverified entry point
-
- if( is_osr_compilation() ) {
- if( PoisonOSREntry ) {
+ if (is_osr_compilation()) {
+ if (PoisonOSREntry) {
// TODO: Should use a ShouldNotReachHereNode...
_cfg->insert( broot, 0, new MachBreakpointNode() );
}
} else {
- if( _method && !_method->flags().is_static() ) {
+ if (_method && !_method->is_static()) {
// Insert unvalidated entry point
- _cfg->insert( broot, 0, new MachUEPNode() );
+ _cfg->insert(broot, 0, new MachUEPNode());
+ }
+ if (_method && _method->has_scalarized_args()) {
+ // Add entry point to unpack all value type arguments
+ _cfg->insert(broot, 0, new MachVEPNode(&verified_entry, /* verified */ true, /* receiver_only */ false));
+ if (!_method->is_static()) {
+ // Add verified/unverified entry points to only unpack value type receiver at interface calls
+ _cfg->insert(broot, 0, new MachVEPNode(&verified_entry, /* verified */ true, /* receiver_only */ true));
+ _cfg->insert(broot, 0, new MachVEPNode(&verified_entry, /* verified */ false, /* receiver_only */ true));
+ }
}
-
}
// Break before main entry point
if ((_method && C->directive()->BreakAtExecuteOption) ||
(OptoBreakpoint && is_method_compilation()) ||
@@ -122,10 +130,23 @@
if (cb == NULL || failing()) {
return;
}
+ if (_method && _method->has_scalarized_args()) {
+ // Compute the offsets of the entry points required by the value type calling convention
+ if (!_method->is_static()) {
+ uint vep_ro_size = ((MachVEPNode*)broot->get_node(0))->size(_regalloc);
+ uint vvep_ro_size = ((MachVEPNode*)broot->get_node(1))->size(_regalloc);
+ _code_offsets.set_value(CodeOffsets::Verified_Value_Entry_RO, vep_ro_size);
+ _code_offsets.set_value(CodeOffsets::Verified_Value_Entry, vep_ro_size + vvep_ro_size);
+ } else {
+ _code_offsets.set_value(CodeOffsets::Entry, -1); // will be patched later
+ _code_offsets.set_value(CodeOffsets::Verified_Value_Entry, 0);
+ }
+ }
+
ScheduleAndBundle();
#ifndef PRODUCT
if (trace_opto_output()) {
tty->print("\n---- After ScheduleAndBundle ----\n");
@@ -286,11 +307,13 @@
reloc_size += CallStubImpl::reloc_call_trampoline();
MachCallNode *mcall = mach->as_MachCall();
// This destination address is NOT PC-relative
+ if (mcall->entry_point() != NULL) {
mcall->method_set((intptr_t)mcall->entry_point());
+ }
if (mcall->is_MachCallJava() && mcall->as_MachCallJava()->_method) {
stub_size += CompiledStaticCall::to_interp_stub_size();
reloc_size += CompiledStaticCall::reloc_to_interp_stub();
#if INCLUDE_AOT
@@ -724,10 +747,11 @@
MachCallNode *mcall;
int safepoint_pc_offset = current_offset;
bool is_method_handle_invoke = false;
bool return_oop = false;
+ bool return_vt = false;
// Add the safepoint in the DebugInfoRecorder
if( !mach->is_MachCall() ) {
mcall = NULL;
debug_info()->add_safepoint(safepoint_pc_offset, sfn->_oop_map);
@@ -741,13 +765,16 @@
is_method_handle_invoke = true;
}
}
// Check if a call returns an object.
- if (mcall->returns_pointer()) {
+ if (mcall->returns_pointer() || mcall->returns_vt()) {
return_oop = true;
}
+ if (mcall->returns_vt()) {
+ return_vt = true;
+ }
safepoint_pc_offset += mcall->ret_addr_offset();
debug_info()->add_safepoint(safepoint_pc_offset, mcall->_oop_map);
}
// Loop over the JVMState list to add scope information
@@ -858,11 +885,11 @@
assert(jvms->bci() >= InvocationEntryBci && jvms->bci() <= 0x10000, "must be a valid or entry BCI");
assert(!jvms->should_reexecute() || depth == max_depth, "reexecute allowed only for the youngest");
// Now we can describe the scope.
methodHandle null_mh;
bool rethrow_exception = false;
- debug_info()->describe_scope(safepoint_pc_offset, null_mh, scope_method, jvms->bci(), jvms->should_reexecute(), rethrow_exception, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
+ debug_info()->describe_scope(safepoint_pc_offset, null_mh, scope_method, jvms->bci(), jvms->should_reexecute(), rethrow_exception, is_method_handle_invoke, return_oop, return_vt, locvals, expvals, monvals);
} // End jvms loop
// Mark the end of the scope set.
debug_info()->end_safepoint(safepoint_pc_offset);
}
@@ -967,10 +994,14 @@
// Compute the byte offset where we can store the deopt pc.
if (fixed_slots() != 0) {
_orig_pc_slot_offset_in_bytes = _regalloc->reg2offset(OptoReg::stack2reg(_orig_pc_slot));
}
+ if (C->needs_stack_repair()) {
+ // Compute the byte offset of the stack increment value
+ _sp_inc_slot_offset_in_bytes = _regalloc->reg2offset(OptoReg::stack2reg(_sp_inc_slot));
+ }
// Compute prolog code size
_method_size = 0;
_frame_slots = OptoReg::reg2stack(_matcher->_old_SP)+_regalloc->_framesize;
#if defined(IA64) && !defined(AIX)
@@ -1231,12 +1262,14 @@
// Remember the start of the last call in a basic block
if (is_mcall) {
MachCallNode *mcall = mach->as_MachCall();
+ if (mcall->entry_point() != NULL) {
// This destination address is NOT PC-relative
mcall->method_set((intptr_t)mcall->entry_point());
+ }
// Save the return address
call_returns[block->_pre_order] = current_offset + mcall->ret_addr_offset();
if (mcall->is_MachCallLeaf()) {
< prev index next >