1 Star 0 Fork 26

ridedolphin/openjdk-17

forked from src-openEuler/openjdk-17 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
8280872-Reorder-code-cache-segments-to-improv.patch 14.20 KB
一键复制 编辑 原始数据 按行查看 历史
diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad
index b3d89863e..8df709ad0 100644
--- a/src/hotspot/cpu/aarch64/aarch64.ad
+++ b/src/hotspot/cpu/aarch64/aarch64.ad
@@ -1279,12 +1279,12 @@ class HandlerImpl {
static int emit_deopt_handler(CodeBuffer& cbuf);
static uint size_exception_handler() {
- return MacroAssembler::far_codestub_branch_size();
+ return MacroAssembler::far_branch_size();
}
static uint size_deopt_handler() {
// count one adr and one far branch instruction
- return NativeInstruction::instruction_size + MacroAssembler::far_codestub_branch_size();
+ return 4 * NativeInstruction::instruction_size;
}
};
@@ -2367,7 +2367,7 @@ int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf)
__ adr(lr, __ pc());
__ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
- assert(__ offset() - offset == (int) size_deopt_handler(), "overflow");
+ assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
__ end_a_stub();
return offset;
}
diff --git a/src/hotspot/cpu/aarch64/icBuffer_aarch64.cpp b/src/hotspot/cpu/aarch64/icBuffer_aarch64.cpp
index 7d0483fb3..21c2a3cc7 100644
--- a/src/hotspot/cpu/aarch64/icBuffer_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/icBuffer_aarch64.cpp
@@ -52,15 +52,9 @@ void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin, void* cached
address start = __ pc();
Label l;
__ ldr(rscratch2, l);
- int jump_code_size = __ far_jump(ExternalAddress(entry_point));
- // IC stub code size is not expected to vary depending on target address.
- // We use NOPs to make the [ldr + far_jump + nops + int64] stub size equal to ic_stub_code_size.
- for (int size = NativeInstruction::instruction_size + jump_code_size + 8;
- size < ic_stub_code_size(); size += NativeInstruction::instruction_size) {
- __ nop();
- }
+ __ far_jump(ExternalAddress(entry_point));
+ __ align(wordSize);
__ bind(l);
- assert((uintptr_t)__ pc() % wordSize == 0, "");
__ emit_int64((int64_t)cached_value);
// Only need to invalidate the 1st two instructions - not the whole ic stub
ICache::invalidate_range(code_begin, InlineCacheBuffer::ic_stub_code_size());
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
index d89d655af..9e84077f9 100644
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
@@ -397,27 +397,14 @@ void MacroAssembler::set_last_Java_frame(Register last_java_sp,
}
}
-static inline bool target_needs_far_branch(address addr) {
- // codecache size <= 128M
- if (!MacroAssembler::far_branches()) {
- return false;
- }
- // codecache size > 240M
- if (MacroAssembler::codestub_branch_needs_far_jump()) {
- return true;
- }
- // codecache size: 128M..240M
- return !CodeCache::is_non_nmethod(addr);
-}
-
void MacroAssembler::far_call(Address entry, CodeBuffer *cbuf, Register tmp) {
assert(ReservedCodeCacheSize < 4*G, "branch out of range");
assert(CodeCache::find_blob(entry.target()) != NULL,
"destination of far call not found in code cache");
- if (target_needs_far_branch(entry.target())) {
+ if (far_branches()) {
uint64_t offset;
// We can use ADRP here because we know that the total size of
- // the code cache cannot exceed 2Gb (ADRP limit is 4GB).
+ // the code cache cannot exceed 2Gb.
adrp(tmp, entry, offset);
add(tmp, tmp, offset);
if (cbuf) cbuf->set_insts_mark();
@@ -428,15 +415,14 @@ void MacroAssembler::far_call(Address entry, CodeBuffer *cbuf, Register tmp) {
}
}
-int MacroAssembler::far_jump(Address entry, CodeBuffer *cbuf, Register tmp) {
+void MacroAssembler::far_jump(Address entry, CodeBuffer *cbuf, Register tmp) {
assert(ReservedCodeCacheSize < 4*G, "branch out of range");
assert(CodeCache::find_blob(entry.target()) != NULL,
"destination of far call not found in code cache");
- address start = pc();
- if (target_needs_far_branch(entry.target())) {
+ if (far_branches()) {
uint64_t offset;
// We can use ADRP here because we know that the total size of
- // the code cache cannot exceed 2Gb (ADRP limit is 4GB).
+ // the code cache cannot exceed 2Gb.
adrp(tmp, entry, offset);
add(tmp, tmp, offset);
if (cbuf) cbuf->set_insts_mark();
@@ -445,7 +431,6 @@ int MacroAssembler::far_jump(Address entry, CodeBuffer *cbuf, Register tmp) {
if (cbuf) cbuf->set_insts_mark();
b(entry);
}
- return pc() - start;
}
void MacroAssembler::reserved_stack_check() {
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
index e403289e2..06733edd6 100644
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
@@ -1086,18 +1086,13 @@ public:
return ReservedCodeCacheSize > branch_range;
}
- // Check if branches to the the non nmethod section require a far jump
- static bool codestub_branch_needs_far_jump() {
- return CodeCache::max_distance_to_non_nmethod() > branch_range;
- }
-
// Jumps that can reach anywhere in the code cache.
// Trashes tmp.
void far_call(Address entry, CodeBuffer *cbuf = NULL, Register tmp = rscratch1);
- int far_jump(Address entry, CodeBuffer *cbuf = NULL, Register tmp = rscratch1);
+ void far_jump(Address entry, CodeBuffer *cbuf = NULL, Register tmp = rscratch1);
- static int far_codestub_branch_size() {
- if (codestub_branch_needs_far_jump()) {
+ static int far_branch_size() {
+ if (far_branches()) {
return 3 * 4; // adrp, add, br
} else {
return 4;
diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp
index 28158adbc..1c6aa37b8 100644
--- a/src/hotspot/share/code/codeCache.cpp
+++ b/src/hotspot/share/code/codeCache.cpp
@@ -296,20 +296,19 @@ void CodeCache::initialize_heaps() {
const size_t alignment = MAX2(page_size(false, 8), (size_t) os::vm_allocation_granularity());
non_nmethod_size = align_up(non_nmethod_size, alignment);
profiled_size = align_down(profiled_size, alignment);
- non_profiled_size = align_down(non_profiled_size, alignment);
// Reserve one continuous chunk of memory for CodeHeaps and split it into
// parts for the individual heaps. The memory layout looks like this:
// ---------- high -----------
// Non-profiled nmethods
- // Non-nmethods
// Profiled nmethods
+ // Non-nmethods
// ---------- low ------------
ReservedCodeSpace rs = reserve_heap_memory(cache_size);
- ReservedSpace profiled_space = rs.first_part(profiled_size);
- ReservedSpace rest = rs.last_part(profiled_size);
- ReservedSpace non_method_space = rest.first_part(non_nmethod_size);
- ReservedSpace non_profiled_space = rest.last_part(non_nmethod_size);
+ ReservedSpace non_method_space = rs.first_part(non_nmethod_size);
+ ReservedSpace rest = rs.last_part(non_nmethod_size);
+ ReservedSpace profiled_space = rest.first_part(profiled_size);
+ ReservedSpace non_profiled_space = rest.last_part(profiled_size);
// Non-nmethods (stubs, adapters, ...)
add_heap(non_method_space, "CodeHeap 'non-nmethods'", CodeBlobType::NonNMethod);
@@ -899,23 +898,6 @@ size_t CodeCache::max_capacity() {
return max_cap;
}
-bool CodeCache::is_non_nmethod(address addr) {
- CodeHeap* blob = get_code_heap(CodeBlobType::NonNMethod);
- return blob->contains(addr);
-}
-
-size_t CodeCache::max_distance_to_non_nmethod() {
- if (!SegmentedCodeCache) {
- return ReservedCodeCacheSize;
- } else {
- CodeHeap* blob = get_code_heap(CodeBlobType::NonNMethod);
- // the max distance is minimized by placing the NonNMethod segment
- // in between MethodProfiled and MethodNonProfiled segments
- size_t dist1 = (size_t)blob->high() - (size_t)_low_bound;
- size_t dist2 = (size_t)_high_bound - (size_t)blob->low();
- return dist1 > dist2 ? dist1 : dist2;
- }
-}
// Returns the reverse free ratio. E.g., if 25% (1/4) of the code cache
// is free, reverse_free_ratio() returns 4.
diff --git a/src/hotspot/share/code/codeCache.hpp b/src/hotspot/share/code/codeCache.hpp
index ca3bae1df..b1219de48 100644
--- a/src/hotspot/share/code/codeCache.hpp
+++ b/src/hotspot/share/code/codeCache.hpp
@@ -213,9 +213,6 @@ class CodeCache : AllStatic {
static double reverse_free_ratio();
- static size_t max_distance_to_non_nmethod();
- static bool is_non_nmethod(address addr);
-
static void clear_inline_caches(); // clear all inline caches
static void cleanup_inline_caches(); // clean unloaded/zombie nmethods from inline caches
diff --git a/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java b/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java
deleted file mode 100644
index f47331a6d..000000000
--- a/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 2022, BELLSOFT. 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.
- */
-package compiler.c2.aarch64;
-
-import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.*;
-
-/*
- * @test
- * @bug 8280872
- * @summary Far call to runtime stub should be generated with single instruction for CodeHeap up to 250MB
- * @library /test/lib /
- *
- * @requires vm.flagless
- * @requires os.arch=="aarch64"
- * @requires vm.debug == false
- * @requires vm.compiler2.enabled
- *
- * @run driver compiler.c2.aarch64.TestFarJump
- */
-public class TestFarJump {
-
- // ADRP instruction encoding:
- // |31 30 29 28|27 26 25 24|23 22 21 20|19 18 17 16|15 14 13 12|11 10 09 08|07 06 05 04|03 02 01 10|
- // | 1|immlo| 1 0 0 0 0| immhi | Rd |
- static boolean isADRP(int encoding) {
- final int mask = 0b1001_1111;
- final int val = 0b1001_0000;
- return ((encoding >> 24) & mask) == val;
- }
-
- // Looking for adrp instruction in binary/text assembly output:
- // 0x0000ffff7ff1b7d0: c8ff ffd0 | 0801 1091 | 0001 1fd6
- // 0x0000ffff6bf20ee0: adrp x8, 0x0000ffff6bef1000
- static boolean containsADRP(String input) {
- int index = input.indexOf(": ");
- if (index == -1) {
- return false;
- }
- input = input.substring(index + 1);
- if (input.contains("adrp")) {
- return true;
- }
- Pattern pattern = Pattern.compile("[0-9a-f ]*");
- Matcher matcher = pattern.matcher(input);
- while (matcher.find()) {
- String match = matcher.group();
- match = match.replace(" " , "");
- if (match.length() != 8) {
- continue;
- }
- int dump = (int)Long.parseLong(match, 16);
- int encoding = Integer.reverseBytes(dump);
- // Check the first instruction only. The raw pointer can be confused with the encoded adrp instruction:
- // emit_exception_handler() = far_call() + should_not_reach_here() = ADRP + ADD + BLR + DCPS1 + raw_pointer
- return isADRP(encoding);
- }
- return false;
- }
-
- static void runVM(boolean bigCodeHeap) throws Exception {
- String className = TestFarJump.class.getName();
- String[] procArgs = {
- "-XX:-Inline",
- "-Xcomp",
- "-Xbatch",
- "-XX:+TieredCompilation",
- "-XX:+SegmentedCodeCache",
- "-XX:CompileOnly=" + className + "::main",
- "-XX:ReservedCodeCacheSize=" + (bigCodeHeap ? "256M" : "200M"),
- "-XX:+UnlockDiagnosticVMOptions",
- "-XX:+PrintAssembly",
- className};
-
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(procArgs);
- OutputAnalyzer output = new OutputAnalyzer(pb.start());
- List<String> lines = output.asLines();
-
- ListIterator<String> itr = lines.listIterator();
- while (itr.hasNext()) {
- String line = itr.next();
- if (line.contains("[Exception Handler]")) {
- String next1 = itr.next();
- String next2 = itr.next();
- System.out.println(line);
- System.out.println(next1);
- System.out.println(next2);
- boolean containsADRP = containsADRP(next1) || containsADRP(next2);
- if (bigCodeHeap && !containsADRP) {
- throw new RuntimeException("ADRP instruction is expected on far jump");
- }
- if (!bigCodeHeap && containsADRP) {
- throw new RuntimeException("for CodeHeap < 250MB the far jump is expected to be encoded with a single branch instruction");
- }
- return;
- }
- }
- throw new RuntimeException("Assembly output: exception Handler is not found");
- }
-
- public static void main(String[] args) throws Exception {
- if (args.length == 0) {
- // Main VM: fork VM with options
- runVM(true);
- runVM(false);
- return;
- }
- if (args.length > 0) {
- // We are in a forked VM. Just exit
- System.out.println("Ok");
- }
- }
-}
-
--
2.39.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ridedolphin/openjdk-17.git
git@gitee.com:ridedolphin/openjdk-17.git
ridedolphin
openjdk-17
openjdk-17
master

搜索帮助