mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-22 12:04:39 +02:00
6716785: implicit null checks not triggering with CompressedOops
Allocate alignment-sized page(s) below java heap so that memory accesses at heap_base+1page give signal and cause an implicit null check Reviewed-by: kvn, jmasa, phh, jcoomes
This commit is contained in:
parent
575988272e
commit
20dba03e99
23 changed files with 197 additions and 133 deletions
|
@ -2414,8 +2414,20 @@ static bool linux_mprotect(char* addr, size_t size, int prot) {
|
|||
return ::mprotect(bottom, size, prot) == 0;
|
||||
}
|
||||
|
||||
bool os::protect_memory(char* addr, size_t size) {
|
||||
return linux_mprotect(addr, size, PROT_READ);
|
||||
// Set protections specified
|
||||
bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
|
||||
bool is_committed) {
|
||||
unsigned int p = 0;
|
||||
switch (prot) {
|
||||
case MEM_PROT_NONE: p = PROT_NONE; break;
|
||||
case MEM_PROT_READ: p = PROT_READ; break;
|
||||
case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break;
|
||||
case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
// is_committed is unused.
|
||||
return linux_mprotect(addr, bytes, p);
|
||||
}
|
||||
|
||||
bool os::guard_memory(char* addr, size_t size) {
|
||||
|
@ -3704,8 +3716,9 @@ void os::make_polling_page_unreadable(void) {
|
|||
|
||||
// Mark the polling page as readable
|
||||
void os::make_polling_page_readable(void) {
|
||||
if( !protect_memory((char *)_polling_page, Linux::page_size()) )
|
||||
if( !linux_mprotect((char *)_polling_page, Linux::page_size(), PROT_READ)) {
|
||||
fatal("Could not enable polling page");
|
||||
}
|
||||
};
|
||||
|
||||
int os::active_processor_count() {
|
||||
|
|
|
@ -2965,10 +2965,21 @@ static bool solaris_mprotect(char* addr, size_t bytes, int prot) {
|
|||
return retVal == 0;
|
||||
}
|
||||
|
||||
// Protect memory (make it read-only. (Used to pass readonly pages through
|
||||
// Protect memory (Used to pass readonly pages through
|
||||
// JNI GetArray<type>Elements with empty arrays.)
|
||||
bool os::protect_memory(char* addr, size_t bytes) {
|
||||
return solaris_mprotect(addr, bytes, PROT_READ);
|
||||
bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
|
||||
bool is_committed) {
|
||||
unsigned int p = 0;
|
||||
switch (prot) {
|
||||
case MEM_PROT_NONE: p = PROT_NONE; break;
|
||||
case MEM_PROT_READ: p = PROT_READ; break;
|
||||
case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break;
|
||||
case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
// is_committed is unused.
|
||||
return solaris_mprotect(addr, bytes, p);
|
||||
}
|
||||
|
||||
// guard_memory and unguard_memory only happens within stack guard pages.
|
||||
|
|
|
@ -2170,6 +2170,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
|||
// Windows 98 reports faulting addresses incorrectly
|
||||
if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) ||
|
||||
!os::win32::is_nt()) {
|
||||
|
||||
return Handle_Exception(exceptionInfo,
|
||||
SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL));
|
||||
}
|
||||
|
@ -2563,9 +2564,33 @@ bool os::release_memory(char* addr, size_t bytes) {
|
|||
return VirtualFree(addr, 0, MEM_RELEASE) != 0;
|
||||
}
|
||||
|
||||
bool os::protect_memory(char* addr, size_t bytes) {
|
||||
// Set protections specified
|
||||
bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
|
||||
bool is_committed) {
|
||||
unsigned int p = 0;
|
||||
switch (prot) {
|
||||
case MEM_PROT_NONE: p = PAGE_NOACCESS; break;
|
||||
case MEM_PROT_READ: p = PAGE_READONLY; break;
|
||||
case MEM_PROT_RW: p = PAGE_READWRITE; break;
|
||||
case MEM_PROT_RWX: p = PAGE_EXECUTE_READWRITE; break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
DWORD old_status;
|
||||
return VirtualProtect(addr, bytes, PAGE_READONLY, &old_status) != 0;
|
||||
|
||||
// Strange enough, but on Win32 one can change protection only for committed
|
||||
// memory, not a big deal anyway, as bytes less or equal than 64K
|
||||
if (!is_committed && !commit_memory(addr, bytes)) {
|
||||
fatal("cannot commit protection page");
|
||||
}
|
||||
// One cannot use os::guard_memory() here, as on Win32 guard page
|
||||
// have different (one-shot) semantics, from MSDN on PAGE_GUARD:
|
||||
//
|
||||
// Pages in the region become guard pages. Any attempt to access a guard page
|
||||
// causes the system to raise a STATUS_GUARD_PAGE exception and turn off
|
||||
// the guard page status. Guard pages thus act as a one-time access alarm.
|
||||
return VirtualProtect(addr, bytes, p, &old_status) != 0;
|
||||
}
|
||||
|
||||
bool os::guard_memory(char* addr, size_t bytes) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue