mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 22:34:27 +02:00
8009026: [parfait] Null pointer deference in hotspot/src/share/vm/code/nmethod.cpp
Add guarantee() to nmethod constructor and checks to ensure CodeCache has space before allocation Reviewed-by: kvn
This commit is contained in:
parent
69a1275cf2
commit
981e9c35c9
2 changed files with 35 additions and 24 deletions
|
@ -156,6 +156,11 @@ class CodeCache : AllStatic {
|
||||||
static address low_bound() { return (address) _heap->low_boundary(); }
|
static address low_bound() { return (address) _heap->low_boundary(); }
|
||||||
static address high_bound() { return (address) _heap->high_boundary(); }
|
static address high_bound() { return (address) _heap->high_boundary(); }
|
||||||
|
|
||||||
|
static bool has_space(int size) {
|
||||||
|
// Always leave some room in the CodeCache for I2C/C2I adapters
|
||||||
|
return largest_free_block() > (CodeCacheMinimumFreeSpace + size);
|
||||||
|
}
|
||||||
|
|
||||||
// Profiling
|
// Profiling
|
||||||
static address first_address(); // first address used for CodeBlobs
|
static address first_address(); // first address used for CodeBlobs
|
||||||
static address last_address(); // last address used for CodeBlobs
|
static address last_address(); // last address used for CodeBlobs
|
||||||
|
|
|
@ -486,7 +486,6 @@ void nmethod::init_defaults() {
|
||||||
#endif // def HAVE_DTRACE_H
|
#endif // def HAVE_DTRACE_H
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
nmethod* nmethod::new_native_nmethod(methodHandle method,
|
nmethod* nmethod::new_native_nmethod(methodHandle method,
|
||||||
int compile_id,
|
int compile_id,
|
||||||
CodeBuffer *code_buffer,
|
CodeBuffer *code_buffer,
|
||||||
|
@ -502,17 +501,19 @@ nmethod* nmethod::new_native_nmethod(methodHandle method,
|
||||||
{
|
{
|
||||||
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||||
int native_nmethod_size = allocation_size(code_buffer, sizeof(nmethod));
|
int native_nmethod_size = allocation_size(code_buffer, sizeof(nmethod));
|
||||||
CodeOffsets offsets;
|
if (CodeCache::has_space(native_nmethod_size)) {
|
||||||
offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
|
CodeOffsets offsets;
|
||||||
offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
|
offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
|
||||||
nm = new (native_nmethod_size)
|
offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
|
||||||
nmethod(method(), native_nmethod_size, compile_id, &offsets,
|
nm = new (native_nmethod_size) nmethod(method(), native_nmethod_size,
|
||||||
code_buffer, frame_size,
|
compile_id, &offsets,
|
||||||
basic_lock_owner_sp_offset, basic_lock_sp_offset,
|
code_buffer, frame_size,
|
||||||
oop_maps);
|
basic_lock_owner_sp_offset,
|
||||||
NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_native_nmethod(nm));
|
basic_lock_sp_offset, oop_maps);
|
||||||
if (PrintAssembly && nm != NULL)
|
NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_native_nmethod(nm));
|
||||||
Disassembler::decode(nm);
|
if (PrintAssembly && nm != NULL)
|
||||||
|
Disassembler::decode(nm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// verify nmethod
|
// verify nmethod
|
||||||
debug_only(if (nm) nm->verify();) // might block
|
debug_only(if (nm) nm->verify();) // might block
|
||||||
|
@ -537,16 +538,19 @@ nmethod* nmethod::new_dtrace_nmethod(methodHandle method,
|
||||||
{
|
{
|
||||||
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||||
int nmethod_size = allocation_size(code_buffer, sizeof(nmethod));
|
int nmethod_size = allocation_size(code_buffer, sizeof(nmethod));
|
||||||
CodeOffsets offsets;
|
if (CodeCache::has_space(nmethod_size)) {
|
||||||
offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
|
CodeOffsets offsets;
|
||||||
offsets.set_value(CodeOffsets::Dtrace_trap, trap_offset);
|
offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
|
||||||
offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
|
offsets.set_value(CodeOffsets::Dtrace_trap, trap_offset);
|
||||||
|
offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
|
||||||
|
|
||||||
nm = new (nmethod_size) nmethod(method(), nmethod_size, &offsets, code_buffer, frame_size);
|
nm = new (nmethod_size) nmethod(method(), nmethod_size,
|
||||||
|
&offsets, code_buffer, frame_size);
|
||||||
|
|
||||||
NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_nmethod(nm));
|
NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_nmethod(nm));
|
||||||
if (PrintAssembly && nm != NULL)
|
if (PrintAssembly && nm != NULL)
|
||||||
Disassembler::decode(nm);
|
Disassembler::decode(nm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// verify nmethod
|
// verify nmethod
|
||||||
debug_only(if (nm) nm->verify();) // might block
|
debug_only(if (nm) nm->verify();) // might block
|
||||||
|
@ -587,7 +591,8 @@ nmethod* nmethod::new_nmethod(methodHandle method,
|
||||||
+ round_to(handler_table->size_in_bytes(), oopSize)
|
+ round_to(handler_table->size_in_bytes(), oopSize)
|
||||||
+ round_to(nul_chk_table->size_in_bytes(), oopSize)
|
+ round_to(nul_chk_table->size_in_bytes(), oopSize)
|
||||||
+ round_to(debug_info->data_size() , oopSize);
|
+ round_to(debug_info->data_size() , oopSize);
|
||||||
nm = new (nmethod_size)
|
if (CodeCache::has_space(nmethod_size)) {
|
||||||
|
nm = new (nmethod_size)
|
||||||
nmethod(method(), nmethod_size, compile_id, entry_bci, offsets,
|
nmethod(method(), nmethod_size, compile_id, entry_bci, offsets,
|
||||||
orig_pc_offset, debug_info, dependencies, code_buffer, frame_size,
|
orig_pc_offset, debug_info, dependencies, code_buffer, frame_size,
|
||||||
oop_maps,
|
oop_maps,
|
||||||
|
@ -595,6 +600,7 @@ nmethod* nmethod::new_nmethod(methodHandle method,
|
||||||
nul_chk_table,
|
nul_chk_table,
|
||||||
compiler,
|
compiler,
|
||||||
comp_level);
|
comp_level);
|
||||||
|
}
|
||||||
if (nm != NULL) {
|
if (nm != NULL) {
|
||||||
// To make dependency checking during class loading fast, record
|
// To make dependency checking during class loading fast, record
|
||||||
// the nmethod dependencies in the classes it is dependent on.
|
// the nmethod dependencies in the classes it is dependent on.
|
||||||
|
@ -793,9 +799,9 @@ nmethod::nmethod(
|
||||||
#endif // def HAVE_DTRACE_H
|
#endif // def HAVE_DTRACE_H
|
||||||
|
|
||||||
void* nmethod::operator new(size_t size, int nmethod_size) {
|
void* nmethod::operator new(size_t size, int nmethod_size) {
|
||||||
// Always leave some room in the CodeCache for I2C/C2I adapters
|
void* alloc = CodeCache::allocate(nmethod_size);
|
||||||
if (CodeCache::largest_free_block() < CodeCacheMinimumFreeSpace) return NULL;
|
guarantee(alloc != NULL, "CodeCache should have enough space");
|
||||||
return CodeCache::allocate(nmethod_size);
|
return alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue