Merge
This commit is contained in:
commit
e24c1e8bbd
@ -825,6 +825,17 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return start;
|
||||
}
|
||||
|
||||
// The following routine generates a subroutine to throw an asynchronous
|
||||
// UnknownError when an unsafe access gets a fault that could not be
|
||||
// reasonably prevented by the programmer. (Example: SIGBUS/OBJERR.)
|
||||
//
|
||||
address generate_handler_for_unsafe_access() {
|
||||
StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
|
||||
address start = __ function_entry();
|
||||
__ unimplemented("StubRoutines::handler_for_unsafe_access", 93);
|
||||
return start;
|
||||
}
|
||||
|
||||
#if !defined(PRODUCT)
|
||||
// Wrapper which calls oopDesc::is_oop_or_null()
|
||||
// Only called by MacroAssembler::verify_oop
|
||||
@ -3100,6 +3111,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError), false);
|
||||
StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call), false);
|
||||
|
||||
StubRoutines::_handler_for_unsafe_access_entry = generate_handler_for_unsafe_access();
|
||||
|
||||
// support for verify_oop (must happen after universe_init)
|
||||
StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, 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
|
||||
@ -64,6 +64,20 @@ static const Register& Lstub_temp = L2;
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
// Stub Code definitions
|
||||
|
||||
static address handle_unsafe_access() {
|
||||
JavaThread* thread = JavaThread::current();
|
||||
address pc = thread->saved_exception_pc();
|
||||
address npc = thread->saved_exception_npc();
|
||||
// pc is the instruction which we must emulate
|
||||
// doing a no-op is fine: return garbage from the load
|
||||
|
||||
// request an async exception
|
||||
thread->set_pending_unsafe_access_error();
|
||||
|
||||
// return address of next instruction to execute
|
||||
return npc;
|
||||
}
|
||||
|
||||
class StubGenerator: public StubCodeGenerator {
|
||||
private:
|
||||
|
||||
@ -732,6 +746,62 @@ class StubGenerator: public StubCodeGenerator {
|
||||
Label _atomic_add_stub; // called from other stubs
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
// The following routine generates a subroutine to throw an asynchronous
|
||||
// UnknownError when an unsafe access gets a fault that could not be
|
||||
// reasonably prevented by the programmer. (Example: SIGBUS/OBJERR.)
|
||||
//
|
||||
// Arguments :
|
||||
//
|
||||
// trapping PC: O7
|
||||
//
|
||||
// Results:
|
||||
// posts an asynchronous exception, skips the trapping instruction
|
||||
//
|
||||
|
||||
address generate_handler_for_unsafe_access() {
|
||||
StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
|
||||
address start = __ pc();
|
||||
|
||||
const int preserve_register_words = (64 * 2);
|
||||
Address preserve_addr(FP, (-preserve_register_words * wordSize) + STACK_BIAS);
|
||||
|
||||
Register Lthread = L7_thread_cache;
|
||||
int i;
|
||||
|
||||
__ save_frame(0);
|
||||
__ mov(G1, L1);
|
||||
__ mov(G2, L2);
|
||||
__ mov(G3, L3);
|
||||
__ mov(G4, L4);
|
||||
__ mov(G5, L5);
|
||||
for (i = 0; i < 64; i += 2) {
|
||||
__ stf(FloatRegisterImpl::D, as_FloatRegister(i), preserve_addr, i * wordSize);
|
||||
}
|
||||
|
||||
address entry_point = CAST_FROM_FN_PTR(address, handle_unsafe_access);
|
||||
BLOCK_COMMENT("call handle_unsafe_access");
|
||||
__ call(entry_point, relocInfo::runtime_call_type);
|
||||
__ delayed()->nop();
|
||||
|
||||
__ mov(L1, G1);
|
||||
__ mov(L2, G2);
|
||||
__ mov(L3, G3);
|
||||
__ mov(L4, G4);
|
||||
__ mov(L5, G5);
|
||||
for (i = 0; i < 64; i += 2) {
|
||||
__ ldf(FloatRegisterImpl::D, preserve_addr, as_FloatRegister(i), i * wordSize);
|
||||
}
|
||||
|
||||
__ verify_thread();
|
||||
|
||||
__ jmp(O0, 0);
|
||||
__ delayed()->restore();
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
// Support for uint StubRoutine::Sparc::partial_subtype_check( Klass sub, Klass super );
|
||||
// Arguments :
|
||||
//
|
||||
@ -5310,6 +5380,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError));
|
||||
StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call));
|
||||
|
||||
StubRoutines::_handler_for_unsafe_access_entry =
|
||||
generate_handler_for_unsafe_access();
|
||||
|
||||
// support for verify_oop (must happen after universe_init)
|
||||
StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop_subroutine();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2015, 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
|
||||
@ -63,6 +63,21 @@ const int FPU_CNTRL_WRD_MASK = 0xFFFF;
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
// Stub Code definitions
|
||||
|
||||
static address handle_unsafe_access() {
|
||||
JavaThread* thread = JavaThread::current();
|
||||
address pc = thread->saved_exception_pc();
|
||||
// pc is the instruction which we must emulate
|
||||
// doing a no-op is fine: return garbage from the load
|
||||
// therefore, compute npc
|
||||
address npc = Assembler::locate_next_instruction(pc);
|
||||
|
||||
// request an async exception
|
||||
thread->set_pending_unsafe_access_error();
|
||||
|
||||
// return address of next instruction to execute
|
||||
return npc;
|
||||
}
|
||||
|
||||
class StubGenerator: public StubCodeGenerator {
|
||||
private:
|
||||
|
||||
@ -608,6 +623,27 @@ class StubGenerator: public StubCodeGenerator {
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// The following routine generates a subroutine to throw an asynchronous
|
||||
// UnknownError when an unsafe access gets a fault that could not be
|
||||
// reasonably prevented by the programmer. (Example: SIGBUS/OBJERR.)
|
||||
address generate_handler_for_unsafe_access() {
|
||||
StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
|
||||
address start = __ pc();
|
||||
|
||||
__ push(0); // hole for return address-to-be
|
||||
__ pusha(); // push registers
|
||||
Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord);
|
||||
BLOCK_COMMENT("call handle_unsafe_access");
|
||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access)));
|
||||
__ movptr(next_pc, rax); // stuff next address
|
||||
__ popa();
|
||||
__ ret(0); // jump to next address
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Non-destructive plausibility checks for oops
|
||||
|
||||
@ -3829,6 +3865,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// These are currently used by Solaris/Intel
|
||||
StubRoutines::_atomic_xchg_entry = generate_atomic_xchg();
|
||||
|
||||
StubRoutines::_handler_for_unsafe_access_entry =
|
||||
generate_handler_for_unsafe_access();
|
||||
|
||||
// platform dependent
|
||||
create_control_words();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, 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
|
||||
@ -61,6 +61,21 @@ const int MXCSR_MASK = 0xFFC0; // Mask out any pending exceptions
|
||||
|
||||
// Stub Code definitions
|
||||
|
||||
static address handle_unsafe_access() {
|
||||
JavaThread* thread = JavaThread::current();
|
||||
address pc = thread->saved_exception_pc();
|
||||
// pc is the instruction which we must emulate
|
||||
// doing a no-op is fine: return garbage from the load
|
||||
// therefore, compute npc
|
||||
address npc = Assembler::locate_next_instruction(pc);
|
||||
|
||||
// request an async exception
|
||||
thread->set_pending_unsafe_access_error();
|
||||
|
||||
// return address of next instruction to execute
|
||||
return npc;
|
||||
}
|
||||
|
||||
class StubGenerator: public StubCodeGenerator {
|
||||
private:
|
||||
|
||||
@ -974,6 +989,32 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return start;
|
||||
}
|
||||
|
||||
// The following routine generates a subroutine to throw an
|
||||
// asynchronous UnknownError when an unsafe access gets a fault that
|
||||
// could not be reasonably prevented by the programmer. (Example:
|
||||
// SIGBUS/OBJERR.)
|
||||
address generate_handler_for_unsafe_access() {
|
||||
StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
|
||||
address start = __ pc();
|
||||
|
||||
__ push(0); // hole for return address-to-be
|
||||
__ pusha(); // push registers
|
||||
Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord);
|
||||
|
||||
// FIXME: this probably needs alignment logic
|
||||
|
||||
__ subptr(rsp, frame::arg_reg_save_area_bytes);
|
||||
BLOCK_COMMENT("call handle_unsafe_access");
|
||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access)));
|
||||
__ addptr(rsp, frame::arg_reg_save_area_bytes);
|
||||
|
||||
__ movptr(next_pc, rax); // stuff next address
|
||||
__ popa();
|
||||
__ ret(0); // jump to next address
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
// Non-destructive plausibility checks for oops
|
||||
//
|
||||
// Arguments:
|
||||
@ -5095,6 +5136,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_atomic_add_ptr_entry = generate_atomic_add_ptr();
|
||||
StubRoutines::_fence_entry = generate_orderaccess_fence();
|
||||
|
||||
StubRoutines::_handler_for_unsafe_access_entry =
|
||||
generate_handler_for_unsafe_access();
|
||||
|
||||
// platform dependent
|
||||
StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp();
|
||||
StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2007, 2008, 2010, 2015 Red Hat, Inc.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -261,6 +261,10 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_atomic_add_entry = ShouldNotCallThisStub();
|
||||
StubRoutines::_atomic_add_ptr_entry = ShouldNotCallThisStub();
|
||||
StubRoutines::_fence_entry = ShouldNotCallThisStub();
|
||||
|
||||
// amd64 does this here, sparc does it in generate_all()
|
||||
StubRoutines::_handler_for_unsafe_access_entry =
|
||||
ShouldNotCallThisStub();
|
||||
}
|
||||
|
||||
void generate_all() {
|
||||
|
@ -392,9 +392,11 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
|
||||
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
|
||||
CompiledMethod* nm = cb->as_compiled_method_or_null();
|
||||
if (nm != NULL && nm->has_unsafe_access()) {
|
||||
address next_pc = pc + 4;
|
||||
next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
|
||||
os::Aix::ucontext_set_pc(uc, next_pc);
|
||||
// We don't really need a stub here! Just set the pending exeption and
|
||||
// continue at the next instruction after the faulting read. Returning
|
||||
// garbage from this read is ok.
|
||||
thread->set_pending_unsafe_access_error();
|
||||
os::Aix::ucontext_set_pc(uc, pc + 4);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -413,9 +415,11 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
|
||||
}
|
||||
else if (thread->thread_state() == _thread_in_vm &&
|
||||
sig == SIGBUS && thread->doing_unsafe_access()) {
|
||||
address next_pc = pc + 4;
|
||||
next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
|
||||
os::Aix::ucontext_set_pc(uc, next_pc);
|
||||
// We don't really need a stub here! Just set the pending exeption and
|
||||
// continue at the next instruction after the faulting read. Returning
|
||||
// garbage from this read is ok.
|
||||
thread->set_pending_unsafe_access_error();
|
||||
os::Aix::ucontext_set_pc(uc, pc + 4);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -584,8 +584,7 @@ JVM_handle_bsd_signal(int sig,
|
||||
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
|
||||
CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
|
||||
if (nm != NULL && nm->has_unsafe_access()) {
|
||||
address next_pc = Assembler::locate_next_instruction(pc);
|
||||
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
|
||||
stub = StubRoutines::handler_for_unsafe_access();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -656,8 +655,7 @@ JVM_handle_bsd_signal(int sig,
|
||||
} else if (thread->thread_state() == _thread_in_vm &&
|
||||
sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
|
||||
thread->doing_unsafe_access()) {
|
||||
address next_pc = Assembler::locate_next_instruction(pc);
|
||||
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
|
||||
stub = StubRoutines::handler_for_unsafe_access();
|
||||
}
|
||||
|
||||
// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
|
||||
|
@ -226,6 +226,23 @@ extern "C" void FetchNPFI () ;
|
||||
extern "C" void FetchNResume () ;
|
||||
#endif
|
||||
|
||||
// An operation in Unsafe has faulted. We're going to return to the
|
||||
// instruction after the faulting load or store. We also set
|
||||
// pending_unsafe_access_error so that at some point in the future our
|
||||
// user will get a helpful message.
|
||||
static address handle_unsafe_access(JavaThread* thread, address pc) {
|
||||
// pc is the instruction which we must emulate
|
||||
// doing a no-op is fine: return garbage from the load
|
||||
// therefore, compute npc
|
||||
address npc = pc + NativeCall::instruction_size;
|
||||
|
||||
// request an async exception
|
||||
thread->set_pending_unsafe_access_error();
|
||||
|
||||
// return address of next instruction to execute
|
||||
return npc;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int
|
||||
JVM_handle_linux_signal(int sig,
|
||||
siginfo_t* info,
|
||||
@ -370,8 +387,7 @@ JVM_handle_linux_signal(int sig,
|
||||
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
|
||||
CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
|
||||
if (nm != NULL && nm->has_unsafe_access()) {
|
||||
address next_pc = pc + NativeCall::instruction_size;
|
||||
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
|
||||
stub = handle_unsafe_access(thread, pc);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -392,8 +408,7 @@ JVM_handle_linux_signal(int sig,
|
||||
} else if (thread->thread_state() == _thread_in_vm &&
|
||||
sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
|
||||
thread->doing_unsafe_access()) {
|
||||
address next_pc = pc + NativeCall::instruction_size;
|
||||
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
|
||||
stub = handle_unsafe_access(thread, pc);
|
||||
}
|
||||
|
||||
// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
|
||||
|
@ -366,9 +366,11 @@ JVM_handle_linux_signal(int sig,
|
||||
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
|
||||
CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
|
||||
if (nm != NULL && nm->has_unsafe_access()) {
|
||||
address next_pc = pc + 4;
|
||||
next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
|
||||
os::Linux::ucontext_set_pc(uc, next_pc);
|
||||
// We don't really need a stub here! Just set the pending exeption and
|
||||
// continue at the next instruction after the faulting read. Returning
|
||||
// garbage from this read is ok.
|
||||
thread->set_pending_unsafe_access_error();
|
||||
os::Linux::ucontext_set_pc(uc, pc + 4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -383,8 +385,10 @@ JVM_handle_linux_signal(int sig,
|
||||
}
|
||||
else if (thread->thread_state() == _thread_in_vm &&
|
||||
sig == SIGBUS && thread->doing_unsafe_access()) {
|
||||
address next_pc = pc + 4;
|
||||
next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
|
||||
// We don't really need a stub here! Just set the pending exeption and
|
||||
// continue at the next instruction after the faulting read. Returning
|
||||
// garbage from this read is ok.
|
||||
thread->set_pending_unsafe_access_error();
|
||||
os::Linux::ucontext_set_pc(uc, pc + 4);
|
||||
return true;
|
||||
}
|
||||
|
@ -433,14 +433,14 @@ inline static bool checkPollingPage(address pc, address fault, address* stub) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline static bool checkByteBuffer(address pc, address npc, address* stub) {
|
||||
inline static bool checkByteBuffer(address pc, address* stub) {
|
||||
// BugId 4454115: A read from a MappedByteBuffer can fault
|
||||
// here if the underlying file has been truncated.
|
||||
// Do not crash the VM in such a case.
|
||||
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
|
||||
CompiledMethod* nm = cb->as_compiled_method_or_null();
|
||||
if (nm != NULL && nm->has_unsafe_access()) {
|
||||
*stub = SharedRuntime::handle_unsafe_access(thread, npc);
|
||||
*stub = StubRoutines::handler_for_unsafe_access();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -613,7 +613,7 @@ JVM_handle_linux_signal(int sig,
|
||||
if (sig == SIGBUS &&
|
||||
thread->thread_state() == _thread_in_vm &&
|
||||
thread->doing_unsafe_access()) {
|
||||
stub = SharedRuntime::handle_unsafe_access(thread, npc);
|
||||
stub = StubRoutines::handler_for_unsafe_access();
|
||||
}
|
||||
|
||||
if (thread->thread_state() == _thread_in_Java) {
|
||||
@ -625,7 +625,7 @@ JVM_handle_linux_signal(int sig,
|
||||
break;
|
||||
}
|
||||
|
||||
if ((sig == SIGBUS) && checkByteBuffer(pc, npc, &stub)) {
|
||||
if ((sig == SIGBUS) && checkByteBuffer(pc, &stub)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -420,8 +420,7 @@ JVM_handle_linux_signal(int sig,
|
||||
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
|
||||
CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
|
||||
if (nm != NULL && nm->has_unsafe_access()) {
|
||||
address next_pc = Assembler::locate_next_instruction(pc);
|
||||
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
|
||||
stub = StubRoutines::handler_for_unsafe_access();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -470,8 +469,7 @@ JVM_handle_linux_signal(int sig,
|
||||
} else if (thread->thread_state() == _thread_in_vm &&
|
||||
sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
|
||||
thread->doing_unsafe_access()) {
|
||||
address next_pc = Assembler::locate_next_instruction(pc);
|
||||
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
|
||||
stub = StubRoutines::handler_for_unsafe_access();
|
||||
}
|
||||
|
||||
// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
|
||||
|
@ -441,7 +441,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||
|
||||
if (thread->thread_state() == _thread_in_vm) {
|
||||
if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
|
||||
stub = SharedRuntime::handle_unsafe_access(thread, npc);
|
||||
stub = StubRoutines::handler_for_unsafe_access();
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,7 +480,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
|
||||
CompiledMethod* nm = cb->as_compiled_method_or_null();
|
||||
if (nm != NULL && nm->has_unsafe_access()) {
|
||||
stub = SharedRuntime::handle_unsafe_access(thread, npc);
|
||||
stub = StubRoutines::handler_for_unsafe_access();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -503,8 +503,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||
|
||||
if (thread->thread_state() == _thread_in_vm) {
|
||||
if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
|
||||
address next_pc = Assembler::locate_next_instruction(pc);
|
||||
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
|
||||
stub = StubRoutines::handler_for_unsafe_access();
|
||||
}
|
||||
}
|
||||
|
||||
@ -521,8 +520,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||
if (cb != NULL) {
|
||||
CompiledMethod* nm = cb->as_compiled_method_or_null();
|
||||
if (nm != NULL && nm->has_unsafe_access()) {
|
||||
address next_pc = Assembler::locate_next_instruction(pc);
|
||||
stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
|
||||
stub = StubRoutines::handler_for_unsafe_access();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1762,21 +1762,6 @@ methodHandle SharedRuntime::reresolve_call_site(JavaThread *thread, TRAPS) {
|
||||
return callee_method;
|
||||
}
|
||||
|
||||
address SharedRuntime::handle_unsafe_access(JavaThread* thread, address next_pc) {
|
||||
// The faulting unsafe accesses should be changed to throw the error
|
||||
// synchronously instead. Meanwhile the faulting instruction will be
|
||||
// skipped over (effectively turning it into a no-op) and an
|
||||
// asynchronous exception will be raised which the thread will
|
||||
// handle at a later point. If the instruction is a load it will
|
||||
// return garbage.
|
||||
|
||||
// Request an async exception.
|
||||
thread->set_pending_unsafe_access_error();
|
||||
|
||||
// Return address of next instruction to execute.
|
||||
return next_pc;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void SharedRuntime::check_member_name_argument_is_last_argument(const methodHandle& method,
|
||||
const BasicType* sig_bt,
|
||||
|
@ -522,8 +522,6 @@ class SharedRuntime: AllStatic {
|
||||
static address handle_wrong_method_abstract(JavaThread* thread);
|
||||
static address handle_wrong_method_ic_miss(JavaThread* thread);
|
||||
|
||||
static address handle_unsafe_access(JavaThread* thread, address next_pc);
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
// Collect and print inline cache miss statistics
|
||||
|
@ -55,6 +55,7 @@ address StubRoutines::_throw_IncompatibleClassChangeError_entry = NULL;
|
||||
address StubRoutines::_throw_NullPointerException_at_call_entry = NULL;
|
||||
address StubRoutines::_throw_StackOverflowError_entry = NULL;
|
||||
address StubRoutines::_throw_delayed_StackOverflowError_entry = NULL;
|
||||
address StubRoutines::_handler_for_unsafe_access_entry = NULL;
|
||||
jint StubRoutines::_verify_oop_count = 0;
|
||||
address StubRoutines::_verify_oop_subroutine_entry = NULL;
|
||||
address StubRoutines::_atomic_xchg_entry = NULL;
|
||||
|
@ -111,6 +111,7 @@ class StubRoutines: AllStatic {
|
||||
static address _throw_NullPointerException_at_call_entry;
|
||||
static address _throw_StackOverflowError_entry;
|
||||
static address _throw_delayed_StackOverflowError_entry;
|
||||
static address _handler_for_unsafe_access_entry;
|
||||
|
||||
static address _atomic_xchg_entry;
|
||||
static address _atomic_xchg_ptr_entry;
|
||||
@ -287,6 +288,10 @@ class StubRoutines: AllStatic {
|
||||
static address throw_StackOverflowError_entry() { return _throw_StackOverflowError_entry; }
|
||||
static address throw_delayed_StackOverflowError_entry() { return _throw_delayed_StackOverflowError_entry; }
|
||||
|
||||
// Exceptions during unsafe access - should throw Java exception rather
|
||||
// than crash.
|
||||
static address handler_for_unsafe_access() { return _handler_for_unsafe_access_entry; }
|
||||
|
||||
static address atomic_xchg_entry() { return _atomic_xchg_entry; }
|
||||
static address atomic_xchg_ptr_entry() { return _atomic_xchg_ptr_entry; }
|
||||
static address atomic_store_entry() { return _atomic_store_entry; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user