547 lines
23 KiB
Diff
Executable File
547 lines
23 KiB
Diff
Executable File
From 63cadc56420c73719e7a08587984bf5d96d3b063 Mon Sep 17 00:00:00 2001
|
|
From: miaozhuojun <mouzhuojun@huawei.com>
|
|
Date: Sat, 11 Sep 2021 14:48:00 +0800
|
|
Subject: [PATCH 23/23] JDK debug version crash when using AppCDS
|
|
|
|
Summary: <AppCDS> : JDK debug version crash when using AppCDS
|
|
LLT: ./jdk8u-dev/hotspot/test/runtime/NMT/NMTWithCDS.java
|
|
Patch Type: huawei
|
|
Bug url: NA
|
|
---
|
|
.../vm/interpreterGenerator_aarch64.hpp | 2 -
|
|
.../vm/templateInterpreter_aarch64.cpp | 144 +++++++++---------
|
|
.../vm/templateInterpreter_aarch64.hpp | 72 +++++++++
|
|
.../share/vm/interpreter/cppInterpreter.cpp | 13 +-
|
|
.../share/vm/interpreter/cppInterpreter.hpp | 3 +-
|
|
.../src/share/vm/interpreter/interpreter.cpp | 19 +--
|
|
.../vm/interpreter/templateInterpreter.cpp | 14 +-
|
|
.../vm/interpreter/templateInterpreter.hpp | 3 +-
|
|
hotspot/src/share/vm/memory/universe.cpp | 8 +
|
|
hotspot/src/share/vm/runtime/init.cpp | 6 +-
|
|
10 files changed, 165 insertions(+), 119 deletions(-)
|
|
|
|
diff --git a/hotspot/src/cpu/aarch64/vm/interpreterGenerator_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/interpreterGenerator_aarch64.hpp
|
|
index a275a6a99..40af38a79 100644
|
|
--- a/hotspot/src/cpu/aarch64/vm/interpreterGenerator_aarch64.hpp
|
|
+++ b/hotspot/src/cpu/aarch64/vm/interpreterGenerator_aarch64.hpp
|
|
@@ -50,8 +50,6 @@ void generate_transcendental_entry(AbstractInterpreter::MethodKind kind, int fpa
|
|
address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind);
|
|
void lock_method(void);
|
|
void generate_stack_overflow_check(void);
|
|
- void load_String_value(Register src, Register dst);
|
|
- void load_String_offset(Register src, Register dst);
|
|
void emit_array_address(Register src, Register idx, Register dst, BasicType type);
|
|
address generate_Dgemm_dgemm_entry();
|
|
address generate_Dgemv_dgemv_entry();
|
|
diff --git a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp
|
|
index b5f56fd03..f356fbf81 100644
|
|
--- a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp
|
|
+++ b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp
|
|
@@ -849,27 +849,6 @@ address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpret
|
|
return generate_native_entry(false);
|
|
}
|
|
|
|
-// Access the char-array of String
|
|
-void InterpreterGenerator::load_String_value(Register src, Register dst) {
|
|
- // Need to cooperate with JDK-8243996
|
|
- int value_offset = java_lang_String::value_offset_in_bytes();
|
|
-
|
|
- __ add(src, src, value_offset);
|
|
- __ load_heap_oop(dst, Address(src));
|
|
-}
|
|
-
|
|
-void InterpreterGenerator::load_String_offset(Register src, Register dst) {
|
|
- __ mov(dst, 0);
|
|
-
|
|
- // Get String value offset, because of order of initialization for Interpreter,
|
|
- // we have to hardcode the offset for String value. (JDK-8243996)
|
|
- if (java_lang_String::has_offset_field()) {
|
|
- int offset_offset = java_lang_String::offset_offset_in_bytes();
|
|
- __ add(src, src, offset_offset);
|
|
- __ ldrw(dst, Address(src));
|
|
- }
|
|
-}
|
|
-
|
|
void InterpreterGenerator::emit_array_address(Register src, Register idx,
|
|
Register dst, BasicType type) {
|
|
int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type);
|
|
@@ -900,7 +879,7 @@ void InterpreterGenerator::emit_array_address(Register src, Register idx,
|
|
*
|
|
*/
|
|
address InterpreterGenerator::generate_Dgemm_dgemm_entry() {
|
|
- if (!UseF2jBLASIntrinsics || (StubRoutines::dgemmDgemm() == NULL)) return NULL;
|
|
+ if (StubRoutines::dgemmDgemm() == NULL) return NULL;
|
|
|
|
address entry = __ pc();
|
|
|
|
@@ -917,19 +896,29 @@ address InterpreterGenerator::generate_Dgemm_dgemm_entry() {
|
|
const Register lda = c_rarg6;
|
|
const Register B = c_rarg7;
|
|
const FloatRegister beta = c_farg1;
|
|
- const Register tmp1 = rscratch1;
|
|
- const Register tmp2 = rscratch2;
|
|
-
|
|
- // trana
|
|
- __ ldr(ta, Address(esp, 17 * wordSize));
|
|
- load_String_value(ta, tmp1);
|
|
- load_String_offset(ta, tmp2);
|
|
- emit_array_address(tmp1, tmp2, ta, T_CHAR);
|
|
- // tranb
|
|
- __ ldr(tb, Address(esp, 16 * wordSize));
|
|
- load_String_value(tb, tmp1);
|
|
- load_String_offset(tb, tmp2);
|
|
- emit_array_address(tmp1, tmp2, tb, T_CHAR);
|
|
+
|
|
+ // trana/tranb
|
|
+ __ ldr(r0, Address(esp, 17 * wordSize));
|
|
+ __ ldr(r1, Address(esp, 16 * wordSize));
|
|
+
|
|
+ // Get String value offset, because of order of initialization for Interpreter,
|
|
+ // we have to hardcode the offset for String value and offset. These instructions
|
|
+ // generated there will be patched in interpreter_patch after java.lang.String has
|
|
+ // been loaded.
|
|
+ // load String offset
|
|
+ __ mov(r2, 0); // __ ldrw(r2, Address(r0, java_lang_String::offset_offset_in_bytes()))
|
|
+ __ mov(r3, 0); // __ ldrw(r3, Address(r1, java_lang_String::offset_offset_in_bytes()))
|
|
+
|
|
+ // load String value
|
|
+ __ mov(r4, 0xc); // __ mov(r4, java_lang_String::value_offset_in_bytes())
|
|
+ __ add(r0, r0, r4);
|
|
+ __ load_heap_oop(r0, Address(r0));
|
|
+ __ add(r1, r1, r4);
|
|
+ __ load_heap_oop(r1, Address(r1));
|
|
+
|
|
+ emit_array_address(r0, r2, ta, T_CHAR);
|
|
+ emit_array_address(r1, r3, tb, T_CHAR);
|
|
+
|
|
// m, n, k
|
|
__ ldrw(m, Address(esp, 15 * wordSize));
|
|
__ ldrw(n, Address(esp, 14 * wordSize));
|
|
@@ -937,16 +926,15 @@ address InterpreterGenerator::generate_Dgemm_dgemm_entry() {
|
|
// alpha
|
|
__ ldrd(alpha, Address(esp, 11 * wordSize));
|
|
// A
|
|
- __ ldr(tmp1, Address(esp, 10 * wordSize));
|
|
- __ mov(tmp2, 0);
|
|
- __ ldrw(tmp2, Address(esp, 9 * wordSize));
|
|
- emit_array_address(tmp1, tmp2, A, T_DOUBLE);
|
|
+ __ ldr(r5, Address(esp, 10 * wordSize));
|
|
+ __ ldrw(r6, Address(esp, 9 * wordSize));
|
|
+ emit_array_address(r5, r6, A, T_DOUBLE);
|
|
// lda
|
|
__ ldrw(lda, Address(esp, 8 * wordSize));
|
|
// B
|
|
- __ ldr(tmp1, Address(esp, 7 * wordSize));
|
|
- __ ldrw(tmp2, Address(esp, 6 * wordSize));
|
|
- emit_array_address(tmp1, tmp2, B, T_DOUBLE);
|
|
+ __ ldr(rscratch1, Address(esp, 7 * wordSize));
|
|
+ __ ldrw(rscratch2, Address(esp, 6 * wordSize));
|
|
+ emit_array_address(rscratch1, rscratch2, B, T_DOUBLE);
|
|
// beta
|
|
__ ldrd(beta, Address(esp, 3 * wordSize));
|
|
// Start pushing arguments to machine stack.
|
|
@@ -960,22 +948,22 @@ address InterpreterGenerator::generate_Dgemm_dgemm_entry() {
|
|
__ andr(sp, r13, -16);
|
|
__ str(lr, Address(sp, -wordSize));
|
|
// ldc
|
|
- __ ldrw(tmp1, Address(esp, 0x0));
|
|
- __ strw(tmp1, Address(sp, 2 * -wordSize));
|
|
+ __ ldrw(rscratch1, Address(esp, 0x0));
|
|
+ __ strw(rscratch1, Address(sp, 2 * -wordSize));
|
|
// C
|
|
- __ ldr(tmp1, Address(esp, 2 * wordSize));
|
|
- __ ldrw(tmp2, Address(esp, wordSize));
|
|
- emit_array_address(tmp1, tmp2, tmp1, T_DOUBLE);
|
|
- __ str(tmp1, Address(sp, 3 * -wordSize));
|
|
+ __ ldr(rscratch1, Address(esp, 2 * wordSize));
|
|
+ __ ldrw(rscratch2, Address(esp, wordSize));
|
|
+ emit_array_address(rscratch1, rscratch2, rscratch1, T_DOUBLE);
|
|
+ __ str(rscratch1, Address(sp, 3 * -wordSize));
|
|
// ldb
|
|
- __ ldrw(tmp2, Address(esp, 5 * wordSize));
|
|
- __ strw(tmp2, Address(sp, 4 * -wordSize));
|
|
+ __ ldrw(rscratch2, Address(esp, 5 * wordSize));
|
|
+ __ strw(rscratch2, Address(sp, 4 * -wordSize));
|
|
|
|
// Call function
|
|
__ add(sp, sp, 4 * -wordSize);
|
|
address fn = CAST_FROM_FN_PTR(address, StubRoutines::dgemmDgemm());
|
|
- __ mov(tmp1, fn);
|
|
- __ blr(tmp1);
|
|
+ __ mov(rscratch1, fn);
|
|
+ __ blr(rscratch1);
|
|
|
|
__ ldr(lr, Address(sp, 3 * wordSize));
|
|
// For assert(Rd != sp || imm % 16 == 0)
|
|
@@ -1001,9 +989,6 @@ address InterpreterGenerator::generate_Dgemv_dgemv_entry() {
|
|
const FloatRegister alpha = v0; // alpha
|
|
const FloatRegister beta = v1; // beta
|
|
|
|
- const Register tmp1 = rscratch1;
|
|
- const Register tmp2 = rscratch2;
|
|
-
|
|
// esp: expression stack of caller
|
|
// dgemv parameter ---> the position in stack ---> move to register
|
|
// | char* trans | | esp + 15 | | r0 |
|
|
@@ -1032,10 +1017,21 @@ address InterpreterGenerator::generate_Dgemv_dgemv_entry() {
|
|
|
|
|
|
// trans
|
|
- __ ldr(trans, Address(esp, 15 * wordSize));
|
|
- load_String_value(trans, tmp1);
|
|
- load_String_offset(trans, tmp2);
|
|
- emit_array_address(tmp1, tmp2, trans, T_CHAR);
|
|
+ __ ldr(r0, Address(esp, 15 * wordSize));
|
|
+
|
|
+ // Get String value offset, because of order of initialization for Interpreter,
|
|
+ // we have to hardcode the offset for String value and offset. These instructions
|
|
+ // generated there will be patched in interpreter_patch after java.lang.String has
|
|
+ // been loaded.
|
|
+ // load String offset
|
|
+ __ mov(r1, 0); // __ ldrw(r1, Address(r0, java_lang_String::offset_offset_in_bytes()))
|
|
+
|
|
+ // load String value
|
|
+ __ mov(r2, 0xc); // __ mov(r2, java_lang_String::value_offset_in_bytes())
|
|
+ __ add(r0, r0, r2);
|
|
+ __ load_heap_oop(r0, Address(r0));
|
|
+ emit_array_address(r0, r1, trans, T_CHAR);
|
|
+
|
|
// m, n
|
|
__ ldrw(m, Address(esp, 14 * wordSize));
|
|
__ ldrw(n, Address(esp, 13 * wordSize));
|
|
@@ -1044,19 +1040,17 @@ address InterpreterGenerator::generate_Dgemv_dgemv_entry() {
|
|
__ ldrd(alpha, Address(esp, 11 * wordSize));
|
|
|
|
// a
|
|
- __ ldr(tmp1, Address(esp, 10 * wordSize));
|
|
- __ mov(tmp2, zr);
|
|
- __ ldrw(tmp2, Address(esp, 9 * wordSize));
|
|
- emit_array_address(tmp1, tmp2, a, T_DOUBLE);
|
|
+ __ ldr(r3, Address(esp, 10 * wordSize));
|
|
+ __ ldrw(r4, Address(esp, 9 * wordSize));
|
|
+ emit_array_address(r3, r4, a, T_DOUBLE);
|
|
|
|
// lda
|
|
__ ldrw(lda, Address(esp, 8 * wordSize));
|
|
|
|
// x
|
|
- __ ldr(tmp1, Address(esp, 7 * wordSize));
|
|
- __ mov(tmp2, zr);
|
|
- __ ldrw(tmp2, Address(esp, 6 * wordSize));
|
|
- emit_array_address(tmp1, tmp2, x, T_DOUBLE);
|
|
+ __ ldr(r5, Address(esp, 7 * wordSize));
|
|
+ __ ldrw(r6, Address(esp, 6 * wordSize));
|
|
+ emit_array_address(r5, r6, x, T_DOUBLE);
|
|
|
|
// incx
|
|
__ ldrw(incx, Address(esp, 5 * wordSize));
|
|
@@ -1065,25 +1059,24 @@ address InterpreterGenerator::generate_Dgemv_dgemv_entry() {
|
|
__ ldrd(beta, Address(esp, 3 * wordSize));
|
|
|
|
// y
|
|
- __ ldr(tmp1, Address(esp, 2 * wordSize));
|
|
- __ mov(tmp2, zr);
|
|
- __ ldrw(tmp2, Address(esp, wordSize));
|
|
- emit_array_address(tmp1, tmp2, y, T_DOUBLE);
|
|
+ __ ldr(rscratch1, Address(esp, 2 * wordSize));
|
|
+ __ ldrw(rscratch2, Address(esp, wordSize));
|
|
+ emit_array_address(rscratch1, rscratch2, y, T_DOUBLE);
|
|
|
|
// resume sp, restore lr
|
|
__ andr(sp, r13, -16);
|
|
__ str(lr, Address(sp, -wordSize));
|
|
|
|
// incy, push on stack
|
|
- __ ldrw(tmp1, Address(esp, 0));
|
|
- __ strw(tmp1, Address(sp, 2 * -wordSize));
|
|
+ __ ldrw(rscratch1, Address(esp, 0));
|
|
+ __ strw(rscratch1, Address(sp, 2 * -wordSize));
|
|
|
|
__ add(sp, sp, -2 * wordSize);
|
|
|
|
// call function
|
|
address fn = CAST_FROM_FN_PTR(address, StubRoutines::dgemvDgemv());
|
|
- __ mov(tmp1, fn);
|
|
- __ blr(tmp1);
|
|
+ __ mov(rscratch1, fn);
|
|
+ __ blr(rscratch1);
|
|
|
|
// resume lr
|
|
__ ldr(lr, Address(sp, wordSize));
|
|
@@ -1960,7 +1953,6 @@ void AbstractInterpreter::layout_activation(Method* method,
|
|
method->constants()->cache();
|
|
}
|
|
|
|
-
|
|
//-----------------------------------------------------------------------------
|
|
// Exceptions
|
|
|
|
diff --git a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.hpp
|
|
index 36e1aa89d..3ca17e3c4 100644
|
|
--- a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.hpp
|
|
+++ b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.hpp
|
|
@@ -28,6 +28,78 @@
|
|
#define CPU_AARCH64_VM_TEMPLATEINTERPRETER_AARCH64_HPP
|
|
|
|
|
|
+ public:
|
|
+ static void patch_method(AbstractInterpreter::MethodKind kind) {
|
|
+ unsigned value_offset = java_lang_String::value_offset_in_bytes();
|
|
+ unsigned offset_offset = 0;
|
|
+ address entry = entry_for_kind(kind);
|
|
+
|
|
+ if (entry == NULL) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ switch (kind) {
|
|
+ case AbstractInterpreter::org_netlib_blas_Dgemm_dgemm:
|
|
+ if (StubRoutines::_dgemmDgemm == NULL) {
|
|
+ break;
|
|
+ }
|
|
+ // 0 : ldr x0, [x20, #136]
|
|
+ // 1 : ldr x1, [x20, #128]
|
|
+ // 2 : mov x2, #0x0 ==================> ldr w2, [x0, <java_lang_String::value_offset_in_bytes()>]
|
|
+ // 3 : mov x3, #0x0 ==================> ldr w3, [x1, <java_lang_String::value_offset_in_bytes()>]
|
|
+ // 4 : orr x4, xzr, #0xc =============> orr x4, xzr, <java_lang_String::value_offset_in_bytes()>
|
|
+ if (java_lang_String::has_offset_field()) {
|
|
+ guarantee(Instruction_aarch64::extract(((unsigned*)entry)[2], 31, 23) == 0b110100101 &&
|
|
+ Instruction_aarch64::extract(((unsigned*)entry)[3], 31, 23) == 0b110100101,
|
|
+ "wrong insns in patch");
|
|
+ offset_offset = java_lang_String::offset_offset_in_bytes();
|
|
+ // ldr w2, [x0, <java_lang_String::value_offset_in_bytes()>]
|
|
+ address tmp = entry + 4 * 2;
|
|
+ Instruction_aarch64::patch(tmp, 31, 22, 0b1011100101); // opc
|
|
+ Instruction_aarch64::patch(tmp, 21, 10, offset_offset >> 2); // imm12
|
|
+ Instruction_aarch64::patch(tmp, 9, 5, 0); // Rn
|
|
+ Instruction_aarch64::patch(tmp, 4, 0, 2); // Rt
|
|
+ // ldr w3, [x1, <java_lang_String::value_offset_in_bytes()>]
|
|
+ tmp = entry + 4 * 3;
|
|
+ Instruction_aarch64::patch(tmp, 31, 22, 0b1011100101); // opc
|
|
+ Instruction_aarch64::patch(tmp, 21, 10, offset_offset >> 2); // imm12
|
|
+ Instruction_aarch64::patch(tmp, 9, 5, 1); // Rn
|
|
+ Instruction_aarch64::patch(tmp, 4, 0, 3); // Rt
|
|
+ }
|
|
+ guarantee(Instruction_aarch64::extract(((unsigned*)entry)[4], 31, 23) == 0b101100100 &&
|
|
+ Instruction_aarch64::extract(((unsigned*)entry)[4], 9, 0) == 0b1111100100, "wrong insns in patch");
|
|
+ Instruction_aarch64::patch(entry + 4 * 4, 22, 10,
|
|
+ (uint64_t)encode_logical_immediate(false, (uint64_t)value_offset)); // imm16
|
|
+ ICache::invalidate_range(entry, 4 * 5);
|
|
+ break;
|
|
+ case AbstractInterpreter::org_netlib_blas_Dgemv_dgemv:
|
|
+ if (StubRoutines::_dgemvDgemv == NULL) {
|
|
+ break;
|
|
+ }
|
|
+ // 0 : ldr x0, [x20, #120]
|
|
+ // 1 : mov x1, #0x0 ==================> ldr w1, [r0, <java_lang_String::offset_offset_in_bytes()>]
|
|
+ // 2 : orr x2, xzr, #0xc =============> orr x2, xzr, <java_lang_String::value_offset_in_bytes()>
|
|
+ if (java_lang_String::has_offset_field()) {
|
|
+ guarantee(Instruction_aarch64::extract(((unsigned*)entry)[1], 31, 23) == 0b110100101, "wrong insns in patch");
|
|
+ offset_offset = java_lang_String::offset_offset_in_bytes();
|
|
+ // ldr w1, [x0, <java_lang_String::value_offset_in_bytes()>]
|
|
+ address tmp = entry + 4 * 1;
|
|
+ Instruction_aarch64::patch(tmp, 31, 22, 0b1011100101); // opc
|
|
+ Instruction_aarch64::patch(tmp, 21, 10, offset_offset >> 2); // imm12
|
|
+ Instruction_aarch64::patch(tmp, 9, 5, 0); // Rn
|
|
+ Instruction_aarch64::patch(tmp, 4, 0, 1); // Rt
|
|
+ }
|
|
+ guarantee(Instruction_aarch64::extract(((unsigned*)entry)[2], 31, 23) == 0b101100100 &&
|
|
+ Instruction_aarch64::extract(((unsigned*)entry)[2], 9, 0) == 0b1111100010, "wrong insns in patch");
|
|
+ Instruction_aarch64::patch(entry + 4 * 2, 22, 10,
|
|
+ (uint64_t)encode_logical_immediate(false, (uint64_t)value_offset)); // imm16
|
|
+ ICache::invalidate_range(entry, 4 * 3);
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
protected:
|
|
|
|
// Size of interpreter code. Increase if too small. Interpreter will
|
|
diff --git a/hotspot/src/share/vm/interpreter/cppInterpreter.cpp b/hotspot/src/share/vm/interpreter/cppInterpreter.cpp
|
|
index 9e48a1d94..0007aa8be 100644
|
|
--- a/hotspot/src/share/vm/interpreter/cppInterpreter.cpp
|
|
+++ b/hotspot/src/share/vm/interpreter/cppInterpreter.cpp
|
|
@@ -31,20 +31,17 @@
|
|
#ifdef CC_INTERP
|
|
# define __ _masm->
|
|
|
|
-void CppInterpreter::initialize_stub() {
|
|
+void CppInterpreter::initialize() {
|
|
if (_code != NULL) return;
|
|
- int code_size = InterpreterCodeSize;
|
|
- NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space
|
|
- _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,
|
|
- "Interpreter");
|
|
-}
|
|
-
|
|
-void CppInterpreter::initialize_code() {
|
|
AbstractInterpreter::initialize();
|
|
|
|
// generate interpreter
|
|
{ ResourceMark rm;
|
|
TraceTime timer("Interpreter generation", TraceStartupTime);
|
|
+ int code_size = InterpreterCodeSize;
|
|
+ NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space
|
|
+ _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,
|
|
+ "Interpreter");
|
|
InterpreterGenerator g(_code);
|
|
if (PrintInterpreter) print();
|
|
}
|
|
diff --git a/hotspot/src/share/vm/interpreter/cppInterpreter.hpp b/hotspot/src/share/vm/interpreter/cppInterpreter.hpp
|
|
index 58efcfaf2..6a6447503 100644
|
|
--- a/hotspot/src/share/vm/interpreter/cppInterpreter.hpp
|
|
+++ b/hotspot/src/share/vm/interpreter/cppInterpreter.hpp
|
|
@@ -54,8 +54,7 @@ class CppInterpreter: public AbstractInterpreter {
|
|
|
|
public:
|
|
// Initialization/debugging
|
|
- static void initialize_stub();
|
|
- static void initialize_code();
|
|
+ static void initialize();
|
|
// this only returns whether a pc is within generated code for the interpreter.
|
|
|
|
// This is a moderately dubious interface for the c++ interpreter. Only
|
|
diff --git a/hotspot/src/share/vm/interpreter/interpreter.cpp b/hotspot/src/share/vm/interpreter/interpreter.cpp
|
|
index a313f2e63..bfcb1bea2 100644
|
|
--- a/hotspot/src/share/vm/interpreter/interpreter.cpp
|
|
+++ b/hotspot/src/share/vm/interpreter/interpreter.cpp
|
|
@@ -85,6 +85,7 @@ void InterpreterCodelet::print_on(outputStream* st) const {
|
|
// Implementation of platform independent aspects of Interpreter
|
|
|
|
void AbstractInterpreter::initialize() {
|
|
+ if (_code != NULL) return;
|
|
// make sure 'imported' classes are initialized
|
|
if (CountBytecodes || TraceBytecodes || StopInterpreterAt) BytecodeCounter::reset();
|
|
if (PrintBytecodeHistogram) BytecodeHistogram::reset();
|
|
@@ -112,22 +113,8 @@ void AbstractInterpreter::print() {
|
|
}
|
|
|
|
|
|
-// The reason that interpreter initialization is split into two parts is that the first part
|
|
-// needs to run before methods are loaded (which with CDS implies linked also), and the other
|
|
-// part needs to run after. The reason is that when methods are loaded (with CDS) or linked
|
|
-// (without CDS), the i2c adapters are generated that assert we are currently in the interpreter.
|
|
-// Asserting that requires knowledge about where the interpreter is in memory. Therefore,
|
|
-// establishing the interpreter address must be done before methods are loaded. However,
|
|
-// we would like to actually generate the interpreter after methods are loaded. That allows
|
|
-// us to remove otherwise hardcoded offsets regarding fields that are needed in the interpreter
|
|
-// code. This leads to a split if 1. reserving the memory for the interpreter, 2. loading methods
|
|
-// and 3. generating the interpreter.
|
|
-void interpreter_init_stub() {
|
|
- Interpreter::initialize_stub();
|
|
-}
|
|
-
|
|
-void interpreter_init_code() {
|
|
- Interpreter::initialize_code();
|
|
+void interpreter_init() {
|
|
+ Interpreter::initialize();
|
|
#ifndef PRODUCT
|
|
if (TraceBytecodes) BytecodeTracer::set_closure(BytecodeTracer::std_closure());
|
|
#endif // PRODUCT
|
|
diff --git a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp
|
|
index f38f05117..09298a7fc 100644
|
|
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp
|
|
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp
|
|
@@ -32,20 +32,12 @@
|
|
|
|
# define __ _masm->
|
|
|
|
-void TemplateInterpreter::initialize_stub() {
|
|
+void TemplateInterpreter::initialize() {
|
|
if (_code != NULL) return;
|
|
// assertions
|
|
assert((int)Bytecodes::number_of_codes <= (int)DispatchTable::length,
|
|
"dispatch table too small");
|
|
|
|
- // allocate interpreter
|
|
- int code_size = InterpreterCodeSize;
|
|
- NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space
|
|
- _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,
|
|
- "Interpreter");
|
|
-}
|
|
-
|
|
-void TemplateInterpreter::initialize_code() {
|
|
AbstractInterpreter::initialize();
|
|
|
|
TemplateTable::initialize();
|
|
@@ -53,6 +45,10 @@ void TemplateInterpreter::initialize_code() {
|
|
// generate interpreter
|
|
{ ResourceMark rm;
|
|
TraceTime timer("Interpreter generation", TraceStartupTime);
|
|
+ int code_size = InterpreterCodeSize;
|
|
+ NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space
|
|
+ _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,
|
|
+ "Interpreter");
|
|
InterpreterGenerator g(_code);
|
|
if (PrintInterpreter) print();
|
|
}
|
|
diff --git a/hotspot/src/share/vm/interpreter/templateInterpreter.hpp b/hotspot/src/share/vm/interpreter/templateInterpreter.hpp
|
|
index 96da6353c..5f76dca8a 100644
|
|
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.hpp
|
|
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.hpp
|
|
@@ -132,8 +132,7 @@ class TemplateInterpreter: public AbstractInterpreter {
|
|
|
|
public:
|
|
// Initialization/debugging
|
|
- static void initialize_stub();
|
|
- static void initialize_code();
|
|
+ static void initialize();
|
|
// this only returns whether a pc is within generated code for the interpreter.
|
|
static bool contains(address pc) { return _code != NULL && _code->contains(pc); }
|
|
|
|
diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
|
|
index d9e670bee..1d05bcc73 100644
|
|
--- a/hotspot/src/share/vm/memory/universe.cpp
|
|
+++ b/hotspot/src/share/vm/memory/universe.cpp
|
|
@@ -425,6 +425,14 @@ void Universe::genesis(TRAPS) {
|
|
// Initialize dependency array for null class loader
|
|
ClassLoaderData::the_null_class_loader_data()->init_dependencies(CHECK);
|
|
|
|
+ // Patch the BLAS Interpreter intrinsics with java.lang.String
|
|
+ // offset after java.lang.String has been loaded.
|
|
+#if defined(TARGET_OS_ARCH_linux_aarch64) && !defined(CC_INTERP)
|
|
+ if (UseF2jBLASIntrinsics) {
|
|
+ Interpreter::patch_method(Interpreter::org_netlib_blas_Dgemm_dgemm);
|
|
+ Interpreter::patch_method(Interpreter::org_netlib_blas_Dgemv_dgemv);
|
|
+ }
|
|
+#endif
|
|
}
|
|
|
|
// CDS support for patching vtables in metadata in the shared archive.
|
|
diff --git a/hotspot/src/share/vm/runtime/init.cpp b/hotspot/src/share/vm/runtime/init.cpp
|
|
index 4c133bd4e..d15e40d44 100644
|
|
--- a/hotspot/src/share/vm/runtime/init.cpp
|
|
+++ b/hotspot/src/share/vm/runtime/init.cpp
|
|
@@ -54,8 +54,7 @@ void VM_Version_init();
|
|
void os_init_globals(); // depends on VM_Version_init, before universe_init
|
|
void stubRoutines_init1();
|
|
jint universe_init(); // depends on codeCache_init and stubRoutines_init
|
|
-void interpreter_init_stub(); // before any methods loaded
|
|
-void interpreter_init_code(); // after methods loaded, but before they are linked
|
|
+void interpreter_init(); // before any methods loaded
|
|
void invocationCounter_init(); // before any methods loaded
|
|
void marksweep_init();
|
|
void accessFlags_init();
|
|
@@ -107,7 +106,7 @@ jint init_globals() {
|
|
if (status != JNI_OK)
|
|
return status;
|
|
|
|
- interpreter_init_stub(); // before methods get loaded
|
|
+ interpreter_init(); // before any methods loaded
|
|
invocationCounter_init(); // before any methods loaded
|
|
marksweep_init();
|
|
accessFlags_init();
|
|
@@ -115,7 +114,6 @@ jint init_globals() {
|
|
InterfaceSupport_init();
|
|
SharedRuntime::generate_stubs();
|
|
universe2_init(); // dependent on codeCache_init and stubRoutines_init1
|
|
- interpreter_init_code(); // after universe2_init and before any method gets linked
|
|
referenceProcessor_init();
|
|
jni_handles_init();
|
|
#if INCLUDE_VM_STRUCTS
|
|
--
|
|
2.22.0
|
|
|