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

Sat, 23 Mar 2013 06:22:07 -0700

author
morris
date
Sat, 23 Mar 2013 06:22:07 -0700
changeset 4864
3c786355ffb4
parent 4863
360ce06580b8
child 4865
818a1ac7da7a

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

src/share/vm/code/codeCache.hpp file | annotate | diff | comparison | revisions
src/share/vm/code/nmethod.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/code/codeCache.hpp	Fri Mar 22 13:35:31 2013 -0400
     1.2 +++ b/src/share/vm/code/codeCache.hpp	Sat Mar 23 06:22:07 2013 -0700
     1.3 @@ -156,6 +156,11 @@
     1.4    static address  low_bound()                    { return (address) _heap->low_boundary(); }
     1.5    static address  high_bound()                   { return (address) _heap->high_boundary(); }
     1.6  
     1.7 +  static bool has_space(int size) {
     1.8 +    // Always leave some room in the CodeCache for I2C/C2I adapters
     1.9 +    return largest_free_block() > (CodeCacheMinimumFreeSpace + size);
    1.10 +  }
    1.11 +
    1.12    // Profiling
    1.13    static address first_address();                // first address used for CodeBlobs
    1.14    static address last_address();                 // last  address used for CodeBlobs
     2.1 --- a/src/share/vm/code/nmethod.cpp	Fri Mar 22 13:35:31 2013 -0400
     2.2 +++ b/src/share/vm/code/nmethod.cpp	Sat Mar 23 06:22:07 2013 -0700
     2.3 @@ -486,7 +486,6 @@
     2.4  #endif // def HAVE_DTRACE_H
     2.5  }
     2.6  
     2.7 -
     2.8  nmethod* nmethod::new_native_nmethod(methodHandle method,
     2.9    int compile_id,
    2.10    CodeBuffer *code_buffer,
    2.11 @@ -502,17 +501,19 @@
    2.12    {
    2.13      MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    2.14      int native_nmethod_size = allocation_size(code_buffer, sizeof(nmethod));
    2.15 -    CodeOffsets offsets;
    2.16 -    offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
    2.17 -    offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
    2.18 -    nm = new (native_nmethod_size)
    2.19 -      nmethod(method(), native_nmethod_size, compile_id, &offsets,
    2.20 -              code_buffer, frame_size,
    2.21 -              basic_lock_owner_sp_offset, basic_lock_sp_offset,
    2.22 -              oop_maps);
    2.23 -    NOT_PRODUCT(if (nm != NULL)  nmethod_stats.note_native_nmethod(nm));
    2.24 -    if (PrintAssembly && nm != NULL)
    2.25 -      Disassembler::decode(nm);
    2.26 +    if (CodeCache::has_space(native_nmethod_size)) {
    2.27 +      CodeOffsets offsets;
    2.28 +      offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
    2.29 +      offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
    2.30 +      nm = new (native_nmethod_size) nmethod(method(), native_nmethod_size,
    2.31 +                                             compile_id, &offsets,
    2.32 +                                             code_buffer, frame_size,
    2.33 +                                             basic_lock_owner_sp_offset,
    2.34 +                                             basic_lock_sp_offset, oop_maps);
    2.35 +      NOT_PRODUCT(if (nm != NULL)  nmethod_stats.note_native_nmethod(nm));
    2.36 +      if (PrintAssembly && nm != NULL)
    2.37 +        Disassembler::decode(nm);
    2.38 +    }
    2.39    }
    2.40    // verify nmethod
    2.41    debug_only(if (nm) nm->verify();) // might block
    2.42 @@ -537,16 +538,19 @@
    2.43    {
    2.44      MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    2.45      int nmethod_size = allocation_size(code_buffer, sizeof(nmethod));
    2.46 -    CodeOffsets offsets;
    2.47 -    offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
    2.48 -    offsets.set_value(CodeOffsets::Dtrace_trap, trap_offset);
    2.49 -    offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
    2.50 +    if (CodeCache::has_space(nmethod_size)) {
    2.51 +      CodeOffsets offsets;
    2.52 +      offsets.set_value(CodeOffsets::Verified_Entry, vep_offset);
    2.53 +      offsets.set_value(CodeOffsets::Dtrace_trap, trap_offset);
    2.54 +      offsets.set_value(CodeOffsets::Frame_Complete, frame_complete);
    2.55  
    2.56 -    nm = new (nmethod_size) nmethod(method(), nmethod_size, &offsets, code_buffer, frame_size);
    2.57 +      nm = new (nmethod_size) nmethod(method(), nmethod_size,
    2.58 +                                      &offsets, code_buffer, frame_size);
    2.59  
    2.60 -    NOT_PRODUCT(if (nm != NULL)  nmethod_stats.note_nmethod(nm));
    2.61 -    if (PrintAssembly && nm != NULL)
    2.62 -      Disassembler::decode(nm);
    2.63 +      NOT_PRODUCT(if (nm != NULL)  nmethod_stats.note_nmethod(nm));
    2.64 +      if (PrintAssembly && nm != NULL)
    2.65 +        Disassembler::decode(nm);
    2.66 +    }
    2.67    }
    2.68    // verify nmethod
    2.69    debug_only(if (nm) nm->verify();) // might block
    2.70 @@ -587,7 +591,8 @@
    2.71        + round_to(handler_table->size_in_bytes(), oopSize)
    2.72        + round_to(nul_chk_table->size_in_bytes(), oopSize)
    2.73        + round_to(debug_info->data_size()       , oopSize);
    2.74 -    nm = new (nmethod_size)
    2.75 +    if (CodeCache::has_space(nmethod_size)) {
    2.76 +      nm = new (nmethod_size)
    2.77        nmethod(method(), nmethod_size, compile_id, entry_bci, offsets,
    2.78                orig_pc_offset, debug_info, dependencies, code_buffer, frame_size,
    2.79                oop_maps,
    2.80 @@ -595,6 +600,7 @@
    2.81                nul_chk_table,
    2.82                compiler,
    2.83                comp_level);
    2.84 +    }
    2.85      if (nm != NULL) {
    2.86        // To make dependency checking during class loading fast, record
    2.87        // the nmethod dependencies in the classes it is dependent on.
    2.88 @@ -793,9 +799,9 @@
    2.89  #endif // def HAVE_DTRACE_H
    2.90  
    2.91  void* nmethod::operator new(size_t size, int nmethod_size) {
    2.92 -  // Always leave some room in the CodeCache for I2C/C2I adapters
    2.93 -  if (CodeCache::largest_free_block() < CodeCacheMinimumFreeSpace) return NULL;
    2.94 -  return CodeCache::allocate(nmethod_size);
    2.95 +  void*  alloc = CodeCache::allocate(nmethod_size);
    2.96 +  guarantee(alloc != NULL, "CodeCache should have enough space");
    2.97 +  return alloc;
    2.98  }
    2.99  
   2.100  

mercurial