Merge

Sat, 26 Jun 2010 00:19:55 -0700

author
jrose
date
Sat, 26 Jun 2010 00:19:55 -0700
changeset 1974
5a297ea605c7
parent 1969
b8537b881421
parent 1973
5f249b390094
child 1978
fcbb92a1ab3b
child 1982
c5f1ea9e15e8

Merge

     1.1 --- a/src/share/vm/c1/c1_Compilation.cpp	Thu Jun 24 15:56:12 2010 -0700
     1.2 +++ b/src/share/vm/c1/c1_Compilation.cpp	Sat Jun 26 00:19:55 2010 -0700
     1.3 @@ -242,10 +242,10 @@
     1.4    code->insts()->initialize_shared_locs((relocInfo*)locs_buffer,
     1.5                                          locs_buffer_size / sizeof(relocInfo));
     1.6    code->initialize_consts_size(Compilation::desired_max_constant_size());
     1.7 -  // Call stubs + deopt/exception handler
     1.8 +  // Call stubs + two deopt handlers (regular and MH) + exception handler
     1.9    code->initialize_stubs_size((call_stub_estimate * LIR_Assembler::call_stub_size) +
    1.10                                LIR_Assembler::exception_handler_size +
    1.11 -                              LIR_Assembler::deopt_handler_size);
    1.12 +                              2 * LIR_Assembler::deopt_handler_size);
    1.13  }
    1.14  
    1.15  
     2.1 --- a/src/share/vm/code/nmethod.cpp	Thu Jun 24 15:56:12 2010 -0700
     2.2 +++ b/src/share/vm/code/nmethod.cpp	Sat Jun 26 00:19:55 2010 -0700
     2.3 @@ -584,6 +584,7 @@
     2.4      _oops_do_mark_link       = NULL;
     2.5      _method                  = method;
     2.6      _entry_bci               = InvocationEntryBci;
     2.7 +    _jmethod_id              = NULL;
     2.8      _osr_link                = NULL;
     2.9      _scavenge_root_link      = NULL;
    2.10      _scavenge_root_state     = 0;
    2.11 @@ -677,6 +678,7 @@
    2.12      _oops_do_mark_link       = NULL;
    2.13      _method                  = method;
    2.14      _entry_bci               = InvocationEntryBci;
    2.15 +    _jmethod_id              = NULL;
    2.16      _osr_link                = NULL;
    2.17      _scavenge_root_link      = NULL;
    2.18      _scavenge_root_state     = 0;
    2.19 @@ -784,6 +786,7 @@
    2.20      NOT_PRODUCT(_has_debug_info = false);
    2.21      _oops_do_mark_link       = NULL;
    2.22      _method                  = method;
    2.23 +    _jmethod_id              = NULL;
    2.24      _compile_id              = compile_id;
    2.25      _comp_level              = comp_level;
    2.26      _entry_bci               = entry_bci;
    2.27 @@ -1488,11 +1491,25 @@
    2.28        moop->signature()->utf8_length(),
    2.29        code_begin(), code_size());
    2.30  
    2.31 +  if (JvmtiExport::should_post_compiled_method_load() ||
    2.32 +      JvmtiExport::should_post_compiled_method_unload()) {
    2.33 +    get_and_cache_jmethod_id();
    2.34 +  }
    2.35 +
    2.36    if (JvmtiExport::should_post_compiled_method_load()) {
    2.37      JvmtiExport::post_compiled_method_load(this);
    2.38    }
    2.39  }
    2.40  
    2.41 +jmethodID nmethod::get_and_cache_jmethod_id() {
    2.42 +  if (_jmethod_id == NULL) {
    2.43 +    // Cache the jmethod_id since it can no longer be looked up once the
    2.44 +    // method itself has been marked for unloading.
    2.45 +    _jmethod_id = method()->jmethod_id();
    2.46 +  }
    2.47 +  return _jmethod_id;
    2.48 +}
    2.49 +
    2.50  void nmethod::post_compiled_method_unload() {
    2.51    if (unload_reported()) {
    2.52      // During unloading we transition to unloaded and then to zombie
    2.53 @@ -1504,12 +1521,17 @@
    2.54    DTRACE_METHOD_UNLOAD_PROBE(method());
    2.55  
    2.56    // If a JVMTI agent has enabled the CompiledMethodUnload event then
    2.57 -  // post the event. Sometime later this nmethod will be made a zombie by
    2.58 -  // the sweeper but the methodOop will not be valid at that point.
    2.59 -  if (JvmtiExport::should_post_compiled_method_unload()) {
    2.60 +  // post the event. Sometime later this nmethod will be made a zombie
    2.61 +  // by the sweeper but the methodOop will not be valid at that point.
    2.62 +  // If the _jmethod_id is null then no load event was ever requested
    2.63 +  // so don't bother posting the unload.  The main reason for this is
    2.64 +  // that the jmethodID is a weak reference to the methodOop so if
    2.65 +  // it's being unloaded there's no way to look it up since the weak
    2.66 +  // ref will have been cleared.
    2.67 +  if (_jmethod_id != NULL && JvmtiExport::should_post_compiled_method_unload()) {
    2.68      assert(!unload_reported(), "already unloaded");
    2.69      HandleMark hm;
    2.70 -    JvmtiExport::post_compiled_method_unload(method()->jmethod_id(), code_begin());
    2.71 +    JvmtiExport::post_compiled_method_unload(_jmethod_id, code_begin());
    2.72    }
    2.73  
    2.74    // The JVMTI CompiledMethodUnload event can be enabled or disabled at
     3.1 --- a/src/share/vm/code/nmethod.hpp	Thu Jun 24 15:56:12 2010 -0700
     3.2 +++ b/src/share/vm/code/nmethod.hpp	Sat Jun 26 00:19:55 2010 -0700
     3.3 @@ -135,6 +135,7 @@
     3.4  
     3.5    methodOop _method;
     3.6    int       _entry_bci;        // != InvocationEntryBci if this nmethod is an on-stack replacement method
     3.7 +  jmethodID _jmethod_id;       // Cache of method()->jmethod_id()
     3.8  
     3.9    // To support simple linked-list chaining of nmethods:
    3.10    nmethod*  _osr_link;         // from instanceKlass::osr_nmethods_head
    3.11 @@ -599,6 +600,7 @@
    3.12  
    3.13    // jvmti support:
    3.14    void post_compiled_method_load_event();
    3.15 +  jmethodID get_and_cache_jmethod_id();
    3.16  
    3.17    // verify operations
    3.18    void verify();
     4.1 --- a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp	Thu Jun 24 15:56:12 2010 -0700
     4.2 +++ b/src/share/vm/prims/jvmtiCodeBlobEvents.cpp	Sat Jun 26 00:19:55 2010 -0700
     4.3 @@ -217,21 +217,21 @@
     4.4  
     4.5  class nmethodDesc: public CHeapObj {
     4.6   private:
     4.7 -  methodHandle _method;
     4.8 +  jmethodID _jmethod_id;
     4.9    address _code_begin;
    4.10    address _code_end;
    4.11    jvmtiAddrLocationMap* _map;
    4.12    jint _map_length;
    4.13   public:
    4.14 -  nmethodDesc(methodHandle method, address code_begin, address code_end,
    4.15 +  nmethodDesc(jmethodID jmethod_id, address code_begin, address code_end,
    4.16                jvmtiAddrLocationMap* map, jint map_length) {
    4.17 -    _method = method;
    4.18 +    _jmethod_id = jmethod_id;
    4.19      _code_begin = code_begin;
    4.20      _code_end = code_end;
    4.21      _map = map;
    4.22      _map_length = map_length;
    4.23    }
    4.24 -  methodHandle method() const           { return _method; }
    4.25 +  jmethodID jmethod_id() const          { return _jmethod_id; }
    4.26    address code_begin() const            { return _code_begin; }
    4.27    address code_end() const              { return _code_end; }
    4.28    jvmtiAddrLocationMap* map() const     { return _map; }
    4.29 @@ -323,8 +323,7 @@
    4.30    JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &map, &map_length);
    4.31  
    4.32    // record the nmethod details
    4.33 -  methodHandle mh(nm->method());
    4.34 -  nmethodDesc* snm = new nmethodDesc(mh,
    4.35 +  nmethodDesc* snm = new nmethodDesc(nm->get_and_cache_jmethod_id(),
    4.36                                       nm->code_begin(),
    4.37                                       nm->code_end(),
    4.38                                       map,
    4.39 @@ -367,8 +366,7 @@
    4.40    // iterate over the  list and post an event for each nmethod
    4.41    nmethodDesc* nm_desc = collector.first();
    4.42    while (nm_desc != NULL) {
    4.43 -    methodOop method = nm_desc->method()();
    4.44 -    jmethodID mid = method->jmethod_id();
    4.45 +    jmethodID mid = nm_desc->jmethod_id();
    4.46      assert(mid != NULL, "checking");
    4.47      JvmtiExport::post_compiled_method_load(env, mid,
    4.48                                             (jint)(nm_desc->code_end() - nm_desc->code_begin()),
     5.1 --- a/src/share/vm/runtime/jniHandles.cpp	Thu Jun 24 15:56:12 2010 -0700
     5.2 +++ b/src/share/vm/runtime/jniHandles.cpp	Sat Jun 26 00:19:55 2010 -0700
     5.3 @@ -66,6 +66,7 @@
     5.4  
     5.5  
     5.6  jobject JNIHandles::make_global(Handle obj) {
     5.7 +  assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
     5.8    jobject res = NULL;
     5.9    if (!obj.is_null()) {
    5.10      // ignore null handles
    5.11 @@ -81,6 +82,7 @@
    5.12  
    5.13  
    5.14  jobject JNIHandles::make_weak_global(Handle obj) {
    5.15 +  assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
    5.16    jobject res = NULL;
    5.17    if (!obj.is_null()) {
    5.18      // ignore null handles
     6.1 --- a/src/share/vm/runtime/sweeper.cpp	Thu Jun 24 15:56:12 2010 -0700
     6.2 +++ b/src/share/vm/runtime/sweeper.cpp	Sat Jun 26 00:19:55 2010 -0700
     6.3 @@ -26,7 +26,7 @@
     6.4  # include "incls/_sweeper.cpp.incl"
     6.5  
     6.6  long      NMethodSweeper::_traversals = 0;   // No. of stack traversals performed
     6.7 -CodeBlob* NMethodSweeper::_current = NULL;   // Current nmethod
     6.8 +nmethod*  NMethodSweeper::_current = NULL;   // Current nmethod
     6.9  int       NMethodSweeper::_seen = 0 ;        // No. of blobs we have currently processed in current pass of CodeCache
    6.10  int       NMethodSweeper::_invocations = 0;  // No. of invocations left until we are completed with this pass
    6.11  
    6.12 @@ -171,20 +171,16 @@
    6.13        // Since we will give up the CodeCache_lock, always skip ahead to an nmethod.
    6.14        // Other blobs can be deleted by other threads
    6.15        // Read next before we potentially delete current
    6.16 -      CodeBlob* next = CodeCache::next_nmethod(_current);
    6.17 +      nmethod* next = CodeCache::next_nmethod(_current);
    6.18  
    6.19        // Now ready to process nmethod and give up CodeCache_lock
    6.20        {
    6.21          MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    6.22 -        process_nmethod((nmethod *)_current);
    6.23 +        process_nmethod(_current);
    6.24        }
    6.25        _seen++;
    6.26        _current = next;
    6.27      }
    6.28 -
    6.29 -    // Skip forward to the next nmethod (if any). Code blobs other than nmethods
    6.30 -    // can be freed async to us and make _current invalid while we sleep.
    6.31 -    _current = CodeCache::next_nmethod(_current);
    6.32    }
    6.33  
    6.34    if (_current == NULL && !_rescan && (_locked_seen || _not_entrant_seen_on_stack)) {
     7.1 --- a/src/share/vm/runtime/sweeper.hpp	Thu Jun 24 15:56:12 2010 -0700
     7.2 +++ b/src/share/vm/runtime/sweeper.hpp	Sat Jun 26 00:19:55 2010 -0700
     7.3 @@ -29,7 +29,7 @@
     7.4  
     7.5  class NMethodSweeper : public AllStatic {
     7.6    static long      _traversals;   // Stack traversal count
     7.7 -  static CodeBlob* _current;      // Current nmethod
     7.8 +  static nmethod*  _current;      // Current nmethod
     7.9    static int       _seen;         // Nof. nmethod we have currently processed in current pass of CodeCache
    7.10    static int       _invocations;  // No. of invocations left until we are completed with this pass
    7.11  
     8.1 --- a/src/share/vm/runtime/virtualspace.cpp	Thu Jun 24 15:56:12 2010 -0700
     8.2 +++ b/src/share/vm/runtime/virtualspace.cpp	Sat Jun 26 00:19:55 2010 -0700
     8.3 @@ -111,6 +111,35 @@
     8.4    return result;
     8.5  }
     8.6  
     8.7 +// Helper method.
     8.8 +static bool failed_to_reserve_as_requested(char* base, char* requested_address,
     8.9 +                                           const size_t size, bool special)
    8.10 +{
    8.11 +  if (base == requested_address || requested_address == NULL)
    8.12 +    return false; // did not fail
    8.13 +
    8.14 +  if (base != NULL) {
    8.15 +    // Different reserve address may be acceptable in other cases
    8.16 +    // but for compressed oops heap should be at requested address.
    8.17 +    assert(UseCompressedOops, "currently requested address used only for compressed oops");
    8.18 +    if (PrintCompressedOopsMode) {
    8.19 +      tty->cr();
    8.20 +      tty->print_cr("Reserved memory at not requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address);
    8.21 +    }
    8.22 +    // OS ignored requested address. Try different address.
    8.23 +    if (special) {
    8.24 +      if (!os::release_memory_special(base, size)) {
    8.25 +        fatal("os::release_memory_special failed");
    8.26 +      }
    8.27 +    } else {
    8.28 +      if (!os::release_memory(base, size)) {
    8.29 +        fatal("os::release_memory failed");
    8.30 +      }
    8.31 +    }
    8.32 +  }
    8.33 +  return true;
    8.34 +}
    8.35 +
    8.36  ReservedSpace::ReservedSpace(const size_t prefix_size,
    8.37                               const size_t prefix_align,
    8.38                               const size_t suffix_size,
    8.39 @@ -129,6 +158,10 @@
    8.40    assert((suffix_align & prefix_align - 1) == 0,
    8.41      "suffix_align not divisible by prefix_align");
    8.42  
    8.43 +  // Assert that if noaccess_prefix is used, it is the same as prefix_align.
    8.44 +  assert(noaccess_prefix == 0 ||
    8.45 +         noaccess_prefix == prefix_align, "noaccess prefix wrong");
    8.46 +
    8.47    // Add in noaccess_prefix to prefix_size;
    8.48    const size_t adjusted_prefix_size = prefix_size + noaccess_prefix;
    8.49    const size_t size = adjusted_prefix_size + suffix_size;
    8.50 @@ -150,15 +183,16 @@
    8.51    _noaccess_prefix = 0;
    8.52    _executable = false;
    8.53  
    8.54 -  // Assert that if noaccess_prefix is used, it is the same as prefix_align.
    8.55 -  assert(noaccess_prefix == 0 ||
    8.56 -         noaccess_prefix == prefix_align, "noaccess prefix wrong");
    8.57 -
    8.58    // Optimistically try to reserve the exact size needed.
    8.59    char* addr;
    8.60    if (requested_address != 0) {
    8.61 -    addr = os::attempt_reserve_memory_at(size,
    8.62 -                                         requested_address-noaccess_prefix);
    8.63 +    requested_address -= noaccess_prefix; // adjust address
    8.64 +    assert(requested_address != NULL, "huge noaccess prefix?");
    8.65 +    addr = os::attempt_reserve_memory_at(size, requested_address);
    8.66 +    if (failed_to_reserve_as_requested(addr, requested_address, size, false)) {
    8.67 +      // OS ignored requested address. Try different address.
    8.68 +      addr = NULL;
    8.69 +    }
    8.70    } else {
    8.71      addr = os::reserve_memory(size, NULL, prefix_align);
    8.72    }
    8.73 @@ -222,11 +256,20 @@
    8.74    bool special = large && !os::can_commit_large_page_memory();
    8.75    char* base = NULL;
    8.76  
    8.77 +  if (requested_address != 0) {
    8.78 +    requested_address -= noaccess_prefix; // adjust requested address
    8.79 +    assert(requested_address != NULL, "huge noaccess prefix?");
    8.80 +  }
    8.81 +
    8.82    if (special) {
    8.83  
    8.84      base = os::reserve_memory_special(size, requested_address, executable);
    8.85  
    8.86      if (base != NULL) {
    8.87 +      if (failed_to_reserve_as_requested(base, requested_address, size, true)) {
    8.88 +        // OS ignored requested address. Try different address.
    8.89 +        return;
    8.90 +      }
    8.91        // Check alignment constraints
    8.92        if (alignment > 0) {
    8.93          assert((uintptr_t) base % alignment == 0,
    8.94 @@ -235,6 +278,13 @@
    8.95        _special = true;
    8.96      } else {
    8.97        // failed; try to reserve regular memory below
    8.98 +      if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
    8.99 +                            !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
   8.100 +        if (PrintCompressedOopsMode) {
   8.101 +          tty->cr();
   8.102 +          tty->print_cr("Reserve regular memory without large pages.");
   8.103 +        }
   8.104 +      }
   8.105      }
   8.106    }
   8.107  
   8.108 @@ -248,8 +298,11 @@
   8.109      // important.  If available space is not detected, return NULL.
   8.110  
   8.111      if (requested_address != 0) {
   8.112 -      base = os::attempt_reserve_memory_at(size,
   8.113 -                                           requested_address-noaccess_prefix);
   8.114 +      base = os::attempt_reserve_memory_at(size, requested_address);
   8.115 +      if (failed_to_reserve_as_requested(base, requested_address, size, false)) {
   8.116 +        // OS ignored requested address. Try different address.
   8.117 +        base = NULL;
   8.118 +      }
   8.119      } else {
   8.120        base = os::reserve_memory(size, NULL, alignment);
   8.121      }
   8.122 @@ -365,7 +418,12 @@
   8.123  }
   8.124  
   8.125  void ReservedSpace::protect_noaccess_prefix(const size_t size) {
   8.126 -  // If there is noaccess prefix, return.
   8.127 +  assert( (_noaccess_prefix != 0) == (UseCompressedOops && _base != NULL &&
   8.128 +                                      (size_t(_base + _size) > OopEncodingHeapMax) &&
   8.129 +                                      Universe::narrow_oop_use_implicit_null_checks()),
   8.130 +         "noaccess_prefix should be used only with non zero based compressed oops");
   8.131 +
   8.132 +  // If there is no noaccess prefix, return.
   8.133    if (_noaccess_prefix == 0) return;
   8.134  
   8.135    assert(_noaccess_prefix >= (size_t)os::vm_page_size(),
   8.136 @@ -377,6 +435,10 @@
   8.137                            _special)) {
   8.138      fatal("cannot protect protection page");
   8.139    }
   8.140 +  if (PrintCompressedOopsMode) {
   8.141 +    tty->cr();
   8.142 +    tty->print_cr("Protected page at the reserved heap base: " PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix);
   8.143 +  }
   8.144  
   8.145    _base += _noaccess_prefix;
   8.146    _size -= _noaccess_prefix;

mercurial