Sat, 26 Jun 2010 00:19:55 -0700
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;