Skip to content

Commit cf75f1f

Browse files
dean-longTheRealMDoerroffamitkumar
committed
8358821: patch_verified_entry causes problems, use nmethod entry barriers instead
Co-authored-by: Martin Doerr <[email protected]> Co-authored-by: Amit Kumar <[email protected]> Reviewed-by: mdoerr, eosterlund
1 parent 5252608 commit cf75f1f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+144
-506
lines changed

src/hotspot/cpu/aarch64/aarch64.ad

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,10 +1765,6 @@ void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
17651765
// n.b. frame size includes space for return pc and rfp
17661766
const int framesize = C->output()->frame_size_in_bytes();
17671767

1768-
// insert a nop at the start of the prolog so we can patch in a
1769-
// branch if we need to invalidate the method later
1770-
__ nop();
1771-
17721768
if (C->clinit_barrier_on_entry()) {
17731769
assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
17741770

src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,6 @@ void NativeMovRegMem::verify() {
212212

213213
void NativeJump::verify() { ; }
214214

215-
216-
void NativeJump::check_verified_entry_alignment(address entry, address verified_entry) {
217-
}
218-
219-
220215
address NativeJump::jump_destination() const {
221216
address dest = MacroAssembler::target_addr_for_insn_or_null(instruction_address());
222217

@@ -345,10 +340,6 @@ bool NativeInstruction::is_movk() {
345340
return Instruction_aarch64::extract(int_at(0), 30, 23) == 0b11100101;
346341
}
347342

348-
bool NativeInstruction::is_sigill_not_entrant() {
349-
return uint_at(0) == 0xd4bbd5a1; // dcps1 #0xdead
350-
}
351-
352343
void NativeIllegalInstruction::insert(address code_pos) {
353344
*(juint*)code_pos = 0xd4bbd5a1; // dcps1 #0xdead
354345
}
@@ -359,31 +350,6 @@ bool NativeInstruction::is_stop() {
359350

360351
//-------------------------------------------------------------------
361352

362-
// MT-safe inserting of a jump over a jump or a nop (used by
363-
// nmethod::make_not_entrant)
364-
365-
void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {
366-
367-
assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "expected fixed destination of patch");
368-
assert(nativeInstruction_at(verified_entry)->is_jump_or_nop()
369-
|| nativeInstruction_at(verified_entry)->is_sigill_not_entrant(),
370-
"Aarch64 cannot replace non-jump with jump");
371-
372-
// Patch this nmethod atomically.
373-
if (Assembler::reachable_from_branch_at(verified_entry, dest)) {
374-
ptrdiff_t disp = dest - verified_entry;
375-
guarantee(disp < 1 << 27 && disp > - (1 << 27), "branch overflow");
376-
377-
unsigned int insn = (0b000101 << 26) | ((disp >> 2) & 0x3ffffff);
378-
*(unsigned int*)verified_entry = insn;
379-
} else {
380-
// We use an illegal instruction for marking a method as not_entrant.
381-
NativeIllegalInstruction::insert(verified_entry);
382-
}
383-
384-
ICache::invalidate_range(verified_entry, instruction_size);
385-
}
386-
387353
void NativeGeneralJump::verify() { }
388354

389355
// MT-safe patching of a long jump instruction.

src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ class NativeInstruction {
8383
bool is_safepoint_poll();
8484
bool is_movz();
8585
bool is_movk();
86-
bool is_sigill_not_entrant();
8786
bool is_stop();
8887

8988
protected:
@@ -360,9 +359,6 @@ class NativeJump: public NativeInstruction {
360359

361360
// Insertion of native jump instruction
362361
static void insert(address code_pos, address entry);
363-
// MT-safe insertion of native jump at verified method entry
364-
static void check_verified_entry_alignment(address entry, address verified_entry);
365-
static void patch_verified_entry(address entry, address verified_entry, address dest);
366362
};
367363

368364
inline NativeJump* nativeJump_at(address address) {

src/hotspot/cpu/arm/gc/shared/barrierSetAssembler_arm.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,7 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm) {
193193
__ bind(guard);
194194

195195
// nmethod guard value. Skipped over in common case.
196-
//
197-
// Put a debug value to make any offsets skew
198-
// clearly visible in coredump
199-
__ emit_int32(0xDEADBEAF);
196+
__ emit_int32(0); // initial armed value, will be reset later
200197

201198
__ bind(skip);
202199
__ block_comment("nmethod_barrier end");

src/hotspot/cpu/arm/nativeInst_arm_32.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -282,16 +282,6 @@ void NativeMovConstReg::set_pc_relative_offset(address addr, address pc) {
282282
}
283283
}
284284

285-
void RawNativeJump::check_verified_entry_alignment(address entry, address verified_entry) {
286-
}
287-
288-
void RawNativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {
289-
assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "should be");
290-
int *a = (int *)verified_entry;
291-
a[0] = not_entrant_illegal_instruction; // always illegal
292-
ICache::invalidate_range((address)&a[0], sizeof a[0]);
293-
}
294-
295285
void NativeGeneralJump::insert_unconditional(address code_pos, address entry) {
296286
int offset = (int)(entry - code_pos - 8);
297287
assert(offset < 0x2000000 && offset > -0x2000000, "encoding constraint");

src/hotspot/cpu/arm/nativeInst_arm_32.hpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -61,10 +61,6 @@ class RawNativeInstruction {
6161
instr_fld_fst = 0xd0
6262
};
6363

64-
// illegal instruction used by NativeJump::patch_verified_entry
65-
// permanently undefined (UDF): 0xe << 28 | 0b1111111 << 20 | 0b1111 << 4
66-
static const int not_entrant_illegal_instruction = 0xe7f000f0;
67-
6864
static int decode_rotated_imm12(int encoding) {
6965
int base = encoding & 0xff;
7066
int right_rotation = (encoding & 0xf00) >> 7;
@@ -274,10 +270,6 @@ class RawNativeJump: public NativeInstruction {
274270
}
275271
}
276272

277-
static void check_verified_entry_alignment(address entry, address verified_entry);
278-
279-
static void patch_verified_entry(address entry, address verified_entry, address dest);
280-
281273
};
282274

283275
inline RawNativeJump* rawNativeJump_at(address address) {

src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ void C1_MacroAssembler::explicit_null_check(Register base) {
4646

4747

4848
void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
49-
// Avoid stack bang as first instruction. It may get overwritten by patch_verified_entry.
5049
const Register return_pc = R20;
5150
mflr(return_pc);
5251

src/hotspot/cpu/ppc/nativeInst_ppc.cpp

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,6 @@
3939
#include "c1/c1_Runtime1.hpp"
4040
#endif
4141

42-
// We use an illtrap for marking a method as not_entrant
43-
// Work around a C++ compiler bug which changes 'this'
44-
bool NativeInstruction::is_sigill_not_entrant_at(address addr) {
45-
if (!Assembler::is_illtrap(addr)) return false;
46-
CodeBlob* cb = CodeCache::find_blob(addr);
47-
if (cb == nullptr || !cb->is_nmethod()) return false;
48-
nmethod *nm = (nmethod *)cb;
49-
// This method is not_entrant iff the illtrap instruction is
50-
// located at the verified entry point.
51-
return nm->verified_entry_point() == addr;
52-
}
53-
5442
#ifdef ASSERT
5543
void NativeInstruction::verify() {
5644
// Make sure code pattern is actually an instruction address.
@@ -331,25 +319,6 @@ void NativeMovConstReg::verify() {
331319
}
332320
#endif // ASSERT
333321

334-
void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {
335-
ResourceMark rm;
336-
int code_size = 1 * BytesPerInstWord;
337-
CodeBuffer cb(verified_entry, code_size + 1);
338-
MacroAssembler* a = new MacroAssembler(&cb);
339-
#ifdef COMPILER2
340-
assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "expected fixed destination of patch");
341-
#endif
342-
// Patch this nmethod atomically. Always use illtrap/trap in debug build.
343-
if (DEBUG_ONLY(false &&) a->is_within_range_of_b(dest, a->pc())) {
344-
a->b(dest);
345-
} else {
346-
// The signal handler will continue at dest=OptoRuntime::handle_wrong_method_stub().
347-
// We use an illtrap for marking a method as not_entrant.
348-
a->illtrap();
349-
}
350-
ICache::ppc64_flush_icache_bytes(verified_entry, code_size);
351-
}
352-
353322
#ifdef ASSERT
354323
void NativeJump::verify() {
355324
address addr = addr_at(0);
@@ -462,9 +431,7 @@ bool NativeDeoptInstruction::is_deopt_at(address code_pos) {
462431
if (!Assembler::is_illtrap(code_pos)) return false;
463432
CodeBlob* cb = CodeCache::find_blob(code_pos);
464433
if (cb == nullptr || !cb->is_nmethod()) return false;
465-
nmethod *nm = (nmethod *)cb;
466-
// see NativeInstruction::is_sigill_not_entrant_at()
467-
return nm->verified_entry_point() != code_pos;
434+
return true;
468435
}
469436

470437
// Inserts an instruction which is specified to cause a SIGILL at a given pc

src/hotspot/cpu/ppc/nativeInst_ppc.hpp

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2012, 2024 SAP SE. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
@@ -69,13 +69,6 @@ class NativeInstruction {
6969
return MacroAssembler::tdi_get_si16(long_at(0), Assembler::traptoUnconditional, 0);
7070
}
7171

72-
// We use an illtrap for marking a method as not_entrant.
73-
bool is_sigill_not_entrant() {
74-
// Work around a C++ compiler bug which changes 'this'.
75-
return NativeInstruction::is_sigill_not_entrant_at(addr_at(0));
76-
}
77-
static bool is_sigill_not_entrant_at(address addr);
78-
7972
#ifdef COMPILER2
8073
// SIGTRAP-based implicit range checks
8174
bool is_sigtrap_range_check() {
@@ -328,15 +321,7 @@ class NativeJump: public NativeInstruction {
328321
}
329322
}
330323

331-
// MT-safe insertion of native jump at verified method entry
332-
static void patch_verified_entry(address entry, address verified_entry, address dest);
333-
334324
void verify() NOT_DEBUG_RETURN;
335-
336-
static void check_verified_entry_alignment(address entry, address verified_entry) {
337-
// We just patch one instruction on ppc64, so the jump doesn't have to
338-
// be aligned. Nothing to do here.
339-
}
340325
};
341326

342327
// Instantiates a NativeJump object starting at the given instruction

src/hotspot/cpu/ppc/ppc.ad

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,12 +1493,7 @@ void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
14931493
const Register toc_temp = R23;
14941494
assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp);
14951495

1496-
if (method_is_frameless) {
1497-
// Add nop at beginning of all frameless methods to prevent any
1498-
// oop instructions from getting overwritten by make_not_entrant
1499-
// (patching attempt would fail).
1500-
__ nop();
1501-
} else {
1496+
if (!method_is_frameless) {
15021497
// Get return pc.
15031498
__ mflr(return_pc);
15041499
}

src/hotspot/cpu/riscv/nativeInst_riscv.cpp

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -356,18 +356,6 @@ void NativeMovRegMem::verify() {
356356

357357
void NativeJump::verify() { }
358358

359-
360-
void NativeJump::check_verified_entry_alignment(address entry, address verified_entry) {
361-
// Patching to not_entrant can happen while activations of the method are
362-
// in use. The patching in that instance must happen only when certain
363-
// alignment restrictions are true. These guarantees check those
364-
// conditions.
365-
366-
// Must be 4 bytes aligned
367-
MacroAssembler::assert_alignment(verified_entry);
368-
}
369-
370-
371359
address NativeJump::jump_destination() const {
372360
address dest = MacroAssembler::target_addr_for_insn(instruction_address());
373361

@@ -420,12 +408,6 @@ bool NativeInstruction::is_safepoint_poll() {
420408
return MacroAssembler::is_lwu_to_zr(address(this));
421409
}
422410

423-
// A 16-bit instruction with all bits ones is permanently reserved as an illegal instruction.
424-
bool NativeInstruction::is_sigill_not_entrant() {
425-
// jvmci
426-
return uint_at(0) == 0xffffffff;
427-
}
428-
429411
void NativeIllegalInstruction::insert(address code_pos) {
430412
assert_cond(code_pos != nullptr);
431413
Assembler::sd_instr(code_pos, 0xffffffff); // all bits ones is permanently reserved as an illegal instruction
@@ -437,45 +419,6 @@ bool NativeInstruction::is_stop() {
437419

438420
//-------------------------------------------------------------------
439421

440-
// MT-safe inserting of a jump over a jump or a nop (used by
441-
// nmethod::make_not_entrant)
442-
443-
void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {
444-
445-
assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "expected fixed destination of patch");
446-
447-
assert(nativeInstruction_at(verified_entry)->is_jump_or_nop() ||
448-
nativeInstruction_at(verified_entry)->is_sigill_not_entrant(),
449-
"riscv cannot replace non-jump with jump");
450-
451-
check_verified_entry_alignment(entry, verified_entry);
452-
453-
// Patch this nmethod atomically.
454-
if (Assembler::reachable_from_branch_at(verified_entry, dest)) {
455-
ptrdiff_t offset = dest - verified_entry;
456-
guarantee(Assembler::is_simm21(offset) && ((offset % 2) == 0),
457-
"offset is too large to be patched in one jal instruction."); // 1M
458-
459-
uint32_t insn = 0;
460-
address pInsn = (address)&insn;
461-
Assembler::patch(pInsn, 31, 31, (offset >> 20) & 0x1);
462-
Assembler::patch(pInsn, 30, 21, (offset >> 1) & 0x3ff);
463-
Assembler::patch(pInsn, 20, 20, (offset >> 11) & 0x1);
464-
Assembler::patch(pInsn, 19, 12, (offset >> 12) & 0xff);
465-
Assembler::patch(pInsn, 11, 7, 0); // zero, no link jump
466-
Assembler::patch(pInsn, 6, 0, 0b1101111); // j, (jal x0 offset)
467-
Assembler::sd_instr(verified_entry, insn);
468-
} else {
469-
// We use an illegal instruction for marking a method as
470-
// not_entrant.
471-
NativeIllegalInstruction::insert(verified_entry);
472-
}
473-
474-
ICache::invalidate_range(verified_entry, instruction_size);
475-
}
476-
477-
//-------------------------------------------------------------------
478-
479422
void NativeGeneralJump::insert_unconditional(address code_pos, address entry) {
480423
CodeBuffer cb(code_pos, instruction_size);
481424
MacroAssembler a(&cb);

src/hotspot/cpu/riscv/nativeInst_riscv.hpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2014, 2018, Red Hat Inc. All rights reserved.
44
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
55
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -74,7 +74,6 @@ class NativeInstruction {
7474
bool is_nop() const;
7575
bool is_jump_or_nop();
7676
bool is_safepoint_poll();
77-
bool is_sigill_not_entrant();
7877
bool is_stop();
7978

8079
protected:
@@ -274,9 +273,6 @@ class NativeJump: public NativeInstruction {
274273

275274
// Insertion of native jump instruction
276275
static void insert(address code_pos, address entry);
277-
// MT-safe insertion of native jump at verified method entry
278-
static void check_verified_entry_alignment(address entry, address verified_entry);
279-
static void patch_verified_entry(address entry, address verified_entry, address dest);
280276
};
281277

282278
inline NativeJump* nativeJump_at(address addr) {

src/hotspot/cpu/riscv/riscv.ad

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,14 +1368,6 @@ void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const {
13681368
// n.b. frame size includes space for return pc and fp
13691369
const int framesize = C->output()->frame_size_in_bytes();
13701370

1371-
// insert a nop at the start of the prolog so we can patch in a
1372-
// branch if we need to invalidate the method later
1373-
{
1374-
Assembler::IncompressibleScope scope(masm); // keep the nop as 4 bytes for patching.
1375-
MacroAssembler::assert_alignment(__ pc());
1376-
__ nop(); // 4 bytes
1377-
}
1378-
13791371
assert_cond(C != nullptr);
13801372

13811373
if (C->clinit_barrier_on_entry()) {
@@ -1804,7 +1796,6 @@ void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const
18041796
// This is the unverified entry point.
18051797
__ ic_check(CodeEntryAlignment);
18061798

1807-
// Verified entry point must be properly 4 bytes aligned for patching by NativeJump::patch_verified_entry().
18081799
// ic_check() aligns to CodeEntryAlignment >= InteriorEntryAlignment(min 16) > NativeInstruction::instruction_size(4).
18091800
assert(((__ offset()) % CodeEntryAlignment) == 0, "Misaligned verified entry point");
18101801
}
@@ -8199,7 +8190,7 @@ instruct unnecessary_membar_volatile_rvtso() %{
81998190
ins_cost(0);
82008191

82018192
size(0);
8202-
8193+
82038194
format %{ "#@unnecessary_membar_volatile_rvtso (unnecessary so empty encoding)" %}
82048195
ins_encode %{
82058196
__ block_comment("unnecessary_membar_volatile_rvtso");

0 commit comments

Comments
 (0)