From dfb706a51b7cf593bab660588367280328813127 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Tue, 29 Mar 2022 22:08:20 +0000 Subject: [PATCH 01/19] 8280481: Duplicated static stubs in NMethod Stub Code section --- src/hotspot/cpu/aarch64/aarch64.ad | 8 ++--- src/hotspot/share/asm/codeBuffer.cpp | 41 ++++++++++++++++++++++++ src/hotspot/share/asm/codeBuffer.hpp | 33 +++++++++++++++++++ src/hotspot/share/c1/c1_LIRAssembler.cpp | 7 ++-- src/hotspot/share/ci/ciEnv.cpp | 4 +++ 5 files changed, 85 insertions(+), 8 deletions(-) diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index fe62e2fdf5201..19f3a990a6745 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -3810,12 +3810,8 @@ encode %{ ciEnv::current()->record_failure("CodeCache is full"); return; } - // Emit stub for static call - address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); - if (stub == NULL) { - ciEnv::current()->record_failure("CodeCache is full"); - return; - } + assert(_method->is_loaded(), "must be loaded"); + cbuf.shared_stub_to_interp_for(_method->get_Method(), cbuf.insts_mark()); } _masm.clear_inst_mark(); diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index ddd946d75420e..1a6243e289240 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -24,6 +24,9 @@ #include "precompiled.hpp" #include "asm/codeBuffer.hpp" +#include "asm/macroAssembler.hpp" +#include "ci/ciEnv.hpp" +#include "code/compiledIC.hpp" #include "code/oopRecorder.inline.hpp" #include "compiler/disassembler.hpp" #include "logging/log.hpp" @@ -441,6 +444,7 @@ void CodeBuffer::compute_final_layout(CodeBuffer* dest) const { address buf = dest->_total_start; csize_t buf_offset = 0; assert(dest->_total_size >= total_content_size(), "must be big enough"); + assert(!_finalize_stubs, "non-finalized stubs"); { // not sure why this is here, but why not... @@ -979,6 +983,43 @@ void CodeBuffer::log_section_sizes(const char* name) { } } +static bool emit_shared_stubs_to_interp(const SharedStubToInterpRequests& requests, MacroAssembler* masm) { + LinkedListIterator it(requests.head()); + SharedStubToInterpRequest* request = it.next(); + while (request != NULL) { + address stub = masm->start_a_stub(CompiledStaticCall::to_interp_stub_size()); + if (stub == NULL) { + ciEnv::current()->record_failure("CodeCache is full"); + return false; + } + Method* method = request->shared_method(); + do { + masm->relocate(static_stub_Relocation::spec(request->caller_pc())); + request = it.next(); + } while (request != NULL && request->shared_method() == method); + masm->emit_static_call_stub(); + masm->end_a_stub(); + } + return true; +} + +void CodeBuffer::finalize_stubs() { + MacroAssembler masm(this); + if (!emit_shared_stubs_to_interp(_shared_stub_to_interp_requests, &masm)) { + return; + } + _finalize_stubs = false; +} + +void CodeBuffer::shared_stub_to_interp_for(Method* method, address caller_pc) { + SharedStubToInterpRequest request(method, caller_pc); + auto node = _shared_stub_to_interp_requests.find_node(request); + auto new_node = (node == NULL) ? _shared_stub_to_interp_requests.add(request) + : _shared_stub_to_interp_requests.insert_after(request, node); + assert(new_node != NULL, "sanity"); + _finalize_stubs = true; +} + #ifndef PRODUCT void CodeBuffer::block_comment(ptrdiff_t offset, const char* comment) { if (_collect_comments) { diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index 207be18606752..69d643b202613 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -29,6 +29,7 @@ #include "code/relocInfo.hpp" #include "utilities/align.hpp" #include "utilities/debug.hpp" +#include "utilities/linkedlist.hpp" #include "utilities/macros.hpp" class PhaseCFG; @@ -342,6 +343,28 @@ class Scrubber { }; #endif // ASSERT +// A Java method can have calls of Java methods which can be statically bound. +// Calls of Java mehtods need stubs to the interpreter. Calls sharing the same Java method +// can share a stub to interpreter. +// A SharedStubToInterpRequest describes a request for a shared stub to the interpreter. +class SharedStubToInterpRequest { + private: + Method* _shared_method; + address _caller_pc; + + public: + SharedStubToInterpRequest(Method* method, address caller_pc = NULL) : _shared_method(method), + _caller_pc(caller_pc) {} + + bool equals(const SharedStubToInterpRequest& request) const { + return _shared_method == request._shared_method; + } + + Method* shared_method() { return _shared_method; } + address caller_pc() { return _caller_pc; } +}; +typedef LinkedListImpl SharedStubToInterpRequests; + // A CodeBuffer describes a memory space into which assembly // code is generated. This memory space usually occupies the // interior of a single BufferBlob, but in some cases it may be @@ -414,6 +437,9 @@ class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) { address _last_insn; // used to merge consecutive memory barriers, loads or stores. + SharedStubToInterpRequests _shared_stub_to_interp_requests; // used to collect requests for shared iterpreter stubs + bool _finalize_stubs; // Indicate if we need to finalize stubs to make CodeBuffer final. + #ifndef PRODUCT AsmRemarks _asm_remarks; DbgStrings _dbg_strings; @@ -431,6 +457,7 @@ class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) { _oop_recorder = NULL; _overflow_arena = NULL; _last_insn = NULL; + _finalize_stubs = false; #ifndef PRODUCT _decode_begin = NULL; @@ -682,6 +709,12 @@ class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) { // Log a little info about section usage in the CodeBuffer void log_section_sizes(const char* name); + // Make a set of stubs final. It can create/optimize stubs. + void finalize_stubs(); + + // Request for a shared stub to the interpreter + void shared_stub_to_interp_for(Method* call, address caller_pc); + #ifndef PRODUCT public: // Printing / Decoding diff --git a/src/hotspot/share/c1/c1_LIRAssembler.cpp b/src/hotspot/share/c1/c1_LIRAssembler.cpp index 0ce2485e63216..45f7955b8502f 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.cpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp @@ -456,8 +456,11 @@ void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { // must align calls sites, otherwise they can't be updated atomically align_call(op->code()); - // emit the static call stub stuff out of line - emit_static_call_stub(); + if (op->code() == lir_static_call && op->method()->is_loaded()) { + _masm->code()->shared_stub_to_interp_for(op->method()->get_Method(), pc()); + } else { + emit_static_call_stub(); + } CHECK_BAILOUT(); switch (op->code()) { diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp index 84eb3948f6029..a69e4cb6dce3a 100644 --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp @@ -1117,6 +1117,10 @@ void ciEnv::register_method(ciMethod* target, } #endif + if (!failing()) { + code_buffer->finalize_stubs(); + } + if (failing()) { // While not a true deoptimization, it is a preemptive decompile. MethodData* mdo = method()->method_data(); From 2e59d308ecceef9856d4cf9a701c8d87ba956712 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Wed, 30 Mar 2022 16:57:19 +0000 Subject: [PATCH 02/19] Put code into AArch64 platform part --- .../cpu/aarch64/codeBuffer_aarch64.cpp | 49 +++++++++++++++++++ .../cpu/aarch64/codeBuffer_aarch64.hpp | 5 ++ src/hotspot/cpu/arm/codeBuffer_arm.hpp | 3 ++ src/hotspot/cpu/ppc/codeBuffer_ppc.hpp | 3 ++ src/hotspot/cpu/riscv/codeBuffer_riscv.hpp | 3 ++ src/hotspot/cpu/s390/codeBuffer_s390.hpp | 3 ++ src/hotspot/cpu/x86/codeBuffer_x86.hpp | 3 ++ src/hotspot/cpu/zero/codeBuffer_zero.hpp | 5 ++ src/hotspot/share/asm/codeBuffer.cpp | 26 +--------- src/hotspot/share/c1/c1_LIRAssembler.cpp | 3 +- 10 files changed, 77 insertions(+), 26 deletions(-) create mode 100644 src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp diff --git a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp new file mode 100644 index 0000000000000..ee7804b370fe4 --- /dev/null +++ b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp @@ -0,0 +1,49 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "asm/codeBuffer.hpp" +#include "asm/macroAssembler.hpp" +#include "ci/ciEnv.hpp" +#include "code/compiledIC.hpp" + +bool CodeBuffer::emit_shared_stubs_to_interp() { + MacroAssembler masm(this); + LinkedListIterator it(_shared_stub_to_interp_requests.head()); + SharedStubToInterpRequest* request = it.next(); + while (request != NULL) { + address stub = masm.start_a_stub(CompiledStaticCall::to_interp_stub_size()); + if (stub == NULL) { + ciEnv::current()->record_failure("CodeCache is full"); + return false; + } + Method* method = request->shared_method(); + do { + masm.relocate(static_stub_Relocation::spec(request->caller_pc())); + request = it.next(); + } while (request != NULL && request->shared_method() == method); + masm.emit_static_call_stub(); + masm.end_a_stub(); + } + return true; +} \ No newline at end of file diff --git a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp index 647327f6f0890..1b5326acf628c 100644 --- a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp @@ -28,8 +28,13 @@ private: void pd_initialize() {} + bool emit_shared_stubs_to_interp(); + bool pd_finalize_stubs() { + return emit_shared_stubs_to_interp(); + } public: void flush_bundle(bool start_new_bundle) {} + static bool supports_shared_stubs() { return true; } #endif // CPU_AARCH64_CODEBUFFER_AARCH64_HPP diff --git a/src/hotspot/cpu/arm/codeBuffer_arm.hpp b/src/hotspot/cpu/arm/codeBuffer_arm.hpp index c306e6a6a0743..e992bfed1204c 100644 --- a/src/hotspot/cpu/arm/codeBuffer_arm.hpp +++ b/src/hotspot/cpu/arm/codeBuffer_arm.hpp @@ -27,8 +27,11 @@ private: void pd_initialize() {} + bool emit_shared_stubs_to_interp() { Unimplemented(); return true; } + bool pd_finalize_stubs() { return true; } public: void flush_bundle(bool start_new_bundle) {} + static bool supports_shared_stubs() { return false; } #endif // CPU_ARM_CODEBUFFER_ARM_HPP diff --git a/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp b/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp index 2fb9e5657a821..56061c9a8a2a5 100644 --- a/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp +++ b/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp @@ -28,8 +28,11 @@ private: void pd_initialize() {} + bool emit_shared_stubs_to_interp() { Unimplemented(); return true; } + bool pd_finalize_stubs() { return true; } public: void flush_bundle(bool start_new_bundle) {} + static bool supports_shared_stubs() { return false; } #endif // CPU_PPC_CODEBUFFER_PPC_HPP diff --git a/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp b/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp index 14a68b45026da..001f606c11f55 100644 --- a/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp +++ b/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp @@ -29,8 +29,11 @@ private: void pd_initialize() {} + bool emit_shared_stubs_to_interp() { Unimplemented(); return true; } + bool pd_finalize_stubs() { return true; } public: void flush_bundle(bool start_new_bundle) {} + static bool supports_shared_stubs() { return false; } #endif // CPU_RISCV_CODEBUFFER_RISCV_HPP diff --git a/src/hotspot/cpu/s390/codeBuffer_s390.hpp b/src/hotspot/cpu/s390/codeBuffer_s390.hpp index b1499b037a39e..4b1e8ab14cfee 100644 --- a/src/hotspot/cpu/s390/codeBuffer_s390.hpp +++ b/src/hotspot/cpu/s390/codeBuffer_s390.hpp @@ -28,9 +28,12 @@ private: void pd_initialize() {} + bool emit_shared_stubs_to_interp() { Unimplemented(); return true; } + bool pd_finalize_stubs() { return true; } public: void flush_bundle(bool start_new_bundle) {} + static bool supports_shared_stubs() { return false; } void getCpuData(const CodeBuffer * const cb) {} diff --git a/src/hotspot/cpu/x86/codeBuffer_x86.hpp b/src/hotspot/cpu/x86/codeBuffer_x86.hpp index ae03833595c96..3ee16d151e62e 100644 --- a/src/hotspot/cpu/x86/codeBuffer_x86.hpp +++ b/src/hotspot/cpu/x86/codeBuffer_x86.hpp @@ -27,8 +27,11 @@ private: void pd_initialize() {} + bool emit_shared_stubs_to_interp() { Unimplemented(); return true; } + bool pd_finalize_stubs() { return true; } public: void flush_bundle(bool start_new_bundle) {} + static bool supports_shared_stubs() { return false; } #endif // CPU_X86_CODEBUFFER_X86_HPP diff --git a/src/hotspot/cpu/zero/codeBuffer_zero.hpp b/src/hotspot/cpu/zero/codeBuffer_zero.hpp index f35294be0c12e..9cac37129d8dc 100644 --- a/src/hotspot/cpu/zero/codeBuffer_zero.hpp +++ b/src/hotspot/cpu/zero/codeBuffer_zero.hpp @@ -28,5 +28,10 @@ private: void pd_initialize() {} + bool emit_shared_stubs_to_interp() { Unimplemented(); return true; } + bool pd_finalize_stubs() { return true; } + + public: + static bool supports_shared_stubs() { return false; } #endif // CPU_ZERO_CODEBUFFER_ZERO_HPP diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index 1a6243e289240..71582eaf92352 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -24,9 +24,6 @@ #include "precompiled.hpp" #include "asm/codeBuffer.hpp" -#include "asm/macroAssembler.hpp" -#include "ci/ciEnv.hpp" -#include "code/compiledIC.hpp" #include "code/oopRecorder.inline.hpp" #include "compiler/disassembler.hpp" #include "logging/log.hpp" @@ -983,29 +980,8 @@ void CodeBuffer::log_section_sizes(const char* name) { } } -static bool emit_shared_stubs_to_interp(const SharedStubToInterpRequests& requests, MacroAssembler* masm) { - LinkedListIterator it(requests.head()); - SharedStubToInterpRequest* request = it.next(); - while (request != NULL) { - address stub = masm->start_a_stub(CompiledStaticCall::to_interp_stub_size()); - if (stub == NULL) { - ciEnv::current()->record_failure("CodeCache is full"); - return false; - } - Method* method = request->shared_method(); - do { - masm->relocate(static_stub_Relocation::spec(request->caller_pc())); - request = it.next(); - } while (request != NULL && request->shared_method() == method); - masm->emit_static_call_stub(); - masm->end_a_stub(); - } - return true; -} - void CodeBuffer::finalize_stubs() { - MacroAssembler masm(this); - if (!emit_shared_stubs_to_interp(_shared_stub_to_interp_requests, &masm)) { + if (!pd_finalize_stubs()) { return; } _finalize_stubs = false; diff --git a/src/hotspot/share/c1/c1_LIRAssembler.cpp b/src/hotspot/share/c1/c1_LIRAssembler.cpp index 45f7955b8502f..76cccc11e0340 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.cpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp @@ -456,7 +456,8 @@ void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { // must align calls sites, otherwise they can't be updated atomically align_call(op->code()); - if (op->code() == lir_static_call && op->method()->is_loaded()) { + if (CodeBuffer::supports_shared_stubs() && op->code() == lir_static_call + && op->method()->is_loaded()) { _masm->code()->shared_stub_to_interp_for(op->method()->get_Method(), pc()); } else { emit_static_call_stub(); From 00a31b13bcefe8931063f224cbf8a5a5d02c2a2f Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Wed, 30 Mar 2022 17:22:05 +0000 Subject: [PATCH 03/19] Fix missing precompiled.hpp error --- src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp index ee7804b370fe4..0914db8dfa871 100644 --- a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp @@ -22,6 +22,7 @@ * */ +#include "precompiled.hpp" #include "asm/codeBuffer.hpp" #include "asm/macroAssembler.hpp" #include "ci/ciEnv.hpp" @@ -46,4 +47,4 @@ bool CodeBuffer::emit_shared_stubs_to_interp() { masm.end_a_stub(); } return true; -} \ No newline at end of file +} From 902e78b561a6e10db8162bf80c8e25738b8bcd2c Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Fri, 8 Apr 2022 09:33:40 +0000 Subject: [PATCH 04/19] Add a test and implementation fixes --- src/hotspot/cpu/aarch64/aarch64.ad | 16 +- src/hotspot/share/c1/c1_LIRAssembler.cpp | 10 +- .../sharedstubs/SharedStubToInterpTest.java | 182 ++++++++++++++++++ 3 files changed, 204 insertions(+), 4 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 19f3a990a6745..34b05e92edbb2 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -3810,8 +3810,20 @@ encode %{ ciEnv::current()->record_failure("CodeCache is full"); return; } - assert(_method->is_loaded(), "must be loaded"); - cbuf.shared_stub_to_interp_for(_method->get_Method(), cbuf.insts_mark()); + if (CodeBuffer::supports_shared_stubs() && + _method->is_loaded() && + (!_optimized_virtual || _method->is_final_method())) { + // Postpone creating a stub to the interpreter because + // it might be shared among calls of the same Java method. + cbuf.shared_stub_to_interp_for(_method->get_Method(), cbuf.insts_mark()); + } else { + // Emit stub for static call + address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); + if (stub == NULL) { + ciEnv::current()->record_failure("CodeCache is full"); + return; + } + } } _masm.clear_inst_mark(); diff --git a/src/hotspot/share/c1/c1_LIRAssembler.cpp b/src/hotspot/share/c1/c1_LIRAssembler.cpp index 76cccc11e0340..893e54e3b13cf 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.cpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp @@ -449,6 +449,11 @@ void LIR_Assembler::emit_rtcall(LIR_OpRTCall* op) { rt_call(op->result_opr(), op->addr(), op->arguments(), op->tmp(), op->info()); } +static bool can_use_shared_stub_for(LIR_OpJavaCall* op) { + return CodeBuffer::supports_shared_stubs() && + op->method()->is_loaded() && + (op->code() == lir_static_call || op->method()->is_final_method()); +} void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { verify_oop_map(op->info()); @@ -456,8 +461,9 @@ void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { // must align calls sites, otherwise they can't be updated atomically align_call(op->code()); - if (CodeBuffer::supports_shared_stubs() && op->code() == lir_static_call - && op->method()->is_loaded()) { + if (can_use_shared_stub_for(op)) { + // Postpone creating a stub to the interpreter. + // It might be shared among calls of the same Java method. _masm->code()->shared_stub_to_interp_for(op->method()->get_Method(), pc()); } else { emit_static_call_stub(); diff --git a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java new file mode 100644 index 0000000000000..11952a16fc36d --- /dev/null +++ b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java @@ -0,0 +1,182 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test SharedStubToInterpTest + * @summary Checks that stubs to the interpreter can be shared for static or final method. + * @bug 8280481 + * @library /test/lib + * + * @requires os.arch=="aarch64" + * + * @run driver compiler.sharedstubs.SharedStubToInterpTest c2 StaticMethodTest + * @run driver compiler.sharedstubs.SharedStubToInterpTest c1 StaticMethodTest + * @run driver compiler.sharedstubs.SharedStubToInterpTest c2 FinalClassTest + * @run driver compiler.sharedstubs.SharedStubToInterpTest c1 FinalClassTest + * @run driver compiler.sharedstubs.SharedStubToInterpTest c2 FinalMethodTest + * @run driver compiler.sharedstubs.SharedStubToInterpTest c1 FinalMethodTest + */ + +package compiler.sharedstubs; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.ListIterator; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class SharedStubToInterpTest { + public static void main(String[] args) throws Exception { + String compiler = args[0]; + String testClassName = SharedStubToInterpTest.class.getName() + "$" + args[1]; + ArrayList command = new ArrayList(); + command.add("-XX:+IgnoreUnrecognizedVMOptions"); + command.add("-XX:+UnlockDiagnosticVMOptions"); + if (compiler.equals("c2")) { + command.add("-XX:-TieredCompilation"); + } else if (compiler.equals("c1")) { + command.add("-XX:TieredStopAtLevel=1"); + } else { + throw new RuntimeException("Unknown compiler: " + compiler); + } + command.add("-Xbatch"); + command.add("-XX:CompileCommand=compileonly," + testClassName + "::" + "test"); + command.add("-XX:CompileCommand=dontinline," + testClassName + "::" + "test"); + command.add("-XX:CompileCommand=print," + testClassName + "::" + "test"); + command.add("-XX:CompileCommand=exclude," + testClassName + "::" + "log"); + command.add("-XX:CompileCommand=dontinline," + testClassName + "::" + "log"); + command.add(testClassName); + command.add("a"); + command.add("b"); + command.add("c"); + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(command); + + OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); + + analyzer.shouldHaveExitValue(0); + + System.out.println(analyzer.getOutput()); + + checkOutput(analyzer); + } + + private static String skipTo(Iterator iter, String substring) { + while (iter.hasNext()) { + String nextLine = iter.next(); + if (nextLine.contains(substring)) { + return nextLine; + } + } + return null; + } + + private static void checkOutput(OutputAnalyzer output) { + Iterator iter = output.asLines().listIterator(); + + String match = skipTo(iter, "Compiled method"); + while (match != null && !match.contains("Test::test")) { + match = skipTo(iter, "Compiled method"); + } + if (match == null) { + throw new RuntimeException("Missing compiler output for the method 'test'"); + } + + // Shared static stubs are put after Deopt Handler Code. + match = skipTo(iter, "[Deopt Handler Code]"); + if (match == null) { + throw new RuntimeException("The start of Deopt Handler Code not found"); + } + int foundStaticStubs = 0; + while (iter.hasNext()) { + if (iter.next().contains("{static_stub}")) { + foundStaticStubs += 1; + } + } + + final int expectedStaticStubs = 1; + if (foundStaticStubs != expectedStaticStubs) { + throw new RuntimeException("Found static stubs: " + foundStaticStubs + "; Expected static stubs: " + expectedStaticStubs); + } + } + + public static class StaticMethodTest { + static void log(int i) { + } + + static void test(int i, String[] args) { + if (i % args.length == 0) { + log(i); + } else { + log(i); + } + } + + public static void main(String[] args) { + for (int i = 1; i < 50_000; ++i) { + test(i, args); + } + } + } + + public static final class FinalClassTest { + void log(int i) { + } + + void test(int i, String[] args) { + if (i % args.length == 0) { + log(i); + } else { + log(i); + } + } + + public static void main(String[] args) { + FinalClassTest tFC = new FinalClassTest(); + for (int i = 1; i < 50_000; ++i) { + tFC.test(i,args); + } + } + } + + public static class FinalMethodTest { + final void log(int i) { + } + + void test(int i, String[] args) { + if (i % args.length == 0) { + log(i); + } else { + log(i); + } + } + + public static void main(String[] args) { + FinalMethodTest tFM = new FinalMethodTest(); + for (int i = 1; i < 50_000; ++i) { + tFM.test(i,args); + } + } + } +} From 107efe0879447a6f1978c7f82f8897991af0ef50 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Fri, 8 Apr 2022 20:09:45 +0000 Subject: [PATCH 05/19] Resolve merge conflict in x86_32.ad --- src/hotspot/cpu/x86/codeBuffer_x86.cpp | 50 +++++++++++++++++++ src/hotspot/cpu/x86/codeBuffer_x86.hpp | 8 +-- src/hotspot/cpu/x86/compiledIC_x86.cpp | 5 +- src/hotspot/cpu/x86/macroAssembler_x86.cpp | 7 +++ src/hotspot/cpu/x86/macroAssembler_x86.hpp | 2 + src/hotspot/cpu/x86/x86_32.ad | 19 +++++-- src/hotspot/cpu/x86/x86_64.ad | 18 +++++-- .../sharedstubs/SharedStubToInterpTest.java | 4 +- 8 files changed, 94 insertions(+), 19 deletions(-) create mode 100644 src/hotspot/cpu/x86/codeBuffer_x86.cpp diff --git a/src/hotspot/cpu/x86/codeBuffer_x86.cpp b/src/hotspot/cpu/x86/codeBuffer_x86.cpp new file mode 100644 index 0000000000000..6f49b54bd7df2 --- /dev/null +++ b/src/hotspot/cpu/x86/codeBuffer_x86.cpp @@ -0,0 +1,50 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "asm/codeBuffer.hpp" +#include "asm/macroAssembler.hpp" +#include "ci/ciEnv.hpp" +#include "code/compiledIC.hpp" + +bool CodeBuffer::emit_shared_stubs_to_interp() { + MacroAssembler masm(this); + LinkedListIterator it(_shared_stub_to_interp_requests.head()); + SharedStubToInterpRequest* request = it.next(); + while (request != NULL) { + address stub = masm.start_a_stub(CompiledStaticCall::to_interp_stub_size()); + if (stub == NULL) { + ciEnv::current()->record_failure("CodeCache is full"); + return false; + } + Method* method = request->shared_method(); + do { + masm.relocate(static_stub_Relocation::spec(request->caller_pc()), Assembler::imm_operand); + request = it.next(); + } while (request != NULL && request->shared_method() == method); + masm.emit_static_call_stub(); + masm.end_a_stub(); + } + return true; +} \ No newline at end of file diff --git a/src/hotspot/cpu/x86/codeBuffer_x86.hpp b/src/hotspot/cpu/x86/codeBuffer_x86.hpp index 3ee16d151e62e..729325caf9a5e 100644 --- a/src/hotspot/cpu/x86/codeBuffer_x86.hpp +++ b/src/hotspot/cpu/x86/codeBuffer_x86.hpp @@ -27,11 +27,13 @@ private: void pd_initialize() {} - bool emit_shared_stubs_to_interp() { Unimplemented(); return true; } - bool pd_finalize_stubs() { return true; } + bool emit_shared_stubs_to_interp(); + bool pd_finalize_stubs() { + return emit_shared_stubs_to_interp(); + } public: void flush_bundle(bool start_new_bundle) {} - static bool supports_shared_stubs() { return false; } + static bool supports_shared_stubs() { return true; } #endif // CPU_X86_CODEBUFFER_X86_HPP diff --git a/src/hotspot/cpu/x86/compiledIC_x86.cpp b/src/hotspot/cpu/x86/compiledIC_x86.cpp index e898e523c0fe9..d9d97d75033e0 100644 --- a/src/hotspot/cpu/x86/compiledIC_x86.cpp +++ b/src/hotspot/cpu/x86/compiledIC_x86.cpp @@ -55,10 +55,7 @@ address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) } // Static stub relocation stores the instruction address of the call. __ relocate(static_stub_Relocation::spec(mark), Assembler::imm_operand); - // Static stub relocation also tags the Method* in the code-stream. - __ mov_metadata(rbx, (Metadata*) NULL); // Method is zapped till fixup time. - // This is recognized as unresolved by relocs/nativeinst/ic code. - __ jump(RuntimeAddress(__ pc())); + __ emit_static_call_stub(); assert(__ pc() - base <= to_interp_stub_size(), "wrong stub size"); diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index bca825468ff04..1417f77b73282 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -1328,6 +1328,13 @@ void MacroAssembler::ic_call(address entry, jint method_index) { call(AddressLiteral(entry, rh)); } +void MacroAssembler::emit_static_call_stub() { + // Static stub relocation also tags the Method* in the code-stream. + mov_metadata(rbx, (Metadata*) NULL); // Method is zapped till fixup time. + // This is recognized as unresolved by relocs/nativeinst/ic code. + jump(RuntimeAddress(pc())); +} + // Implementation of call_VM versions void MacroAssembler::call_VM(Register oop_result, diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp index 54d1a0c2c6948..6dc3baebe8314 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp @@ -865,6 +865,8 @@ class MacroAssembler: public Assembler { // Emit the CompiledIC call idiom void ic_call(address entry, jint method_index = 0); + void emit_static_call_stub(); + // Jumps // NOTE: these jumps transfer to the effective address of dst NOT diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad index dbbfb7c92603f..21c5a8b7e4020 100644 --- a/src/hotspot/cpu/x86/x86_32.ad +++ b/src/hotspot/cpu/x86/x86_32.ad @@ -1813,11 +1813,20 @@ encode %{ emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4), rspec, RELOC_DISP32); __ post_call_nop(); - // Emit stubs for static call. - address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); - if (stub == NULL) { - ciEnv::current()->record_failure("CodeCache is full"); - return; + address mark = cbuf.insts_mark(); + if (CodeBuffer::supports_shared_stubs() && + _method->is_loaded() && + (!_optimized_virtual || _method->is_final_method())) { + // Postpone creating a stub to the interpreter because + // it might be shared among calls of the same Java method. + cbuf.shared_stub_to_interp_for(_method->get_Method(), mark); + } else { + // Emit stubs for static call. + address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); + if (stub == NULL) { + ciEnv::current()->record_failure("CodeCache is full"); + return; + } } } %} diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 8e7c04f4d1e55..8a11685cc99e1 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -2168,12 +2168,20 @@ encode %{ : static_call_Relocation::spec(method_index); emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), rspec, RELOC_DISP32); - // Emit stubs for static call. address mark = cbuf.insts_mark(); - address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); - if (stub == NULL) { - ciEnv::current()->record_failure("CodeCache is full"); - return; + if (CodeBuffer::supports_shared_stubs() && + _method->is_loaded() && + (!_optimized_virtual || _method->is_final_method())) { + // Postpone creating a stub to the interpreter because + // it might be shared among calls of the same Java method. + cbuf.shared_stub_to_interp_for(_method->get_Method(), mark); + } else { + // Emit stubs for static call. + address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); + if (stub == NULL) { + ciEnv::current()->record_failure("CodeCache is full"); + return; + } } } _masm.clear_inst_mark(); diff --git a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java index 11952a16fc36d..9f35fb53f44f0 100644 --- a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java +++ b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java @@ -28,7 +28,7 @@ * @bug 8280481 * @library /test/lib * - * @requires os.arch=="aarch64" + * @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="i386" | os.arch=="x86" | os.arch=="aarch64" * * @run driver compiler.sharedstubs.SharedStubToInterpTest c2 StaticMethodTest * @run driver compiler.sharedstubs.SharedStubToInterpTest c1 StaticMethodTest @@ -104,7 +104,7 @@ private static void checkOutput(OutputAnalyzer output) { } // Shared static stubs are put after Deopt Handler Code. - match = skipTo(iter, "[Deopt Handler Code]"); + match = skipTo(iter, "{runtime_call DeoptimizationBlob}"); if (match == null) { throw new RuntimeException("The start of Deopt Handler Code not found"); } From 22df6e69a73c4c3a8636cf073cddf30e28e06905 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Mon, 11 Apr 2022 14:00:10 +0000 Subject: [PATCH 06/19] Refactor code to be shared with aarch64 --- src/hotspot/cpu/x86/codeBuffer_x86.cpp | 27 ++------- src/hotspot/cpu/x86/codeBuffer_x86.hpp | 5 +- src/hotspot/share/asm/codeBuffer.inline.hpp | 61 +++++++++++++++++++++ 3 files changed, 66 insertions(+), 27 deletions(-) create mode 100644 src/hotspot/share/asm/codeBuffer.inline.hpp diff --git a/src/hotspot/cpu/x86/codeBuffer_x86.cpp b/src/hotspot/cpu/x86/codeBuffer_x86.cpp index 6f49b54bd7df2..3c406ed1b198e 100644 --- a/src/hotspot/cpu/x86/codeBuffer_x86.cpp +++ b/src/hotspot/cpu/x86/codeBuffer_x86.cpp @@ -23,28 +23,9 @@ */ #include "precompiled.hpp" -#include "asm/codeBuffer.hpp" +#include "asm/codeBuffer.inline.hpp" #include "asm/macroAssembler.hpp" -#include "ci/ciEnv.hpp" -#include "code/compiledIC.hpp" -bool CodeBuffer::emit_shared_stubs_to_interp() { - MacroAssembler masm(this); - LinkedListIterator it(_shared_stub_to_interp_requests.head()); - SharedStubToInterpRequest* request = it.next(); - while (request != NULL) { - address stub = masm.start_a_stub(CompiledStaticCall::to_interp_stub_size()); - if (stub == NULL) { - ciEnv::current()->record_failure("CodeCache is full"); - return false; - } - Method* method = request->shared_method(); - do { - masm.relocate(static_stub_Relocation::spec(request->caller_pc()), Assembler::imm_operand); - request = it.next(); - } while (request != NULL && request->shared_method() == method); - masm.emit_static_call_stub(); - masm.end_a_stub(); - } - return true; -} \ No newline at end of file +bool CodeBuffer::pd_finalize_stubs() { + return emit_shared_stubs_to_interp(this, _shared_stub_to_interp_requests); +} diff --git a/src/hotspot/cpu/x86/codeBuffer_x86.hpp b/src/hotspot/cpu/x86/codeBuffer_x86.hpp index 729325caf9a5e..2069f20ac2f3e 100644 --- a/src/hotspot/cpu/x86/codeBuffer_x86.hpp +++ b/src/hotspot/cpu/x86/codeBuffer_x86.hpp @@ -27,10 +27,7 @@ private: void pd_initialize() {} - bool emit_shared_stubs_to_interp(); - bool pd_finalize_stubs() { - return emit_shared_stubs_to_interp(); - } + bool pd_finalize_stubs(); public: void flush_bundle(bool start_new_bundle) {} diff --git a/src/hotspot/share/asm/codeBuffer.inline.hpp b/src/hotspot/share/asm/codeBuffer.inline.hpp new file mode 100644 index 0000000000000..4361717794126 --- /dev/null +++ b/src/hotspot/share/asm/codeBuffer.inline.hpp @@ -0,0 +1,61 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_ASM_CODEBUFFER_INLINE_HPP +#define SHARE_ASM_CODEBUFFER_INLINE_HPP + +#include "asm/codeBuffer.hpp" +#include "ci/ciEnv.hpp" +#include "code/compiledIC.hpp" + +template +bool emit_shared_stubs_to_interp(CodeBuffer* cb, const SharedStubToInterpRequests& shared_stub_to_interp_requests) { + MacroAssembler masm(cb); + LinkedListIterator it(shared_stub_to_interp_requests.head()); + SharedStubToInterpRequest* request = it.next(); + int relocations_created = 0; + while (request != NULL) { + address stub = masm.start_a_stub(CompiledStaticCall::to_interp_stub_size()); + if (stub == NULL) { + ciEnv::current()->record_failure("CodeCache is full"); + return false; + } + Method* method = request->shared_method(); + do { + masm.relocate(static_stub_Relocation::spec(request->caller_pc()), relocate_format); + request = it.next(); + ++relocations_created; + } while (request != NULL && request->shared_method() == method); + masm.emit_static_call_stub(); + masm.end_a_stub(); + } + + if (relocations_created > 1 && UseNewCode) { + tty->print_cr("Requests %d", (int)shared_stub_to_interp_requests.size()); + tty->print_cr("Saved %d", (relocations_created-1)*CompiledStaticCall::to_interp_stub_size()); + } + return true; +} + +#endif // SHARE_ASM_CODEBUFFER_INLINE_HPP From 1c8b80308981cba66841be384f901c9be1adf9e5 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Mon, 11 Apr 2022 16:52:19 +0000 Subject: [PATCH 07/19] Add UseSharedStubs option --- src/hotspot/cpu/aarch64/aarch64.ad | 3 +-- .../cpu/aarch64/codeBuffer_aarch64.cpp | 25 +++---------------- .../cpu/aarch64/codeBuffer_aarch64.hpp | 6 +---- src/hotspot/cpu/arm/codeBuffer_arm.hpp | 2 -- src/hotspot/cpu/ppc/codeBuffer_ppc.hpp | 2 -- src/hotspot/cpu/riscv/codeBuffer_riscv.hpp | 2 -- src/hotspot/cpu/s390/codeBuffer_s390.hpp | 2 -- src/hotspot/cpu/x86/codeBuffer_x86.hpp | 1 - src/hotspot/cpu/x86/x86_32.ad | 3 +-- src/hotspot/cpu/x86/x86_64.ad | 3 +-- src/hotspot/cpu/zero/codeBuffer_zero.hpp | 4 --- src/hotspot/share/c1/c1_LIRAssembler.cpp | 2 +- src/hotspot/share/runtime/globals.hpp | 3 +++ .../sharedstubs/SharedStubToInterpTest.java | 1 + 14 files changed, 12 insertions(+), 47 deletions(-) diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 34b05e92edbb2..d3aa95a0f82a2 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -3810,8 +3810,7 @@ encode %{ ciEnv::current()->record_failure("CodeCache is full"); return; } - if (CodeBuffer::supports_shared_stubs() && - _method->is_loaded() && + if (UseSharedStubs && _method->is_loaded() && (!_optimized_virtual || _method->is_final_method())) { // Postpone creating a stub to the interpreter because // it might be shared among calls of the same Java method. diff --git a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp index 0914db8dfa871..4257782fdc2cb 100644 --- a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp @@ -23,28 +23,9 @@ */ #include "precompiled.hpp" -#include "asm/codeBuffer.hpp" +#include "asm/codeBuffer.inline.hpp" #include "asm/macroAssembler.hpp" -#include "ci/ciEnv.hpp" -#include "code/compiledIC.hpp" -bool CodeBuffer::emit_shared_stubs_to_interp() { - MacroAssembler masm(this); - LinkedListIterator it(_shared_stub_to_interp_requests.head()); - SharedStubToInterpRequest* request = it.next(); - while (request != NULL) { - address stub = masm.start_a_stub(CompiledStaticCall::to_interp_stub_size()); - if (stub == NULL) { - ciEnv::current()->record_failure("CodeCache is full"); - return false; - } - Method* method = request->shared_method(); - do { - masm.relocate(static_stub_Relocation::spec(request->caller_pc())); - request = it.next(); - } while (request != NULL && request->shared_method() == method); - masm.emit_static_call_stub(); - masm.end_a_stub(); - } - return true; +bool CodeBuffer::pd_finalize_stubs() { + return emit_shared_stubs_to_interp(this, _shared_stub_to_interp_requests); } diff --git a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp index 1b5326acf628c..104eeccc7a1eb 100644 --- a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp @@ -28,13 +28,9 @@ private: void pd_initialize() {} - bool emit_shared_stubs_to_interp(); - bool pd_finalize_stubs() { - return emit_shared_stubs_to_interp(); - } + bool pd_finalize_stubs(); public: void flush_bundle(bool start_new_bundle) {} - static bool supports_shared_stubs() { return true; } #endif // CPU_AARCH64_CODEBUFFER_AARCH64_HPP diff --git a/src/hotspot/cpu/arm/codeBuffer_arm.hpp b/src/hotspot/cpu/arm/codeBuffer_arm.hpp index e992bfed1204c..375428ca86eeb 100644 --- a/src/hotspot/cpu/arm/codeBuffer_arm.hpp +++ b/src/hotspot/cpu/arm/codeBuffer_arm.hpp @@ -27,11 +27,9 @@ private: void pd_initialize() {} - bool emit_shared_stubs_to_interp() { Unimplemented(); return true; } bool pd_finalize_stubs() { return true; } public: void flush_bundle(bool start_new_bundle) {} - static bool supports_shared_stubs() { return false; } #endif // CPU_ARM_CODEBUFFER_ARM_HPP diff --git a/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp b/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp index 56061c9a8a2a5..a71b573381745 100644 --- a/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp +++ b/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp @@ -28,11 +28,9 @@ private: void pd_initialize() {} - bool emit_shared_stubs_to_interp() { Unimplemented(); return true; } bool pd_finalize_stubs() { return true; } public: void flush_bundle(bool start_new_bundle) {} - static bool supports_shared_stubs() { return false; } #endif // CPU_PPC_CODEBUFFER_PPC_HPP diff --git a/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp b/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp index 001f606c11f55..7a69cf8c261b4 100644 --- a/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp +++ b/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp @@ -29,11 +29,9 @@ private: void pd_initialize() {} - bool emit_shared_stubs_to_interp() { Unimplemented(); return true; } bool pd_finalize_stubs() { return true; } public: void flush_bundle(bool start_new_bundle) {} - static bool supports_shared_stubs() { return false; } #endif // CPU_RISCV_CODEBUFFER_RISCV_HPP diff --git a/src/hotspot/cpu/s390/codeBuffer_s390.hpp b/src/hotspot/cpu/s390/codeBuffer_s390.hpp index 4b1e8ab14cfee..5dcd6c249db88 100644 --- a/src/hotspot/cpu/s390/codeBuffer_s390.hpp +++ b/src/hotspot/cpu/s390/codeBuffer_s390.hpp @@ -28,12 +28,10 @@ private: void pd_initialize() {} - bool emit_shared_stubs_to_interp() { Unimplemented(); return true; } bool pd_finalize_stubs() { return true; } public: void flush_bundle(bool start_new_bundle) {} - static bool supports_shared_stubs() { return false; } void getCpuData(const CodeBuffer * const cb) {} diff --git a/src/hotspot/cpu/x86/codeBuffer_x86.hpp b/src/hotspot/cpu/x86/codeBuffer_x86.hpp index 2069f20ac2f3e..7a8fae033fd40 100644 --- a/src/hotspot/cpu/x86/codeBuffer_x86.hpp +++ b/src/hotspot/cpu/x86/codeBuffer_x86.hpp @@ -31,6 +31,5 @@ public: void flush_bundle(bool start_new_bundle) {} - static bool supports_shared_stubs() { return true; } #endif // CPU_X86_CODEBUFFER_X86_HPP diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad index 21c5a8b7e4020..bffabf0228fd7 100644 --- a/src/hotspot/cpu/x86/x86_32.ad +++ b/src/hotspot/cpu/x86/x86_32.ad @@ -1814,8 +1814,7 @@ encode %{ rspec, RELOC_DISP32); __ post_call_nop(); address mark = cbuf.insts_mark(); - if (CodeBuffer::supports_shared_stubs() && - _method->is_loaded() && + if (UseSharedStubs && _method->is_loaded() && (!_optimized_virtual || _method->is_final_method())) { // Postpone creating a stub to the interpreter because // it might be shared among calls of the same Java method. diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 8a11685cc99e1..c143c2a33add5 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -2169,8 +2169,7 @@ encode %{ emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), rspec, RELOC_DISP32); address mark = cbuf.insts_mark(); - if (CodeBuffer::supports_shared_stubs() && - _method->is_loaded() && + if (UseSharedStubs && _method->is_loaded() && (!_optimized_virtual || _method->is_final_method())) { // Postpone creating a stub to the interpreter because // it might be shared among calls of the same Java method. diff --git a/src/hotspot/cpu/zero/codeBuffer_zero.hpp b/src/hotspot/cpu/zero/codeBuffer_zero.hpp index 9cac37129d8dc..82831e51baaa1 100644 --- a/src/hotspot/cpu/zero/codeBuffer_zero.hpp +++ b/src/hotspot/cpu/zero/codeBuffer_zero.hpp @@ -28,10 +28,6 @@ private: void pd_initialize() {} - bool emit_shared_stubs_to_interp() { Unimplemented(); return true; } bool pd_finalize_stubs() { return true; } - public: - static bool supports_shared_stubs() { return false; } - #endif // CPU_ZERO_CODEBUFFER_ZERO_HPP diff --git a/src/hotspot/share/c1/c1_LIRAssembler.cpp b/src/hotspot/share/c1/c1_LIRAssembler.cpp index 893e54e3b13cf..e3ad26194f274 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.cpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp @@ -450,7 +450,7 @@ void LIR_Assembler::emit_rtcall(LIR_OpRTCall* op) { } static bool can_use_shared_stub_for(LIR_OpJavaCall* op) { - return CodeBuffer::supports_shared_stubs() && + return UseSharedStubs && op->method()->is_loaded() && (op->code() == lir_static_call || op->method()->is_final_method()); } diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index 69c16b244dc92..fe4645be713eb 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -2054,6 +2054,9 @@ const intx ObjectAlignmentInBytes = 8; \ develop(bool, TraceOptimizedUpcallStubs, false, \ "Trace optimized upcall stub generation") \ + product(bool, UseSharedStubs, false, DIAGNOSTIC, \ + "Allow sharing stubs whether it is possible") \ + \ // end of RUNTIME_FLAGS diff --git a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java index 9f35fb53f44f0..d5232df30aea8 100644 --- a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java +++ b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java @@ -61,6 +61,7 @@ public static void main(String[] args) throws Exception { throw new RuntimeException("Unknown compiler: " + compiler); } command.add("-Xbatch"); + command.add("-XX:+UseSharedStubs"); command.add("-XX:CompileCommand=compileonly," + testClassName + "::" + "test"); command.add("-XX:CompileCommand=dontinline," + testClassName + "::" + "test"); command.add("-XX:CompileCommand=print," + testClassName + "::" + "test"); From 475968b931957002fa0c9ca1706986049e86805d Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Mon, 11 Apr 2022 17:57:30 +0000 Subject: [PATCH 08/19] Use array for SharedStubToInterpRequests to be able to sort --- .../cpu/aarch64/codeBuffer_aarch64.cpp | 2 +- src/hotspot/cpu/x86/codeBuffer_x86.cpp | 2 +- src/hotspot/share/asm/codeBuffer.cpp | 5 +--- src/hotspot/share/asm/codeBuffer.hpp | 14 ++++----- src/hotspot/share/asm/codeBuffer.inline.hpp | 30 +++++++++++++------ 5 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp index 4257782fdc2cb..78b69aecba06a 100644 --- a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp @@ -27,5 +27,5 @@ #include "asm/macroAssembler.hpp" bool CodeBuffer::pd_finalize_stubs() { - return emit_shared_stubs_to_interp(this, _shared_stub_to_interp_requests); + return emit_shared_stubs_to_interp(this, &_shared_stub_to_interp_requests); } diff --git a/src/hotspot/cpu/x86/codeBuffer_x86.cpp b/src/hotspot/cpu/x86/codeBuffer_x86.cpp index 3c406ed1b198e..1e6ef09003277 100644 --- a/src/hotspot/cpu/x86/codeBuffer_x86.cpp +++ b/src/hotspot/cpu/x86/codeBuffer_x86.cpp @@ -27,5 +27,5 @@ #include "asm/macroAssembler.hpp" bool CodeBuffer::pd_finalize_stubs() { - return emit_shared_stubs_to_interp(this, _shared_stub_to_interp_requests); + return emit_shared_stubs_to_interp(this, &_shared_stub_to_interp_requests); } diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index 71582eaf92352..d5ef305fffd12 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -989,10 +989,7 @@ void CodeBuffer::finalize_stubs() { void CodeBuffer::shared_stub_to_interp_for(Method* method, address caller_pc) { SharedStubToInterpRequest request(method, caller_pc); - auto node = _shared_stub_to_interp_requests.find_node(request); - auto new_node = (node == NULL) ? _shared_stub_to_interp_requests.add(request) - : _shared_stub_to_interp_requests.insert_after(request, node); - assert(new_node != NULL, "sanity"); + _shared_stub_to_interp_requests.push(request); _finalize_stubs = true; } diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index 69d643b202613..9160d11f7205d 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -29,7 +29,7 @@ #include "code/relocInfo.hpp" #include "utilities/align.hpp" #include "utilities/debug.hpp" -#include "utilities/linkedlist.hpp" +#include "utilities/growableArray.hpp" #include "utilities/macros.hpp" class PhaseCFG; @@ -353,17 +353,13 @@ class SharedStubToInterpRequest { address _caller_pc; public: - SharedStubToInterpRequest(Method* method, address caller_pc = NULL) : _shared_method(method), + SharedStubToInterpRequest(Method* method = NULL, address caller_pc = NULL) : _shared_method(method), _caller_pc(caller_pc) {} - bool equals(const SharedStubToInterpRequest& request) const { - return _shared_method == request._shared_method; - } - - Method* shared_method() { return _shared_method; } - address caller_pc() { return _caller_pc; } + Method* shared_method() const { return _shared_method; } + address caller_pc() const { return _caller_pc; } }; -typedef LinkedListImpl SharedStubToInterpRequests; +typedef GrowableArray SharedStubToInterpRequests; // A CodeBuffer describes a memory space into which assembly // code is generated. This memory space usually occupies the diff --git a/src/hotspot/share/asm/codeBuffer.inline.hpp b/src/hotspot/share/asm/codeBuffer.inline.hpp index 4361717794126..d0cbc4f971a9d 100644 --- a/src/hotspot/share/asm/codeBuffer.inline.hpp +++ b/src/hotspot/share/asm/codeBuffer.inline.hpp @@ -30,29 +30,41 @@ #include "code/compiledIC.hpp" template -bool emit_shared_stubs_to_interp(CodeBuffer* cb, const SharedStubToInterpRequests& shared_stub_to_interp_requests) { +bool emit_shared_stubs_to_interp(CodeBuffer* cb, SharedStubToInterpRequests* shared_stub_to_interp_requests) { + if (shared_stub_to_interp_requests->is_empty()) { + return true; + } + auto by_shared_method = [](SharedStubToInterpRequest* r1, SharedStubToInterpRequest* r2) { + if (r1->shared_method() < r2->shared_method()) { + return -1; + } else if (r1->shared_method() > r2->shared_method()) { + return 1; + } else { + return 0; + } + }; + shared_stub_to_interp_requests->sort(by_shared_method); MacroAssembler masm(cb); - LinkedListIterator it(shared_stub_to_interp_requests.head()); - SharedStubToInterpRequest* request = it.next(); int relocations_created = 0; - while (request != NULL) { + for (int i = 0; i < shared_stub_to_interp_requests->length();) { address stub = masm.start_a_stub(CompiledStaticCall::to_interp_stub_size()); if (stub == NULL) { ciEnv::current()->record_failure("CodeCache is full"); return false; } - Method* method = request->shared_method(); + + Method* method = shared_stub_to_interp_requests->at(i).shared_method(); do { - masm.relocate(static_stub_Relocation::spec(request->caller_pc()), relocate_format); - request = it.next(); + masm.relocate(static_stub_Relocation::spec(shared_stub_to_interp_requests->at(i).caller_pc()), relocate_format); + ++i; ++relocations_created; - } while (request != NULL && request->shared_method() == method); + } while (i < shared_stub_to_interp_requests->length() && shared_stub_to_interp_requests->at(i).shared_method() == method); masm.emit_static_call_stub(); masm.end_a_stub(); } if (relocations_created > 1 && UseNewCode) { - tty->print_cr("Requests %d", (int)shared_stub_to_interp_requests.size()); + tty->print_cr("Requests %d", (int)shared_stub_to_interp_requests->length()); tty->print_cr("Saved %d", (relocations_created-1)*CompiledStaticCall::to_interp_stub_size()); } return true; From 580544dc44c38d9f9f2c5316d3a18cabd29a4d20 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Mon, 11 Apr 2022 19:42:57 +0000 Subject: [PATCH 09/19] Update test to have more static stubs --- .../sharedstubs/SharedStubToInterpTest.java | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java index d5232df30aea8..728ea4b2a3ba6 100644 --- a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java +++ b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java @@ -65,8 +65,10 @@ public static void main(String[] args) throws Exception { command.add("-XX:CompileCommand=compileonly," + testClassName + "::" + "test"); command.add("-XX:CompileCommand=dontinline," + testClassName + "::" + "test"); command.add("-XX:CompileCommand=print," + testClassName + "::" + "test"); - command.add("-XX:CompileCommand=exclude," + testClassName + "::" + "log"); - command.add("-XX:CompileCommand=dontinline," + testClassName + "::" + "log"); + command.add("-XX:CompileCommand=exclude," + testClassName + "::" + "log01"); + command.add("-XX:CompileCommand=dontinline," + testClassName + "::" + "log01"); + command.add("-XX:CompileCommand=exclude," + testClassName + "::" + "log02"); + command.add("-XX:CompileCommand=dontinline," + testClassName + "::" + "log02"); command.add(testClassName); command.add("a"); command.add("b"); @@ -104,11 +106,17 @@ private static void checkOutput(OutputAnalyzer output) { throw new RuntimeException("Missing compiler output for the method 'test'"); } - // Shared static stubs are put after Deopt Handler Code. - match = skipTo(iter, "{runtime_call DeoptimizationBlob}"); - if (match == null) { - throw new RuntimeException("The start of Deopt Handler Code not found"); + while (iter.hasNext()) { + String nextLine = iter.next(); + if (nextLine.contains("{static_stub}")) { + // Static stubs must be created at the end of the Stub section. + throw new RuntimeException("Found {static_stub} before Deopt Handler Code"); + } else if (nextLine.contains("{runtime_call DeoptimizationBlob}")) { + // Shared static stubs are put after Deopt Handler Code. + break; + } } + int foundStaticStubs = 0; while (iter.hasNext()) { if (iter.next().contains("{static_stub}")) { @@ -116,21 +124,25 @@ private static void checkOutput(OutputAnalyzer output) { } } - final int expectedStaticStubs = 1; + final int expectedStaticStubs = 2; if (foundStaticStubs != expectedStaticStubs) { throw new RuntimeException("Found static stubs: " + foundStaticStubs + "; Expected static stubs: " + expectedStaticStubs); } } public static class StaticMethodTest { - static void log(int i) { + static void log01(int i) { + } + static void log02(int i) { } static void test(int i, String[] args) { if (i % args.length == 0) { - log(i); + log01(i); + log02(i); } else { - log(i); + log01(i); + log02(i); } } @@ -142,14 +154,18 @@ public static void main(String[] args) { } public static final class FinalClassTest { - void log(int i) { + void log01(int i) { + } + void log02(int i) { } void test(int i, String[] args) { if (i % args.length == 0) { - log(i); + log01(i); + log02(i); } else { - log(i); + log01(i); + log02(i); } } @@ -162,14 +178,18 @@ public static void main(String[] args) { } public static class FinalMethodTest { - final void log(int i) { + final void log01(int i) { + } + final void log02(int i) { } void test(int i, String[] args) { if (i % args.length == 0) { - log(i); + log01(i); + log02(i); } else { - log(i); + log01(i); + log02(i); } } From 600d3a9fd1a28543b09e7c649150f177869b3d89 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Mon, 11 Apr 2022 20:35:43 +0000 Subject: [PATCH 10/19] Fix memory leak found by gtest --- src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp | 2 +- src/hotspot/share/asm/codeBuffer.cpp | 5 ++++- src/hotspot/share/asm/codeBuffer.hpp | 3 ++- src/hotspot/share/asm/codeBuffer.inline.hpp | 2 +- src/hotspot/share/runtime/globals.hpp | 2 +- .../jtreg/compiler/sharedstubs/SharedStubToInterpTest.java | 2 +- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp index 78b69aecba06a..4257782fdc2cb 100644 --- a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.cpp @@ -27,5 +27,5 @@ #include "asm/macroAssembler.hpp" bool CodeBuffer::pd_finalize_stubs() { - return emit_shared_stubs_to_interp(this, &_shared_stub_to_interp_requests); + return emit_shared_stubs_to_interp(this, _shared_stub_to_interp_requests); } diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index d5ef305fffd12..424bba7600bc7 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -988,8 +988,11 @@ void CodeBuffer::finalize_stubs() { } void CodeBuffer::shared_stub_to_interp_for(Method* method, address caller_pc) { + if (_shared_stub_to_interp_requests == NULL) { + _shared_stub_to_interp_requests = new SharedStubToInterpRequests(); + } SharedStubToInterpRequest request(method, caller_pc); - _shared_stub_to_interp_requests.push(request); + _shared_stub_to_interp_requests->push(request); _finalize_stubs = true; } diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index 9160d11f7205d..4a0e2614b213a 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -433,7 +433,7 @@ class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) { address _last_insn; // used to merge consecutive memory barriers, loads or stores. - SharedStubToInterpRequests _shared_stub_to_interp_requests; // used to collect requests for shared iterpreter stubs + SharedStubToInterpRequests* _shared_stub_to_interp_requests; // used to collect requests for shared iterpreter stubs bool _finalize_stubs; // Indicate if we need to finalize stubs to make CodeBuffer final. #ifndef PRODUCT @@ -454,6 +454,7 @@ class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) { _overflow_arena = NULL; _last_insn = NULL; _finalize_stubs = false; + _shared_stub_to_interp_requests = NULL; #ifndef PRODUCT _decode_begin = NULL; diff --git a/src/hotspot/share/asm/codeBuffer.inline.hpp b/src/hotspot/share/asm/codeBuffer.inline.hpp index d0cbc4f971a9d..bcea4245dca40 100644 --- a/src/hotspot/share/asm/codeBuffer.inline.hpp +++ b/src/hotspot/share/asm/codeBuffer.inline.hpp @@ -31,7 +31,7 @@ template bool emit_shared_stubs_to_interp(CodeBuffer* cb, SharedStubToInterpRequests* shared_stub_to_interp_requests) { - if (shared_stub_to_interp_requests->is_empty()) { + if (shared_stub_to_interp_requests == NULL) { return true; } auto by_shared_method = [](SharedStubToInterpRequest* r1, SharedStubToInterpRequest* r2) { diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index fe4645be713eb..481141cf764b2 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -2054,7 +2054,7 @@ const intx ObjectAlignmentInBytes = 8; \ develop(bool, TraceOptimizedUpcallStubs, false, \ "Trace optimized upcall stub generation") \ - product(bool, UseSharedStubs, false, DIAGNOSTIC, \ + product(bool, UseSharedStubs, true, DIAGNOSTIC, \ "Allow sharing stubs whether it is possible") \ \ diff --git a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java index 728ea4b2a3ba6..16ae2c46fc132 100644 --- a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java +++ b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java @@ -61,7 +61,7 @@ public static void main(String[] args) throws Exception { throw new RuntimeException("Unknown compiler: " + compiler); } command.add("-Xbatch"); - command.add("-XX:+UseSharedStubs"); + //command.add("-XX:+UseSharedStubs"); command.add("-XX:CompileCommand=compileonly," + testClassName + "::" + "test"); command.add("-XX:CompileCommand=dontinline," + testClassName + "::" + "test"); command.add("-XX:CompileCommand=print," + testClassName + "::" + "test"); From 2dd68c92d5fb6370b1178f8fc874de9b3b5609b9 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Mon, 11 Apr 2022 20:46:29 +0000 Subject: [PATCH 11/19] Fix x86 build failure --- src/hotspot/cpu/x86/codeBuffer_x86.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/cpu/x86/codeBuffer_x86.cpp b/src/hotspot/cpu/x86/codeBuffer_x86.cpp index 1e6ef09003277..3c406ed1b198e 100644 --- a/src/hotspot/cpu/x86/codeBuffer_x86.cpp +++ b/src/hotspot/cpu/x86/codeBuffer_x86.cpp @@ -27,5 +27,5 @@ #include "asm/macroAssembler.hpp" bool CodeBuffer::pd_finalize_stubs() { - return emit_shared_stubs_to_interp(this, &_shared_stub_to_interp_requests); + return emit_shared_stubs_to_interp(this, _shared_stub_to_interp_requests); } From 0ca42b1ed82e3480e9fcd16b4af350159bf742f6 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Fri, 15 Apr 2022 15:43:29 +0000 Subject: [PATCH 12/19] Set UseSharedStubs to true for AArch64 --- src/hotspot/cpu/aarch64/vm_version_aarch64.cpp | 4 ++++ src/hotspot/share/asm/codeBuffer.inline.hpp | 7 ------- src/hotspot/share/runtime/globals.hpp | 6 +++--- .../jtreg/compiler/sharedstubs/SharedStubToInterpTest.java | 1 - 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index 63ba7efc0a502..077681b886aa2 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -129,6 +129,10 @@ void VM_Version::initialize() { } } + if (FLAG_IS_DEFAULT(UseSharedStubs)) { + FLAG_SET_DEFAULT(UseSharedStubs, true); + } + // Enable vendor specific features // Ampere eMAG diff --git a/src/hotspot/share/asm/codeBuffer.inline.hpp b/src/hotspot/share/asm/codeBuffer.inline.hpp index bcea4245dca40..ad19653af4052 100644 --- a/src/hotspot/share/asm/codeBuffer.inline.hpp +++ b/src/hotspot/share/asm/codeBuffer.inline.hpp @@ -45,7 +45,6 @@ bool emit_shared_stubs_to_interp(CodeBuffer* cb, SharedStubToInterpRequests* sha }; shared_stub_to_interp_requests->sort(by_shared_method); MacroAssembler masm(cb); - int relocations_created = 0; for (int i = 0; i < shared_stub_to_interp_requests->length();) { address stub = masm.start_a_stub(CompiledStaticCall::to_interp_stub_size()); if (stub == NULL) { @@ -57,16 +56,10 @@ bool emit_shared_stubs_to_interp(CodeBuffer* cb, SharedStubToInterpRequests* sha do { masm.relocate(static_stub_Relocation::spec(shared_stub_to_interp_requests->at(i).caller_pc()), relocate_format); ++i; - ++relocations_created; } while (i < shared_stub_to_interp_requests->length() && shared_stub_to_interp_requests->at(i).shared_method() == method); masm.emit_static_call_stub(); masm.end_a_stub(); } - - if (relocations_created > 1 && UseNewCode) { - tty->print_cr("Requests %d", (int)shared_stub_to_interp_requests->length()); - tty->print_cr("Saved %d", (relocations_created-1)*CompiledStaticCall::to_interp_stub_size()); - } return true; } diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index 481141cf764b2..d937729a24bfd 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -2052,9 +2052,9 @@ const intx ObjectAlignmentInBytes = 8; "Mark all threads after a safepoint, and clear on a modify " \ "fence. Add cleanliness checks.") \ \ - develop(bool, TraceOptimizedUpcallStubs, false, \ - "Trace optimized upcall stub generation") \ - product(bool, UseSharedStubs, true, DIAGNOSTIC, \ + develop(bool, TraceOptimizedUpcallStubs, false, \ + "Trace optimized upcall stub generation") \ + product(bool, UseSharedStubs, false, DIAGNOSTIC, \ "Allow sharing stubs whether it is possible") \ \ diff --git a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java index 16ae2c46fc132..acd64832ed3eb 100644 --- a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java +++ b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java @@ -61,7 +61,6 @@ public static void main(String[] args) throws Exception { throw new RuntimeException("Unknown compiler: " + compiler); } command.add("-Xbatch"); - //command.add("-XX:+UseSharedStubs"); command.add("-XX:CompileCommand=compileonly," + testClassName + "::" + "test"); command.add("-XX:CompileCommand=dontinline," + testClassName + "::" + "test"); command.add("-XX:CompileCommand=print," + testClassName + "::" + "test"); From ec62db17c3e9f873046a31d7ea8925ad44ffe504 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Fri, 15 Apr 2022 22:05:25 +0000 Subject: [PATCH 13/19] Set UseSharedStubs to true for X86 --- src/hotspot/cpu/x86/vm_version_x86.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp index 41a43c7de3c97..27b5cdb4df571 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.cpp +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp @@ -2056,6 +2056,10 @@ void VM_Version::initialize() { detect_virt_stub = CAST_TO_FN_PTR(detect_virt_stub_t, g.generate_detect_virt()); + if (FLAG_IS_DEFAULT(UseSharedStubs)) { + FLAG_SET_DEFAULT(UseSharedStubs, true); + } + get_processor_features(); LP64_ONLY(Assembler::precompute_instructions();) From 04a7cc76044d045765e20dfa067762ad2c4c633a Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Wed, 20 Apr 2022 15:09:08 +0000 Subject: [PATCH 14/19] Update copyright year and add Unimplemented guards --- src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp | 2 +- src/hotspot/cpu/arm/codeBuffer_arm.hpp | 9 +++++++-- src/hotspot/cpu/ppc/codeBuffer_ppc.hpp | 9 +++++++-- src/hotspot/cpu/riscv/codeBuffer_riscv.hpp | 9 +++++++-- src/hotspot/cpu/s390/codeBuffer_s390.hpp | 9 +++++++-- src/hotspot/cpu/x86/codeBuffer_x86.hpp | 2 +- src/hotspot/cpu/x86/compiledIC_x86.cpp | 2 +- src/hotspot/cpu/zero/codeBuffer_zero.hpp | 9 +++++++-- src/hotspot/share/asm/codeBuffer.hpp | 2 +- 9 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp index 104eeccc7a1eb..02d6a496a0457 100644 --- a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff --git a/src/hotspot/cpu/arm/codeBuffer_arm.hpp b/src/hotspot/cpu/arm/codeBuffer_arm.hpp index 375428ca86eeb..d561958561ed0 100644 --- a/src/hotspot/cpu/arm/codeBuffer_arm.hpp +++ b/src/hotspot/cpu/arm/codeBuffer_arm.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,12 @@ private: void pd_initialize() {} - bool pd_finalize_stubs() { return true; } + bool pd_finalize_stubs() { + if (_finalize_stubs) { + Unimplemented(); + } + return true; + } public: void flush_bundle(bool start_new_bundle) {} diff --git a/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp b/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp index a71b573381745..119a39f2c0586 100644 --- a/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp +++ b/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2013 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -28,7 +28,12 @@ private: void pd_initialize() {} - bool pd_finalize_stubs() { return true; } + bool pd_finalize_stubs() { + if (_finalize_stubs) { + Unimplemented(); + } + return true; + } public: void flush_bundle(bool start_new_bundle) {} diff --git a/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp b/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp index 7a69cf8c261b4..6ce43eb8c79cb 100644 --- a/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp +++ b/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -29,7 +29,12 @@ private: void pd_initialize() {} - bool pd_finalize_stubs() { return true; } + bool pd_finalize_stubs() { + if (_finalize_stubs) { + Unimplemented(); + } + return true; + } public: void flush_bundle(bool start_new_bundle) {} diff --git a/src/hotspot/cpu/s390/codeBuffer_s390.hpp b/src/hotspot/cpu/s390/codeBuffer_s390.hpp index 5dcd6c249db88..2f7518013c510 100644 --- a/src/hotspot/cpu/s390/codeBuffer_s390.hpp +++ b/src/hotspot/cpu/s390/codeBuffer_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -28,7 +28,12 @@ private: void pd_initialize() {} - bool pd_finalize_stubs() { return true; } + bool pd_finalize_stubs() { + if (_finalize_stubs) { + Unimplemented(); + } + return true; + } public: void flush_bundle(bool start_new_bundle) {} diff --git a/src/hotspot/cpu/x86/codeBuffer_x86.hpp b/src/hotspot/cpu/x86/codeBuffer_x86.hpp index 7a8fae033fd40..ef751e6198ec7 100644 --- a/src/hotspot/cpu/x86/codeBuffer_x86.hpp +++ b/src/hotspot/cpu/x86/codeBuffer_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/hotspot/cpu/x86/compiledIC_x86.cpp b/src/hotspot/cpu/x86/compiledIC_x86.cpp index d9d97d75033e0..b8ad469805ddc 100644 --- a/src/hotspot/cpu/x86/compiledIC_x86.cpp +++ b/src/hotspot/cpu/x86/compiledIC_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/hotspot/cpu/zero/codeBuffer_zero.hpp b/src/hotspot/cpu/zero/codeBuffer_zero.hpp index 82831e51baaa1..67b15ecaaedb5 100644 --- a/src/hotspot/cpu/zero/codeBuffer_zero.hpp +++ b/src/hotspot/cpu/zero/codeBuffer_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright 2007 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -28,6 +28,11 @@ private: void pd_initialize() {} - bool pd_finalize_stubs() { return true; } + bool pd_finalize_stubs() { + if (_finalize_stubs) { + Unimplemented(); + } + return true; + } #endif // CPU_ZERO_CODEBUFFER_ZERO_HPP diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index 4a0e2614b213a..132f7e0b281cb 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it From 9051c0de60e437ed0ca3240e6adf96baebd184f9 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Thu, 21 Apr 2022 12:55:20 +0000 Subject: [PATCH 15/19] Make SharedStubToInterpRequest ResourceObj and set initial size of SharedStubToInterpRequests to 8 --- src/hotspot/share/asm/codeBuffer.cpp | 2 +- src/hotspot/share/asm/codeBuffer.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index 424bba7600bc7..22827e7e7eef5 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -989,7 +989,7 @@ void CodeBuffer::finalize_stubs() { void CodeBuffer::shared_stub_to_interp_for(Method* method, address caller_pc) { if (_shared_stub_to_interp_requests == NULL) { - _shared_stub_to_interp_requests = new SharedStubToInterpRequests(); + _shared_stub_to_interp_requests = new SharedStubToInterpRequests(8); } SharedStubToInterpRequest request(method, caller_pc); _shared_stub_to_interp_requests->push(request); diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index 132f7e0b281cb..71fb39d8f3355 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -347,7 +347,7 @@ class Scrubber { // Calls of Java mehtods need stubs to the interpreter. Calls sharing the same Java method // can share a stub to interpreter. // A SharedStubToInterpRequest describes a request for a shared stub to the interpreter. -class SharedStubToInterpRequest { +class SharedStubToInterpRequest: public ResourceObj { private: Method* _shared_method; address _caller_pc; From 1459e112b63cce2ad462f3366e0b6d3c8b315e26 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Fri, 22 Apr 2022 12:51:22 +0000 Subject: [PATCH 16/19] Remove UseSharedStubs and clarify shared stub use cases --- src/hotspot/cpu/aarch64/aarch64.ad | 9 ++++----- src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp | 1 + src/hotspot/cpu/aarch64/vm_version_aarch64.cpp | 4 ---- src/hotspot/cpu/arm/codeBuffer_arm.hpp | 1 + src/hotspot/cpu/ppc/codeBuffer_ppc.hpp | 1 + src/hotspot/cpu/riscv/codeBuffer_riscv.hpp | 1 + src/hotspot/cpu/s390/codeBuffer_s390.hpp | 1 + src/hotspot/cpu/x86/codeBuffer_x86.hpp | 1 + src/hotspot/cpu/x86/vm_version_x86.cpp | 4 ---- src/hotspot/cpu/x86/x86_32.ad | 7 +++---- src/hotspot/cpu/x86/x86_64.ad | 7 +++---- src/hotspot/cpu/zero/codeBuffer_zero.hpp | 2 ++ src/hotspot/share/asm/codeBuffer.cpp | 4 ++-- src/hotspot/share/asm/codeBuffer.hpp | 11 ++++++----- src/hotspot/share/asm/codeBuffer.inline.hpp | 2 +- src/hotspot/share/c1/c1_LIRAssembler.cpp | 14 ++++---------- src/hotspot/share/runtime/globals.hpp | 3 --- 17 files changed, 31 insertions(+), 42 deletions(-) diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index d3aa95a0f82a2..d496bc00ee61b 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -3810,11 +3810,10 @@ encode %{ ciEnv::current()->record_failure("CodeCache is full"); return; } - if (UseSharedStubs && _method->is_loaded() && - (!_optimized_virtual || _method->is_final_method())) { - // Postpone creating a stub to the interpreter because - // it might be shared among calls of the same Java method. - cbuf.shared_stub_to_interp_for(_method->get_Method(), cbuf.insts_mark()); + if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { + // Calls of the same statically bound method can share + // a stub to the interpreter. + cbuf.shared_stub_to_interp_for(_method, cbuf.insts_mark()); } else { // Emit stub for static call address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); diff --git a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp index 02d6a496a0457..f6b1241d4f187 100644 --- a/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/codeBuffer_aarch64.hpp @@ -32,5 +32,6 @@ public: void flush_bundle(bool start_new_bundle) {} + static constexpr bool supports_shared_stubs() { return true; } #endif // CPU_AARCH64_CODEBUFFER_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index 077681b886aa2..63ba7efc0a502 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -129,10 +129,6 @@ void VM_Version::initialize() { } } - if (FLAG_IS_DEFAULT(UseSharedStubs)) { - FLAG_SET_DEFAULT(UseSharedStubs, true); - } - // Enable vendor specific features // Ampere eMAG diff --git a/src/hotspot/cpu/arm/codeBuffer_arm.hpp b/src/hotspot/cpu/arm/codeBuffer_arm.hpp index d561958561ed0..eefedb12e08cc 100644 --- a/src/hotspot/cpu/arm/codeBuffer_arm.hpp +++ b/src/hotspot/cpu/arm/codeBuffer_arm.hpp @@ -36,5 +36,6 @@ public: void flush_bundle(bool start_new_bundle) {} + static constexpr bool supports_shared_stubs() { return false; } #endif // CPU_ARM_CODEBUFFER_ARM_HPP diff --git a/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp b/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp index 119a39f2c0586..935063afb2f36 100644 --- a/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp +++ b/src/hotspot/cpu/ppc/codeBuffer_ppc.hpp @@ -37,5 +37,6 @@ public: void flush_bundle(bool start_new_bundle) {} + static constexpr bool supports_shared_stubs() { return false; } #endif // CPU_PPC_CODEBUFFER_PPC_HPP diff --git a/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp b/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp index 6ce43eb8c79cb..2786d4ad76b41 100644 --- a/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp +++ b/src/hotspot/cpu/riscv/codeBuffer_riscv.hpp @@ -38,5 +38,6 @@ public: void flush_bundle(bool start_new_bundle) {} + static constexpr bool supports_shared_stubs() { return false; } #endif // CPU_RISCV_CODEBUFFER_RISCV_HPP diff --git a/src/hotspot/cpu/s390/codeBuffer_s390.hpp b/src/hotspot/cpu/s390/codeBuffer_s390.hpp index 2f7518013c510..dbb75f5a78c3d 100644 --- a/src/hotspot/cpu/s390/codeBuffer_s390.hpp +++ b/src/hotspot/cpu/s390/codeBuffer_s390.hpp @@ -39,5 +39,6 @@ void flush_bundle(bool start_new_bundle) {} void getCpuData(const CodeBuffer * const cb) {} + static constexpr bool supports_shared_stubs() { return false; } #endif // CPU_S390_CODEBUFFER_S390_HPP diff --git a/src/hotspot/cpu/x86/codeBuffer_x86.hpp b/src/hotspot/cpu/x86/codeBuffer_x86.hpp index ef751e6198ec7..3c6e6675b05a4 100644 --- a/src/hotspot/cpu/x86/codeBuffer_x86.hpp +++ b/src/hotspot/cpu/x86/codeBuffer_x86.hpp @@ -31,5 +31,6 @@ public: void flush_bundle(bool start_new_bundle) {} + static constexpr bool supports_shared_stubs() { return true; } #endif // CPU_X86_CODEBUFFER_X86_HPP diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp index 27b5cdb4df571..41a43c7de3c97 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.cpp +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp @@ -2056,10 +2056,6 @@ void VM_Version::initialize() { detect_virt_stub = CAST_TO_FN_PTR(detect_virt_stub_t, g.generate_detect_virt()); - if (FLAG_IS_DEFAULT(UseSharedStubs)) { - FLAG_SET_DEFAULT(UseSharedStubs, true); - } - get_processor_features(); LP64_ONLY(Assembler::precompute_instructions();) diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad index bffabf0228fd7..97428d26be9c5 100644 --- a/src/hotspot/cpu/x86/x86_32.ad +++ b/src/hotspot/cpu/x86/x86_32.ad @@ -1814,10 +1814,9 @@ encode %{ rspec, RELOC_DISP32); __ post_call_nop(); address mark = cbuf.insts_mark(); - if (UseSharedStubs && _method->is_loaded() && - (!_optimized_virtual || _method->is_final_method())) { - // Postpone creating a stub to the interpreter because - // it might be shared among calls of the same Java method. + if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { + // Calls of the same statically bound method can share + // a stub to the interpreter. cbuf.shared_stub_to_interp_for(_method->get_Method(), mark); } else { // Emit stubs for static call. diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index c143c2a33add5..a3b92844931ac 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -2169,10 +2169,9 @@ encode %{ emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), rspec, RELOC_DISP32); address mark = cbuf.insts_mark(); - if (UseSharedStubs && _method->is_loaded() && - (!_optimized_virtual || _method->is_final_method())) { - // Postpone creating a stub to the interpreter because - // it might be shared among calls of the same Java method. + if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { + // Calls of the same statically bound method can share + // a stub to the interpreter. cbuf.shared_stub_to_interp_for(_method->get_Method(), mark); } else { // Emit stubs for static call. diff --git a/src/hotspot/cpu/zero/codeBuffer_zero.hpp b/src/hotspot/cpu/zero/codeBuffer_zero.hpp index 67b15ecaaedb5..4d314f947ee02 100644 --- a/src/hotspot/cpu/zero/codeBuffer_zero.hpp +++ b/src/hotspot/cpu/zero/codeBuffer_zero.hpp @@ -34,5 +34,7 @@ } return true; } + public: + static constexpr bool supports_shared_stubs() { return false; } #endif // CPU_ZERO_CODEBUFFER_ZERO_HPP diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index 22827e7e7eef5..9cce29be7c1c6 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -987,11 +987,11 @@ void CodeBuffer::finalize_stubs() { _finalize_stubs = false; } -void CodeBuffer::shared_stub_to_interp_for(Method* method, address caller_pc) { +void CodeBuffer::shared_stub_to_interp_for(ciMethod* callee, address caller_pc) { if (_shared_stub_to_interp_requests == NULL) { _shared_stub_to_interp_requests = new SharedStubToInterpRequests(8); } - SharedStubToInterpRequest request(method, caller_pc); + SharedStubToInterpRequest request(callee, caller_pc); _shared_stub_to_interp_requests->push(request); _finalize_stubs = true; } diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index 71fb39d8f3355..bbe2f10ae6e40 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -37,6 +37,7 @@ class Compile; class BufferBlob; class CodeBuffer; class Label; +class ciMethod; class CodeOffsets: public StackObj { public: @@ -347,16 +348,16 @@ class Scrubber { // Calls of Java mehtods need stubs to the interpreter. Calls sharing the same Java method // can share a stub to interpreter. // A SharedStubToInterpRequest describes a request for a shared stub to the interpreter. -class SharedStubToInterpRequest: public ResourceObj { +class SharedStubToInterpRequest : public ResourceObj { private: - Method* _shared_method; + ciMethod* _shared_method; address _caller_pc; public: - SharedStubToInterpRequest(Method* method = NULL, address caller_pc = NULL) : _shared_method(method), + SharedStubToInterpRequest(ciMethod* method = NULL, address caller_pc = NULL) : _shared_method(method), _caller_pc(caller_pc) {} - Method* shared_method() const { return _shared_method; } + ciMethod* shared_method() const { return _shared_method; } address caller_pc() const { return _caller_pc; } }; typedef GrowableArray SharedStubToInterpRequests; @@ -710,7 +711,7 @@ class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) { void finalize_stubs(); // Request for a shared stub to the interpreter - void shared_stub_to_interp_for(Method* call, address caller_pc); + void shared_stub_to_interp_for(ciMethod* callee, address caller_pc); #ifndef PRODUCT public: diff --git a/src/hotspot/share/asm/codeBuffer.inline.hpp b/src/hotspot/share/asm/codeBuffer.inline.hpp index ad19653af4052..d137bd893c53d 100644 --- a/src/hotspot/share/asm/codeBuffer.inline.hpp +++ b/src/hotspot/share/asm/codeBuffer.inline.hpp @@ -52,7 +52,7 @@ bool emit_shared_stubs_to_interp(CodeBuffer* cb, SharedStubToInterpRequests* sha return false; } - Method* method = shared_stub_to_interp_requests->at(i).shared_method(); + ciMethod* method = shared_stub_to_interp_requests->at(i).shared_method(); do { masm.relocate(static_stub_Relocation::spec(shared_stub_to_interp_requests->at(i).caller_pc()), relocate_format); ++i; diff --git a/src/hotspot/share/c1/c1_LIRAssembler.cpp b/src/hotspot/share/c1/c1_LIRAssembler.cpp index e3ad26194f274..f91dfd93715b3 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.cpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp @@ -449,22 +449,16 @@ void LIR_Assembler::emit_rtcall(LIR_OpRTCall* op) { rt_call(op->result_opr(), op->addr(), op->arguments(), op->tmp(), op->info()); } -static bool can_use_shared_stub_for(LIR_OpJavaCall* op) { - return UseSharedStubs && - op->method()->is_loaded() && - (op->code() == lir_static_call || op->method()->is_final_method()); -} - void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { verify_oop_map(op->info()); // must align calls sites, otherwise they can't be updated atomically align_call(op->code()); - if (can_use_shared_stub_for(op)) { - // Postpone creating a stub to the interpreter. - // It might be shared among calls of the same Java method. - _masm->code()->shared_stub_to_interp_for(op->method()->get_Method(), pc()); + if (CodeBuffer::supports_shared_stubs() && op->method()->can_be_statically_bound()) { + // Calls of the same statically bound method can share + // a stub to the interpreter. + _masm->code()->shared_stub_to_interp_for(op->method(), pc()); } else { emit_static_call_stub(); } diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index d937729a24bfd..2c620ab9ef36a 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -2054,9 +2054,6 @@ const intx ObjectAlignmentInBytes = 8; \ develop(bool, TraceOptimizedUpcallStubs, false, \ "Trace optimized upcall stub generation") \ - product(bool, UseSharedStubs, false, DIAGNOSTIC, \ - "Allow sharing stubs whether it is possible") \ - \ // end of RUNTIME_FLAGS From 80ca8022778125096ce4637ad09d84a9a79257c4 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Fri, 22 Apr 2022 13:06:42 +0000 Subject: [PATCH 17/19] Fix x86 build failures --- src/hotspot/cpu/x86/x86_32.ad | 2 +- src/hotspot/cpu/x86/x86_64.ad | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad index 97428d26be9c5..2eecc0658f40c 100644 --- a/src/hotspot/cpu/x86/x86_32.ad +++ b/src/hotspot/cpu/x86/x86_32.ad @@ -1817,7 +1817,7 @@ encode %{ if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { // Calls of the same statically bound method can share // a stub to the interpreter. - cbuf.shared_stub_to_interp_for(_method->get_Method(), mark); + cbuf.shared_stub_to_interp_for(_method, mark); } else { // Emit stubs for static call. address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index a3b92844931ac..a58efd4898699 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -2172,7 +2172,7 @@ encode %{ if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { // Calls of the same statically bound method can share // a stub to the interpreter. - cbuf.shared_stub_to_interp_for(_method->get_Method(), mark); + cbuf.shared_stub_to_interp_for(_method, mark); } else { // Emit stubs for static call. address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); From af4bc5eff16fd41d251d5b8782f2af51749d84ce Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Fri, 22 Apr 2022 13:45:53 +0000 Subject: [PATCH 18/19] Simplify test --- .../sharedstubs/SharedStubToInterpTest.java | 64 +++++++++---------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java index acd64832ed3eb..a461c6935c49b 100644 --- a/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java +++ b/test/hotspot/jtreg/compiler/sharedstubs/SharedStubToInterpTest.java @@ -30,36 +30,25 @@ * * @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="i386" | os.arch=="x86" | os.arch=="aarch64" * - * @run driver compiler.sharedstubs.SharedStubToInterpTest c2 StaticMethodTest - * @run driver compiler.sharedstubs.SharedStubToInterpTest c1 StaticMethodTest - * @run driver compiler.sharedstubs.SharedStubToInterpTest c2 FinalClassTest - * @run driver compiler.sharedstubs.SharedStubToInterpTest c1 FinalClassTest - * @run driver compiler.sharedstubs.SharedStubToInterpTest c2 FinalMethodTest - * @run driver compiler.sharedstubs.SharedStubToInterpTest c1 FinalMethodTest + * @run driver compiler.sharedstubs.SharedStubToInterpTest */ package compiler.sharedstubs; import java.util.ArrayList; import java.util.Iterator; -import java.util.ListIterator; +import java.util.List; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; public class SharedStubToInterpTest { - public static void main(String[] args) throws Exception { - String compiler = args[0]; - String testClassName = SharedStubToInterpTest.class.getName() + "$" + args[1]; + private final static int ITERATIONS_TO_HEAT_LOOP = 20_000; + + private static void runTest(String compiler, String test) throws Exception { + String testClassName = SharedStubToInterpTest.class.getName() + "$" + test; ArrayList command = new ArrayList(); - command.add("-XX:+IgnoreUnrecognizedVMOptions"); + command.add(compiler); command.add("-XX:+UnlockDiagnosticVMOptions"); - if (compiler.equals("c2")) { - command.add("-XX:-TieredCompilation"); - } else if (compiler.equals("c1")) { - command.add("-XX:TieredStopAtLevel=1"); - } else { - throw new RuntimeException("Unknown compiler: " + compiler); - } command.add("-Xbatch"); command.add("-XX:CompileCommand=compileonly," + testClassName + "::" + "test"); command.add("-XX:CompileCommand=dontinline," + testClassName + "::" + "test"); @@ -69,9 +58,6 @@ public static void main(String[] args) throws Exception { command.add("-XX:CompileCommand=exclude," + testClassName + "::" + "log02"); command.add("-XX:CompileCommand=dontinline," + testClassName + "::" + "log02"); command.add(testClassName); - command.add("a"); - command.add("b"); - command.add("c"); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(command); @@ -84,6 +70,18 @@ public static void main(String[] args) throws Exception { checkOutput(analyzer); } + public static void main(String[] args) throws Exception { + List compilers = java.util.Arrays.asList("-XX:-TieredCompilation" /* C2 */, + "-XX:TieredStopAtLevel=1" /* C1 */); + List tests = java.util.Arrays.asList("StaticMethodTest", + "FinalClassTest", "FinalMethodTest"); + for (String compiler : compilers) { + for (String test : tests) { + runTest(compiler, test); + } + } + } + private static String skipTo(Iterator iter, String substring) { while (iter.hasNext()) { String nextLine = iter.next(); @@ -135,8 +133,8 @@ static void log01(int i) { static void log02(int i) { } - static void test(int i, String[] args) { - if (i % args.length == 0) { + static void test(int i) { + if (i % 3 == 0) { log01(i); log02(i); } else { @@ -146,8 +144,8 @@ static void test(int i, String[] args) { } public static void main(String[] args) { - for (int i = 1; i < 50_000; ++i) { - test(i, args); + for (int i = 1; i < ITERATIONS_TO_HEAT_LOOP; ++i) { + test(i); } } } @@ -158,8 +156,8 @@ void log01(int i) { void log02(int i) { } - void test(int i, String[] args) { - if (i % args.length == 0) { + void test(int i) { + if (i % 3 == 0) { log01(i); log02(i); } else { @@ -170,8 +168,8 @@ void test(int i, String[] args) { public static void main(String[] args) { FinalClassTest tFC = new FinalClassTest(); - for (int i = 1; i < 50_000; ++i) { - tFC.test(i,args); + for (int i = 1; i < ITERATIONS_TO_HEAT_LOOP; ++i) { + tFC.test(i); } } } @@ -182,8 +180,8 @@ final void log01(int i) { final void log02(int i) { } - void test(int i, String[] args) { - if (i % args.length == 0) { + void test(int i) { + if (i % 3 == 0) { log01(i); log02(i); } else { @@ -194,8 +192,8 @@ void test(int i, String[] args) { public static void main(String[] args) { FinalMethodTest tFM = new FinalMethodTest(); - for (int i = 1; i < 50_000; ++i) { - tFM.test(i,args); + for (int i = 1; i < ITERATIONS_TO_HEAT_LOOP; ++i) { + tFM.test(i); } } } From a249f7da85adededccf1b3e3076d56a316ceee96 Mon Sep 17 00:00:00 2001 From: Evgeny Astigeevich Date: Fri, 20 May 2022 14:50:45 +0000 Subject: [PATCH 19/19] Use call offset instead of caller pc --- src/hotspot/cpu/aarch64/aarch64.ad | 2 +- src/hotspot/cpu/x86/x86_32.ad | 2 +- src/hotspot/cpu/x86/x86_64.ad | 2 +- src/hotspot/share/asm/codeBuffer.cpp | 4 +-- src/hotspot/share/asm/codeBuffer.hpp | 36 +++++++++++---------- src/hotspot/share/asm/codeBuffer.inline.hpp | 3 +- src/hotspot/share/c1/c1_LIRAssembler.cpp | 3 +- 7 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index d496bc00ee61b..8afaa044da1b1 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -3813,7 +3813,7 @@ encode %{ if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { // Calls of the same statically bound method can share // a stub to the interpreter. - cbuf.shared_stub_to_interp_for(_method, cbuf.insts_mark()); + cbuf.shared_stub_to_interp_for(_method, cbuf.insts()->mark_off()); } else { // Emit stub for static call address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad index 2eecc0658f40c..09c6c278e2fed 100644 --- a/src/hotspot/cpu/x86/x86_32.ad +++ b/src/hotspot/cpu/x86/x86_32.ad @@ -1817,7 +1817,7 @@ encode %{ if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { // Calls of the same statically bound method can share // a stub to the interpreter. - cbuf.shared_stub_to_interp_for(_method, mark); + cbuf.shared_stub_to_interp_for(_method, cbuf.insts()->mark_off()); } else { // Emit stubs for static call. address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index a58efd4898699..ac19bf333f009 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -2172,7 +2172,7 @@ encode %{ if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { // Calls of the same statically bound method can share // a stub to the interpreter. - cbuf.shared_stub_to_interp_for(_method, mark); + cbuf.shared_stub_to_interp_for(_method, cbuf.insts()->mark_off()); } else { // Emit stubs for static call. address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index 9cce29be7c1c6..6cf1fec599e92 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -987,11 +987,11 @@ void CodeBuffer::finalize_stubs() { _finalize_stubs = false; } -void CodeBuffer::shared_stub_to_interp_for(ciMethod* callee, address caller_pc) { +void CodeBuffer::shared_stub_to_interp_for(ciMethod* callee, csize_t call_offset) { if (_shared_stub_to_interp_requests == NULL) { _shared_stub_to_interp_requests = new SharedStubToInterpRequests(8); } - SharedStubToInterpRequest request(callee, caller_pc); + SharedStubToInterpRequest request(callee, call_offset); _shared_stub_to_interp_requests->push(request); _finalize_stubs = true; } diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index bbe2f10ae6e40..ca9d0c641a0aa 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -38,6 +38,7 @@ class BufferBlob; class CodeBuffer; class Label; class ciMethod; +class SharedStubToInterpRequest; class CodeOffsets: public StackObj { public: @@ -344,22 +345,6 @@ class Scrubber { }; #endif // ASSERT -// A Java method can have calls of Java methods which can be statically bound. -// Calls of Java mehtods need stubs to the interpreter. Calls sharing the same Java method -// can share a stub to interpreter. -// A SharedStubToInterpRequest describes a request for a shared stub to the interpreter. -class SharedStubToInterpRequest : public ResourceObj { - private: - ciMethod* _shared_method; - address _caller_pc; - - public: - SharedStubToInterpRequest(ciMethod* method = NULL, address caller_pc = NULL) : _shared_method(method), - _caller_pc(caller_pc) {} - - ciMethod* shared_method() const { return _shared_method; } - address caller_pc() const { return _caller_pc; } -}; typedef GrowableArray SharedStubToInterpRequests; // A CodeBuffer describes a memory space into which assembly @@ -711,7 +696,7 @@ class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) { void finalize_stubs(); // Request for a shared stub to the interpreter - void shared_stub_to_interp_for(ciMethod* callee, address caller_pc); + void shared_stub_to_interp_for(ciMethod* callee, csize_t call_offset); #ifndef PRODUCT public: @@ -728,6 +713,23 @@ class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) { }; +// A Java method can have calls of Java methods which can be statically bound. +// Calls of Java methods need stubs to the interpreter. Calls sharing the same Java method +// can share a stub to the interpreter. +// A SharedStubToInterpRequest is a request for a shared stub to the interpreter. +class SharedStubToInterpRequest : public ResourceObj { + private: + ciMethod* _shared_method; + CodeBuffer::csize_t _call_offset; // The offset of the call in CodeBuffer + + public: + SharedStubToInterpRequest(ciMethod* method = NULL, CodeBuffer::csize_t call_offset = -1) : _shared_method(method), + _call_offset(call_offset) {} + + ciMethod* shared_method() const { return _shared_method; } + CodeBuffer::csize_t call_offset() const { return _call_offset; } +}; + inline bool CodeSection::maybe_expand_to_ensure_remaining(csize_t amount) { if (remaining() < amount) { _outer->expand(this, amount); return true; } return false; diff --git a/src/hotspot/share/asm/codeBuffer.inline.hpp b/src/hotspot/share/asm/codeBuffer.inline.hpp index d137bd893c53d..045cff13f25a2 100644 --- a/src/hotspot/share/asm/codeBuffer.inline.hpp +++ b/src/hotspot/share/asm/codeBuffer.inline.hpp @@ -54,7 +54,8 @@ bool emit_shared_stubs_to_interp(CodeBuffer* cb, SharedStubToInterpRequests* sha ciMethod* method = shared_stub_to_interp_requests->at(i).shared_method(); do { - masm.relocate(static_stub_Relocation::spec(shared_stub_to_interp_requests->at(i).caller_pc()), relocate_format); + address caller_pc = cb->insts_begin() + shared_stub_to_interp_requests->at(i).call_offset(); + masm.relocate(static_stub_Relocation::spec(caller_pc), relocate_format); ++i; } while (i < shared_stub_to_interp_requests->length() && shared_stub_to_interp_requests->at(i).shared_method() == method); masm.emit_static_call_stub(); diff --git a/src/hotspot/share/c1/c1_LIRAssembler.cpp b/src/hotspot/share/c1/c1_LIRAssembler.cpp index f91dfd93715b3..1f286330dc6d3 100644 --- a/src/hotspot/share/c1/c1_LIRAssembler.cpp +++ b/src/hotspot/share/c1/c1_LIRAssembler.cpp @@ -458,7 +458,8 @@ void LIR_Assembler::emit_call(LIR_OpJavaCall* op) { if (CodeBuffer::supports_shared_stubs() && op->method()->can_be_statically_bound()) { // Calls of the same statically bound method can share // a stub to the interpreter. - _masm->code()->shared_stub_to_interp_for(op->method(), pc()); + CodeBuffer::csize_t call_offset = pc() - _masm->code()->insts_begin(); + _masm->code()->shared_stub_to_interp_for(op->method(), call_offset); } else { emit_static_call_stub(); }