--- old/src/hotspot/share/opto/output.cpp 2019-03-11 14:26:53.278354504 +0100 +++ new/src/hotspot/share/opto/output.cpp 2019-03-11 14:26:53.066354507 +0100 @@ -71,24 +71,32 @@ 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 @@ -124,6 +132,19 @@ 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 @@ -288,7 +309,9 @@ MachCallNode *mcall = mach->as_MachCall(); // This destination address is NOT PC-relative - mcall->method_set((intptr_t)mcall->entry_point()); + 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(); @@ -726,6 +749,7 @@ 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() ) { @@ -743,9 +767,12 @@ } // 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); } @@ -860,7 +887,7 @@ // 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. @@ -969,6 +996,10 @@ 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; @@ -1233,8 +1264,10 @@ if (is_mcall) { MachCallNode *mcall = mach->as_MachCall(); - // This destination address is NOT PC-relative - mcall->method_set((intptr_t)mcall->entry_point()); + 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();