Skip to content
Permalink
Browse files
8290025: Remove the Sweeper
Reviewed-by: stefank, kvn, iveresov, coleenp, vlivanov, mdoerr
  • Loading branch information
fisk committed Aug 25, 2022
1 parent dc7e256 commit 054c23f
Show file tree
Hide file tree
Showing 188 changed files with 1,106 additions and 3,532 deletions.
@@ -188,16 +188,11 @@ bool frame::safe_for_sender(JavaThread *thread) {
}

// We must always be able to find a recognizable pc
CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
CodeBlob* sender_blob = CodeCache::find_blob(sender_pc);
if (sender_pc == NULL || sender_blob == NULL) {
return false;
}

// Could be a zombie method
if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
return false;
}

// Could just be some random pointer within the codeBlob
if (!sender_blob->code_contains(sender_pc)) {
return false;
@@ -165,10 +165,8 @@ inline frame::frame(intptr_t* sp, intptr_t* fp) {
DEBUG_ONLY(_frame_index = -1;)

// Here's a sticky one. This constructor can be called via AsyncGetCallTrace
// when last_Java_sp is non-null but the pc fetched is junk. If we are truly
// unlucky the junk value could be to a zombied method and we'll die on the
// find_blob call. This is also why we can have no asserts on the validity
// of the pc we find here. AsyncGetCallTrace -> pd_get_top_frame_for_signal_handler
// when last_Java_sp is non-null but the pc fetched is junk.
// AsyncGetCallTrace -> pd_get_top_frame_for_signal_handler
// -> pd_last_frame should use a specialized version of pd_last_frame which could
// call a specilaized frame constructor instead of this one.
// Then we could use the assert below. However this assert is of somewhat dubious
@@ -160,7 +160,7 @@ address NativeCall::destination() const {
address destination = instruction_address() + displacement();

// Do we use a trampoline stub for this call?
CodeBlob* cb = CodeCache::find_blob_unsafe(addr); // Else we get assertion if nmethod is zombie.
CodeBlob* cb = CodeCache::find_blob(addr);
assert(cb && cb->is_nmethod(), "sanity");
nmethod *nm = (nmethod *)cb;
if (nm->stub_contains(destination) && is_NativeCallTrampolineStub_at(destination)) {
@@ -456,7 +456,7 @@ bool NativeInstruction::is_movk() {
return Instruction_aarch64::extract(int_at(0), 30, 23) == 0b11100101;
}

bool NativeInstruction::is_sigill_zombie_not_entrant() {
bool NativeInstruction::is_sigill_not_entrant() {
return uint_at(0) == 0xd4bbd5a1; // dcps1 #0xdead
}

@@ -471,13 +471,13 @@ bool NativeInstruction::is_stop() {
//-------------------------------------------------------------------

// MT-safe inserting of a jump over a jump or a nop (used by
// nmethod::make_not_entrant_or_zombie)
// nmethod::make_not_entrant)

void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {

assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "expected fixed destination of patch");
assert(nativeInstruction_at(verified_entry)->is_jump_or_nop()
|| nativeInstruction_at(verified_entry)->is_sigill_zombie_not_entrant(),
|| nativeInstruction_at(verified_entry)->is_sigill_not_entrant(),
"Aarch64 cannot replace non-jump with jump");

// Patch this nmethod atomically.
@@ -488,8 +488,7 @@ void NativeJump::patch_verified_entry(address entry, address verified_entry, add
unsigned int insn = (0b000101 << 26) | ((disp >> 2) & 0x3ffffff);
*(unsigned int*)verified_entry = insn;
} else {
// We use an illegal instruction for marking a method as
// not_entrant or zombie.
// We use an illegal instruction for marking a method as not_entrant.
NativeIllegalInstruction::insert(verified_entry);
}

@@ -79,7 +79,7 @@ class NativeInstruction {
bool is_safepoint_poll();
bool is_movz();
bool is_movk();
bool is_sigill_zombie_not_entrant();
bool is_sigill_not_entrant();
bool is_stop();

protected:
@@ -123,7 +123,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
}

// We must always be able to find a recognizable pc
CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
CodeBlob* sender_blob = CodeCache::find_blob(sender_pc);
if (sender_pc == NULL || sender_blob == NULL) {
return false;
}
@@ -148,10 +148,6 @@ bool frame::safe_for_sender(JavaThread *thread) {
return sender.is_interpreted_frame_valid(thread);
}

if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
return false;
}

// Could just be some random pointer within the codeBlob
if (!sender_blob->code_contains(sender_pc)) {
return false;
@@ -290,7 +290,7 @@ void RawNativeJump::check_verified_entry_alignment(address entry, address verifi
void RawNativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {
assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "should be");
int *a = (int *)verified_entry;
a[0] = zombie_illegal_instruction; // always illegal
a[0] = not_entrant_illegal_instruction; // always illegal
ICache::invalidate_range((address)&a[0], sizeof a[0]);
}

@@ -63,7 +63,7 @@ class RawNativeInstruction {

// illegal instruction used by NativeJump::patch_verified_entry
// permanently undefined (UDF): 0xe << 28 | 0b1111111 << 20 | 0b1111 << 4
static const int zombie_illegal_instruction = 0xe7f000f0;
static const int not_entrant_illegal_instruction = 0xe7f000f0;

static int decode_rotated_imm12(int encoding) {
int base = encoding & 0xff;
@@ -119,16 +119,11 @@ bool frame::safe_for_sender(JavaThread *thread) {
address sender_pc = (address) sender_abi->lr;;

// We must always be able to find a recognizable pc.
CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
CodeBlob* sender_blob = CodeCache::find_blob(sender_pc);
if (sender_blob == NULL) {
return false;
}

// Could be a zombie method
if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
return false;
}

// It should be safe to construct the sender though it might not be valid.

frame sender(sender_sp, sender_pc);
@@ -122,7 +122,12 @@ void BarrierSetNMethod::disarm(nmethod* nm) {
}

void BarrierSetNMethod::arm(nmethod* nm, int arm_value) {
Unimplemented();
if (!supports_entry_barrier(nm)) {
return;
}

NativeNMethodBarrier* barrier = get_nmethod_barrier(nm);
barrier->release_set_guard_value(arm_value);
}

bool BarrierSetNMethod::is_armed(nmethod* nm) {
@@ -40,14 +40,14 @@
#include "c1/c1_Runtime1.hpp"
#endif

// We use an illtrap for marking a method as not_entrant or zombie
// We use an illtrap for marking a method as not_entrant
// Work around a C++ compiler bug which changes 'this'
bool NativeInstruction::is_sigill_zombie_not_entrant_at(address addr) {
bool NativeInstruction::is_sigill_not_entrant_at(address addr) {
if (*(int*)addr != 0 /*illtrap*/) return false;
CodeBlob* cb = CodeCache::find_blob_unsafe(addr);
CodeBlob* cb = CodeCache::find_blob(addr);
if (cb == NULL || !cb->is_nmethod()) return false;
nmethod *nm = (nmethod *)cb;
// This method is not_entrant or zombie iff the illtrap instruction is
// This method is not_entrant iff the illtrap instruction is
// located at the verified entry point.
return nm->verified_entry_point() == addr;
}
@@ -71,7 +71,7 @@ address NativeCall::destination() const {
// Trampoline stubs are located behind the main code.
if (destination > addr) {
// Filter out recursive method invocation (call to verified/unverified entry point).
CodeBlob* cb = CodeCache::find_blob_unsafe(addr); // Else we get assertion if nmethod is zombie.
CodeBlob* cb = CodeCache::find_blob(addr);
assert(cb && cb->is_nmethod(), "sanity");
nmethod *nm = (nmethod *)cb;
if (nm->stub_contains(destination) && is_NativeCallTrampolineStub_at(destination)) {
@@ -196,7 +196,7 @@ intptr_t NativeMovConstReg::data() const {
return MacroAssembler::get_const(addr);
}

CodeBlob* cb = CodeCache::find_blob_unsafe(addr);
CodeBlob* cb = CodeCache::find_blob(addr);
assert(cb != NULL, "Could not find code blob");
if (MacroAssembler::is_set_narrow_oop(addr, cb->content_begin())) {
narrowOop no = MacroAssembler::get_narrow_oop(addr, cb->content_begin());
@@ -318,7 +318,7 @@ void NativeMovConstReg::verify() {
address addr = addr_at(0);
if (! MacroAssembler::is_load_const_at(addr) &&
! MacroAssembler::is_load_const_from_method_toc_at(addr)) {
CodeBlob* cb = CodeCache::find_blob_unsafe(addr); // find_nmethod() asserts if nmethod is zombie.
CodeBlob* cb = CodeCache::find_blob(addr);
if (! (cb != NULL && MacroAssembler::is_calculate_address_from_global_toc_at(addr, cb->content_begin())) &&
! (cb != NULL && MacroAssembler::is_set_narrow_oop(addr, cb->content_begin())) &&
! MacroAssembler::is_bl(*((int*) addr))) {
@@ -343,7 +343,7 @@ void NativeJump::patch_verified_entry(address entry, address verified_entry, add
a->b(dest);
} else {
// The signal handler will continue at dest=OptoRuntime::handle_wrong_method_stub().
// We use an illtrap for marking a method as not_entrant or zombie.
// We use an illtrap for marking a method as not_entrant.
a->illtrap();
}
ICache::ppc64_flush_icache_bytes(verified_entry, code_size);
@@ -406,7 +406,7 @@ address NativeCallTrampolineStub::encoded_destination_addr() const {
}

address NativeCallTrampolineStub::destination(nmethod *nm) const {
CodeBlob* cb = nm ? nm : CodeCache::find_blob_unsafe(addr_at(0));
CodeBlob* cb = nm ? nm : CodeCache::find_blob(addr_at(0));
assert(cb != NULL, "Could not find code blob");
address ctable = cb->content_begin();

@@ -67,12 +67,12 @@ class NativeInstruction {
return MacroAssembler::tdi_get_si16(long_at(0), Assembler::traptoUnconditional, 0);
}

// We use an illtrap for marking a method as not_entrant or zombie.
bool is_sigill_zombie_not_entrant() {
// We use an illtrap for marking a method as not_entrant.
bool is_sigill_not_entrant() {
// Work around a C++ compiler bug which changes 'this'.
return NativeInstruction::is_sigill_zombie_not_entrant_at(addr_at(0));
return NativeInstruction::is_sigill_not_entrant_at(addr_at(0));
}
static bool is_sigill_zombie_not_entrant_at(address addr);
static bool is_sigill_not_entrant_at(address addr);

#ifdef COMPILER2
// SIGTRAP-based implicit range checks
@@ -175,16 +175,11 @@ bool frame::safe_for_sender(JavaThread *thread) {
}

// We must always be able to find a recognizable pc
CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
CodeBlob* sender_blob = CodeCache::find_blob(sender_pc);
if (sender_pc == NULL || sender_blob == NULL) {
return false;
}

// Could be a zombie method
if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
return false;
}

// Could just be some random pointer within the codeBlob
if (!sender_blob->code_contains(sender_pc)) {
return false;
@@ -115,10 +115,8 @@ inline frame::frame(intptr_t* ptr_sp, intptr_t* ptr_fp) {
_pc = (address)(ptr_sp[-1]);

// Here's a sticky one. This constructor can be called via AsyncGetCallTrace
// when last_Java_sp is non-null but the pc fetched is junk. If we are truly
// unlucky the junk value could be to a zombied method and we'll die on the
// find_blob call. This is also why we can have no asserts on the validity
// of the pc we find here. AsyncGetCallTrace -> pd_get_top_frame_for_signal_handler
// when last_Java_sp is non-null but the pc fetched is junk.
// AsyncGetCallTrace -> pd_get_top_frame_for_signal_handler
// -> pd_last_frame should use a specialized version of pd_last_frame which could
// call a specilaized frame constructor instead of this one.
// Then we could use the assert below. However this assert is of somewhat dubious