提交 688b762c 编写于 作者: M morris

8009026: [parfait] Null pointer deference in hotspot/src/share/vm/code/nmethod.cpp

Summary: add guarantee() to nmethod constructor and checks to ensure CodeCache has space before allocation
Reviewed-by: kvn
上级 a1db0240
...@@ -156,6 +156,11 @@ class CodeCache : AllStatic { ...@@ -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() { ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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( ...@@ -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;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册