Thu, 15 Jul 2010 13:48:01 -0700
Merge
src/os/linux/vm/vtune_linux.cpp | file | annotate | diff | comparison | revisions | |
src/os/solaris/vm/vtune_solaris.cpp | file | annotate | diff | comparison | revisions | |
src/os/windows/vm/vtune_windows.cpp | file | annotate | diff | comparison | revisions | |
src/share/vm/runtime/vtune.hpp | file | annotate | diff | comparison | revisions |
1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java Wed Jul 14 17:52:18 2010 -0400 1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java Thu Jul 15 13:48:01 2010 -0700 1.3 @@ -35,7 +35,6 @@ 1.4 1.5 public class NMethod extends CodeBlob { 1.6 private static long pcDescSize; 1.7 - private static CIntegerField zombieInstructionSizeField; 1.8 private static sun.jvm.hotspot.types.OopField methodField; 1.9 /** != InvocationEntryBci if this nmethod is an on-stack replacement method */ 1.10 private static CIntegerField entryBCIField; 1.11 @@ -88,7 +87,6 @@ 1.12 private static void initialize(TypeDataBase db) { 1.13 Type type = db.lookupType("nmethod"); 1.14 1.15 - zombieInstructionSizeField = type.getCIntegerField("_zombie_instruction_size"); 1.16 methodField = type.getOopField("_method"); 1.17 entryBCIField = type.getCIntegerField("_entry_bci"); 1.18 osrLinkField = type.getAddressField("_osr_link");
2.1 --- a/src/cpu/x86/vm/vm_version_x86.hpp Wed Jul 14 17:52:18 2010 -0400 2.2 +++ b/src/cpu/x86/vm/vm_version_x86.hpp Thu Jul 15 13:48:01 2010 -0700 2.3 @@ -376,10 +376,17 @@ 2.4 static bool is_amd() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x68747541; } // 'htuA' 2.5 static bool is_intel() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x756e6547; } // 'uneG' 2.6 2.7 + static bool supports_processor_topology() { 2.8 + return (_cpuid_info.std_max_function >= 0xB) && 2.9 + // eax[4:0] | ebx[0:15] == 0 indicates invalid topology level. 2.10 + // Some cpus have max cpuid >= 0xB but do not support processor topology. 2.11 + ((_cpuid_info.tpl_cpuidB0_eax & 0x1f | _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus) != 0); 2.12 + } 2.13 + 2.14 static uint cores_per_cpu() { 2.15 uint result = 1; 2.16 if (is_intel()) { 2.17 - if (_cpuid_info.std_max_function >= 0xB) { 2.18 + if (supports_processor_topology()) { 2.19 result = _cpuid_info.tpl_cpuidB1_ebx.bits.logical_cpus / 2.20 _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus; 2.21 } else { 2.22 @@ -393,7 +400,7 @@ 2.23 2.24 static uint threads_per_core() { 2.25 uint result = 1; 2.26 - if (is_intel() && _cpuid_info.std_max_function >= 0xB) { 2.27 + if (is_intel() && supports_processor_topology()) { 2.28 result = _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus; 2.29 } else if (_cpuid_info.std_cpuid1_edx.bits.ht != 0) { 2.30 result = _cpuid_info.std_cpuid1_ebx.bits.threads_per_cpu /
3.1 --- a/src/os/linux/vm/vtune_linux.cpp Wed Jul 14 17:52:18 2010 -0400 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,45 +0,0 @@ 3.4 -/* 3.5 - * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. 3.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 - * 3.8 - * This code is free software; you can redistribute it and/or modify it 3.9 - * under the terms of the GNU General Public License version 2 only, as 3.10 - * published by the Free Software Foundation. 3.11 - * 3.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 3.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.15 - * version 2 for more details (a copy is included in the LICENSE file that 3.16 - * accompanied this code). 3.17 - * 3.18 - * You should have received a copy of the GNU General Public License version 3.19 - * 2 along with this work; if not, write to the Free Software Foundation, 3.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.21 - * 3.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.23 - * or visit www.oracle.com if you need additional information or have any 3.24 - * questions. 3.25 - * 3.26 - */ 3.27 - 3.28 -#include "incls/_precompiled.incl" 3.29 -#include "incls/_vtune_linux.cpp.incl" 3.30 - 3.31 -// empty implementation 3.32 - 3.33 -void VTune::start_GC() {} 3.34 -void VTune::end_GC() {} 3.35 -void VTune::start_class_load() {} 3.36 -void VTune::end_class_load() {} 3.37 -void VTune::exit() {} 3.38 -void VTune::register_stub(const char* name, address start, address end) {} 3.39 - 3.40 -void VTune::create_nmethod(nmethod* nm) {} 3.41 -void VTune::delete_nmethod(nmethod* nm) {} 3.42 - 3.43 -void vtune_init() {} 3.44 - 3.45 - 3.46 -// Reconciliation History 3.47 -// vtune_solaris.cpp 1.8 99/07/12 23:54:21 3.48 -// End
4.1 --- a/src/os/solaris/vm/vtune_solaris.cpp Wed Jul 14 17:52:18 2010 -0400 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,40 +0,0 @@ 4.4 -/* 4.5 - * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. 4.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 - * 4.8 - * This code is free software; you can redistribute it and/or modify it 4.9 - * under the terms of the GNU General Public License version 2 only, as 4.10 - * published by the Free Software Foundation. 4.11 - * 4.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 - * version 2 for more details (a copy is included in the LICENSE file that 4.16 - * accompanied this code). 4.17 - * 4.18 - * You should have received a copy of the GNU General Public License version 4.19 - * 2 along with this work; if not, write to the Free Software Foundation, 4.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 - * 4.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 - * or visit www.oracle.com if you need additional information or have any 4.24 - * questions. 4.25 - * 4.26 - */ 4.27 - 4.28 -#include "incls/_precompiled.incl" 4.29 -#include "incls/_vtune_solaris.cpp.incl" 4.30 - 4.31 -// empty implementation 4.32 - 4.33 -void VTune::start_GC() {} 4.34 -void VTune::end_GC() {} 4.35 -void VTune::start_class_load() {} 4.36 -void VTune::end_class_load() {} 4.37 -void VTune::exit() {} 4.38 -void VTune::register_stub(const char* name, address start, address end) {} 4.39 - 4.40 -void VTune::create_nmethod(nmethod* nm) {} 4.41 -void VTune::delete_nmethod(nmethod* nm) {} 4.42 - 4.43 -void vtune_init() {}
5.1 --- a/src/os/windows/vm/vtune_windows.cpp Wed Jul 14 17:52:18 2010 -0400 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,290 +0,0 @@ 5.4 -/* 5.5 - * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. 5.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 - * 5.8 - * This code is free software; you can redistribute it and/or modify it 5.9 - * under the terms of the GNU General Public License version 2 only, as 5.10 - * published by the Free Software Foundation. 5.11 - * 5.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 5.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.15 - * version 2 for more details (a copy is included in the LICENSE file that 5.16 - * accompanied this code). 5.17 - * 5.18 - * You should have received a copy of the GNU General Public License version 5.19 - * 2 along with this work; if not, write to the Free Software Foundation, 5.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.21 - * 5.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.23 - * or visit www.oracle.com if you need additional information or have any 5.24 - * questions. 5.25 - * 5.26 - */ 5.27 - 5.28 -#include "incls/_precompiled.incl" 5.29 -#include "incls/_vtune_windows.cpp.incl" 5.30 - 5.31 -static int current_method_ID = 0; 5.32 - 5.33 -// ------------- iJITProf.h ------------------- 5.34 -// defined by Intel -- do not change 5.35 - 5.36 -#include "windows.h" 5.37 - 5.38 -extern "C" { 5.39 - enum iJITP_Event { 5.40 - ExceptionOccurred_S, // Java exception 5.41 - ExceptionOccurred_IDS, 5.42 - 5.43 - Shutdown, // VM exit 5.44 - 5.45 - ThreadCreate, // threads 5.46 - ThreadDestroy, 5.47 - ThreadSwitch, 5.48 - 5.49 - ClassLoadStart, // class loading 5.50 - ClassLoadEnd, 5.51 - 5.52 - GCStart, // GC 5.53 - GCEnd, 5.54 - 5.55 - NMethodCreate = 13, // nmethod creation 5.56 - NMethodDelete 5.57 - 5.58 - // rest of event types omitted (call profiling not supported yet) 5.59 - }; 5.60 - 5.61 - // version number -- 0 if VTune not installed 5.62 - int WINAPI iJitP_VersionNumber(); 5.63 - 5.64 - enum iJITP_ModeFlags { 5.65 - NoNotification = 0x0, // don't call vtune 5.66 - NotifyNMethodCreate = 0x1, // notify NMethod_Create 5.67 - NotifyNMethodDelete = 0x2, // notify NMethod_Create 5.68 - NotifyMethodEnter = 0x4, // method entry 5.69 - NotifyMethodExit = 0x8, // method exit 5.70 - NotifyShutdown = 0x10, // VM exit 5.71 - NotifyGC = 0x20, // GC 5.72 - }; 5.73 - 5.74 - // call back function type 5.75 - typedef void (WINAPI *ModeChangedFn)(iJITP_ModeFlags flags); 5.76 - 5.77 - // ------------- VTune method interfaces ---------------------- 5.78 - typedef void (WINAPI *RegisterCallbackFn)(ModeChangedFn fn); // register callback 5.79 - typedef int (WINAPI *NotifyEventFn)(iJITP_Event, void* event_data); 5.80 - 5.81 - // specific event data structures 5.82 - 5.83 - // data for NMethodCreate 5.84 - 5.85 - struct VTuneObj { // base class for allocation 5.86 - // (can't use CHeapObj -- has vtable ptr) 5.87 - void* operator new(size_t size) { return os::malloc(size); } 5.88 - void operator delete(void* p) { fatal("never delete VTune data"); } 5.89 - }; 5.90 - 5.91 - struct LineNumberInfo : VTuneObj { // PC-to-line number mapping 5.92 - unsigned long offset; // byte offset from start of method 5.93 - unsigned long line_num; // corresponding line number 5.94 - }; 5.95 - 5.96 - struct MethodLoadInfo : VTuneObj { 5.97 - unsigned long methodID; // unique method ID 5.98 - const char* name; // method name 5.99 - unsigned long instr_start; // start address 5.100 - unsigned long instr_size; // length in bytes 5.101 - unsigned long line_number_size; // size of line number table 5.102 - LineNumberInfo* line_number_table; // line number mapping 5.103 - unsigned long classID; // unique class ID 5.104 - char* class_file_name; // fully qualified class file name 5.105 - char* source_file_name; // fully qualified source file name 5.106 - 5.107 - MethodLoadInfo(nmethod* nm); // for real nmethods 5.108 - MethodLoadInfo(const char* vm_name, address start, address end); 5.109 - // for "nmethods" like stubs, interpreter, etc 5.110 - 5.111 - }; 5.112 - 5.113 - // data for NMethodDelete 5.114 - struct MethodInfo : VTuneObj { 5.115 - unsigned long methodID; // unique method ID 5.116 - unsigned long classID; // (added for convenience -- not part of Intel interface) 5.117 - 5.118 - MethodInfo(methodOop m); 5.119 - }; 5.120 -}; 5.121 - 5.122 -MethodInfo::MethodInfo(methodOop m) { 5.123 - // just give it a new ID -- we're not compiling methods twice (usually) 5.124 - // (and even if we did, one might want to see the two versions separately) 5.125 - methodID = ++current_method_ID; 5.126 -} 5.127 - 5.128 -MethodLoadInfo::MethodLoadInfo(const char* vm_name, address start, address end) { 5.129 - classID = 0; 5.130 - methodID = ++current_method_ID; 5.131 - name = vm_name; 5.132 - instr_start = (unsigned long)start; 5.133 - instr_size = end - start; 5.134 - line_number_size = 0; 5.135 - line_number_table = NULL; 5.136 - class_file_name = source_file_name = "HotSpot JVM"; 5.137 -} 5.138 - 5.139 -MethodLoadInfo::MethodLoadInfo(nmethod* nm) { 5.140 - methodOop m = nm->method(); 5.141 - MethodInfo info(m); 5.142 - classID = info.classID; 5.143 - methodID = info.methodID; 5.144 - name = strdup(m->name()->as_C_string()); 5.145 - instr_start = (unsigned long)nm->instructions_begin(); 5.146 - instr_size = nm->code_size(); 5.147 - line_number_size = 0; 5.148 - line_number_table = NULL; 5.149 - klassOop kl = m->method_holder(); 5.150 - char* class_name = Klass::cast(kl)->name()->as_C_string(); 5.151 - char* file_name = NEW_C_HEAP_ARRAY(char, strlen(class_name) + 1); 5.152 - strcpy(file_name, class_name); 5.153 - class_file_name = file_name; 5.154 - char* src_name = NEW_C_HEAP_ARRAY(char, strlen(class_name) + strlen(".java") + 1); 5.155 - strcpy(src_name, class_name); 5.156 - strcat(src_name, ".java"); 5.157 - source_file_name = src_name; 5.158 -} 5.159 - 5.160 -// --------------------- DLL loading functions ------------------------ 5.161 - 5.162 -#define DLLNAME "iJitProf.dll" 5.163 - 5.164 -static HINSTANCE load_lib(char* name) { 5.165 - HINSTANCE lib = NULL; 5.166 - HKEY hk; 5.167 - 5.168 - // try to get VTune directory from the registry 5.169 - if (RegOpenKey(HKEY_CURRENT_USER, "Software\\VB and VBA Program Settings\\VTune\\StartUp", &hk) == ERROR_SUCCESS) { 5.170 - for (int i = 0; true; i++) { 5.171 - char szName[MAX_PATH + 1]; 5.172 - char szVal [MAX_PATH + 1]; 5.173 - DWORD cbName, cbVal; 5.174 - 5.175 - cbName = cbVal = MAX_PATH + 1; 5.176 - if (RegEnumValue(hk, i, szName, &cbName, NULL, NULL, (LPBYTE)szVal, &cbVal) == ERROR_SUCCESS) { 5.177 - // get VTune directory 5.178 - if (!strcmp(szName, name)) { 5.179 - char*p = szVal; 5.180 - while (*p == ' ') p++; // trim 5.181 - char* q = p + strlen(p) - 1; 5.182 - while (*q == ' ') *(q--) = '\0'; 5.183 - 5.184 - // chdir to the VTune dir 5.185 - GetCurrentDirectory(MAX_PATH + 1, szName); 5.186 - SetCurrentDirectory(p); 5.187 - // load lib 5.188 - lib = LoadLibrary(strcat(strcat(p, "\\"), DLLNAME)); 5.189 - if (lib != NULL && WizardMode) tty->print_cr("*loaded VTune DLL %s", p); 5.190 - // restore current dir 5.191 - SetCurrentDirectory(szName); 5.192 - break; 5.193 - } 5.194 - } else { 5.195 - break; 5.196 - } 5.197 - } 5.198 - } 5.199 - return lib; 5.200 -} 5.201 - 5.202 -static RegisterCallbackFn iJIT_RegisterCallback = NULL; 5.203 -static NotifyEventFn iJIT_NotifyEvent = NULL; 5.204 - 5.205 -static bool load_iJIT_funcs() { 5.206 - // first try to load from PATH 5.207 - HINSTANCE lib = LoadLibrary(DLLNAME); 5.208 - if (lib != NULL && WizardMode) tty->print_cr("*loaded VTune DLL %s via PATH", DLLNAME); 5.209 - 5.210 - // if not successful, try to look in the VTUNE directory 5.211 - if (lib == NULL) lib = load_lib("VTUNEDIR30"); 5.212 - if (lib == NULL) lib = load_lib("VTUNEDIR25"); 5.213 - if (lib == NULL) lib = load_lib("VTUNEDIR"); 5.214 - 5.215 - if (lib == NULL) return false; // unsuccessful 5.216 - 5.217 - // try to load the functions 5.218 - iJIT_RegisterCallback = (RegisterCallbackFn)GetProcAddress(lib, "iJIT_RegisterCallback"); 5.219 - iJIT_NotifyEvent = (NotifyEventFn) GetProcAddress(lib, "iJIT_NotifyEvent"); 5.220 - 5.221 - if (!iJIT_RegisterCallback) tty->print_cr("*couldn't find VTune entry point iJIT_RegisterCallback"); 5.222 - if (!iJIT_NotifyEvent) tty->print_cr("*couldn't find VTune entry point iJIT_NotifyEvent"); 5.223 - return iJIT_RegisterCallback != NULL && iJIT_NotifyEvent != NULL; 5.224 -} 5.225 - 5.226 -// --------------------- VTune class ------------------------ 5.227 - 5.228 -static bool active = false; 5.229 -static int flags = 0; 5.230 - 5.231 -void VTune::start_GC() { 5.232 - if (active && (flags & NotifyGC)) iJIT_NotifyEvent(GCStart, NULL); 5.233 -} 5.234 - 5.235 -void VTune::end_GC() { 5.236 - if (active && (flags & NotifyGC)) iJIT_NotifyEvent(GCEnd, NULL); 5.237 -} 5.238 - 5.239 -void VTune::start_class_load() { 5.240 - // not yet implemented in VTune 5.241 -} 5.242 - 5.243 -void VTune::end_class_load() { 5.244 - // not yet implemented in VTune 5.245 -} 5.246 - 5.247 -void VTune::exit() { 5.248 - if (active && (flags & NotifyShutdown)) iJIT_NotifyEvent(Shutdown, NULL); 5.249 -} 5.250 - 5.251 -void VTune::register_stub(const char* name, address start, address end) { 5.252 - if (flags & NotifyNMethodCreate) { 5.253 - MethodLoadInfo* info = new MethodLoadInfo(name, start, end); 5.254 - if (PrintMiscellaneous && WizardMode && Verbose) { 5.255 - tty->print_cr("NMethodCreate %s (%d): %#x..%#x", info->name, info->methodID, 5.256 - info->instr_start, info->instr_start + info->instr_size); 5.257 - } 5.258 - iJIT_NotifyEvent(NMethodCreate, info); 5.259 - } 5.260 -} 5.261 - 5.262 -void VTune::create_nmethod(nmethod* nm) { 5.263 - if (flags & NotifyNMethodCreate) { 5.264 - MethodLoadInfo* info = new MethodLoadInfo(nm); 5.265 - if (PrintMiscellaneous && WizardMode && Verbose) { 5.266 - tty->print_cr("NMethodCreate %s (%d): %#x..%#x", info->name, info->methodID, 5.267 - info->instr_start, info->instr_start + info->instr_size); 5.268 - } 5.269 - iJIT_NotifyEvent(NMethodCreate, info); 5.270 - } 5.271 -} 5.272 - 5.273 -void VTune::delete_nmethod(nmethod* nm) { 5.274 - if (flags & NotifyNMethodDelete) { 5.275 - MethodInfo* info = new MethodInfo(nm->method()); 5.276 - iJIT_NotifyEvent(NMethodDelete, info); 5.277 - } 5.278 -} 5.279 - 5.280 -static void set_flags(int new_flags) { 5.281 - flags = new_flags; 5.282 - // if (WizardMode) tty->print_cr("*new VTune flags: %#x", flags); 5.283 -} 5.284 - 5.285 -void vtune_init() { 5.286 - if (!UseVTune) return; 5.287 - active = load_iJIT_funcs(); 5.288 - if (active) { 5.289 - iJIT_RegisterCallback((ModeChangedFn)set_flags); 5.290 - } else { 5.291 - assert(flags == 0, "flags shouldn't be set"); 5.292 - } 5.293 -}
6.1 --- a/src/share/vm/ci/bcEscapeAnalyzer.cpp Wed Jul 14 17:52:18 2010 -0400 6.2 +++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Jul 15 13:48:01 2010 -0700 6.3 @@ -106,7 +106,7 @@ 6.4 void BCEscapeAnalyzer::set_returned(ArgumentMap vars) { 6.5 for (int i = 0; i < _arg_size; i++) { 6.6 if (vars.contains(i)) 6.7 - _arg_returned.set_bit(i); 6.8 + _arg_returned.set(i); 6.9 } 6.10 _return_local = _return_local && !(vars.contains_unknown() || vars.contains_allocated()); 6.11 _return_allocated = _return_allocated && vars.contains_allocated() && !(vars.contains_unknown() || vars.contains_vars()); 6.12 @@ -126,16 +126,16 @@ 6.13 if (_conservative) 6.14 return true; 6.15 for (int i = 0; i < _arg_size; i++) { 6.16 - if (vars.contains(i) && _arg_stack.at(i)) 6.17 + if (vars.contains(i) && _arg_stack.test(i)) 6.18 return true; 6.19 } 6.20 return false; 6.21 } 6.22 6.23 -void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, BitMap &bm) { 6.24 +void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, VectorSet &bm) { 6.25 for (int i = 0; i < _arg_size; i++) { 6.26 if (vars.contains(i)) { 6.27 - bm.clear_bit(i); 6.28 + bm >>= i; 6.29 } 6.30 } 6.31 } 6.32 @@ -1157,15 +1157,15 @@ 6.33 ciSignature* sig = method()->signature(); 6.34 int j = 0; 6.35 if (!method()->is_static()) { 6.36 - _arg_local.set_bit(0); 6.37 - _arg_stack.set_bit(0); 6.38 + _arg_local.set(0); 6.39 + _arg_stack.set(0); 6.40 j++; 6.41 } 6.42 for (i = 0; i < sig->count(); i++) { 6.43 ciType* t = sig->type_at(i); 6.44 if (!t->is_primitive_type()) { 6.45 - _arg_local.set_bit(j); 6.46 - _arg_stack.set_bit(j); 6.47 + _arg_local.set(j); 6.48 + _arg_stack.set(j); 6.49 } 6.50 j += t->size(); 6.51 } 6.52 @@ -1198,9 +1198,9 @@ 6.53 set_modified(var, OFFSET_ANY, 4); 6.54 set_global_escape(var); 6.55 } 6.56 - _arg_local.clear(); 6.57 - _arg_stack.clear(); 6.58 - _arg_returned.clear(); 6.59 + _arg_local.Clear(); 6.60 + _arg_stack.Clear(); 6.61 + _arg_returned.Clear(); 6.62 _return_local = false; 6.63 _return_allocated = false; 6.64 _allocated_escapes = true; 6.65 @@ -1254,7 +1254,7 @@ 6.66 6.67 // Do not scan method if it has no object parameters and 6.68 // does not returns an object (_return_allocated is set in initialize()). 6.69 - if (_arg_local.is_empty() && !_return_allocated) { 6.70 + if (_arg_local.Size() == 0 && !_return_allocated) { 6.71 // Clear all info since method's bytecode was not analysed and 6.72 // set pessimistic escape information. 6.73 clear_escape_info(); 6.74 @@ -1275,14 +1275,14 @@ 6.75 // 6.76 if (!has_dependencies() && !methodData()->is_empty()) { 6.77 for (i = 0; i < _arg_size; i++) { 6.78 - if (_arg_local.at(i)) { 6.79 - assert(_arg_stack.at(i), "inconsistent escape info"); 6.80 + if (_arg_local.test(i)) { 6.81 + assert(_arg_stack.test(i), "inconsistent escape info"); 6.82 methodData()->set_arg_local(i); 6.83 methodData()->set_arg_stack(i); 6.84 - } else if (_arg_stack.at(i)) { 6.85 + } else if (_arg_stack.test(i)) { 6.86 methodData()->set_arg_stack(i); 6.87 } 6.88 - if (_arg_returned.at(i)) { 6.89 + if (_arg_returned.test(i)) { 6.90 methodData()->set_arg_returned(i); 6.91 } 6.92 methodData()->set_arg_modified(i, _arg_modified[i]); 6.93 @@ -1308,9 +1308,12 @@ 6.94 6.95 // read escape information from method descriptor 6.96 for (int i = 0; i < _arg_size; i++) { 6.97 - _arg_local.at_put(i, methodData()->is_arg_local(i)); 6.98 - _arg_stack.at_put(i, methodData()->is_arg_stack(i)); 6.99 - _arg_returned.at_put(i, methodData()->is_arg_returned(i)); 6.100 + if (methodData()->is_arg_local(i)) 6.101 + _arg_local.set(i); 6.102 + if (methodData()->is_arg_stack(i)) 6.103 + _arg_stack.set(i); 6.104 + if (methodData()->is_arg_returned(i)) 6.105 + _arg_returned.set(i); 6.106 _arg_modified[i] = methodData()->arg_modified(i); 6.107 } 6.108 _return_local = methodData()->eflag_set(methodDataOopDesc::return_local); 6.109 @@ -1358,26 +1361,26 @@ 6.110 6.111 BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent) 6.112 : _conservative(method == NULL || !EstimateArgEscape) 6.113 + , _arena(CURRENT_ENV->arena()) 6.114 , _method(method) 6.115 , _methodData(method ? method->method_data() : NULL) 6.116 , _arg_size(method ? method->arg_size() : 0) 6.117 - , _stack() 6.118 - , _arg_local(_arg_size) 6.119 - , _arg_stack(_arg_size) 6.120 - , _arg_returned(_arg_size) 6.121 - , _dirty(_arg_size) 6.122 + , _arg_local(_arena) 6.123 + , _arg_stack(_arena) 6.124 + , _arg_returned(_arena) 6.125 + , _dirty(_arena) 6.126 , _return_local(false) 6.127 , _return_allocated(false) 6.128 , _allocated_escapes(false) 6.129 , _unknown_modified(false) 6.130 - , _dependencies() 6.131 + , _dependencies(_arena, 4, 0, NULL) 6.132 , _parent(parent) 6.133 , _level(parent == NULL ? 0 : parent->level() + 1) { 6.134 if (!_conservative) { 6.135 - _arg_local.clear(); 6.136 - _arg_stack.clear(); 6.137 - _arg_returned.clear(); 6.138 - _dirty.clear(); 6.139 + _arg_local.Clear(); 6.140 + _arg_stack.Clear(); 6.141 + _arg_returned.Clear(); 6.142 + _dirty.Clear(); 6.143 Arena* arena = CURRENT_ENV->arena(); 6.144 _arg_modified = (uint *) arena->Amalloc(_arg_size * sizeof(uint)); 6.145 Copy::zero_to_bytes(_arg_modified, _arg_size * sizeof(uint)); 6.146 @@ -1414,8 +1417,8 @@ 6.147 deps->assert_evol_method(method()); 6.148 } 6.149 for (int i = 0; i < _dependencies.length(); i+=2) { 6.150 - ciKlass *k = _dependencies[i]->as_klass(); 6.151 - ciMethod *m = _dependencies[i+1]->as_method(); 6.152 + ciKlass *k = _dependencies.at(i)->as_klass(); 6.153 + ciMethod *m = _dependencies.at(i+1)->as_method(); 6.154 deps->assert_unique_concrete_method(k, m); 6.155 } 6.156 }
7.1 --- a/src/share/vm/ci/bcEscapeAnalyzer.hpp Wed Jul 14 17:52:18 2010 -0400 7.2 +++ b/src/share/vm/ci/bcEscapeAnalyzer.hpp Thu Jul 15 13:48:01 2010 -0700 7.3 @@ -22,9 +22,6 @@ 7.4 * 7.5 */ 7.6 7.7 -define_array(ciObjectArray, ciObject*); 7.8 -define_stack(ciObjectList, ciObjectArray); 7.9 - 7.10 // This class implements a fast, conservative analysis of effect of methods 7.11 // on the escape state of their arguments. The analysis is at the bytecode 7.12 // level. 7.13 @@ -34,18 +31,17 @@ 7.14 7.15 class BCEscapeAnalyzer : public ResourceObj { 7.16 private: 7.17 + Arena* _arena; // ciEnv arena 7.18 + 7.19 bool _conservative; // If true, return maximally 7.20 // conservative results. 7.21 ciMethod* _method; 7.22 ciMethodData* _methodData; 7.23 int _arg_size; 7.24 - 7.25 - intStack _stack; 7.26 - 7.27 - BitMap _arg_local; 7.28 - BitMap _arg_stack; 7.29 - BitMap _arg_returned; 7.30 - BitMap _dirty; 7.31 + VectorSet _arg_local; 7.32 + VectorSet _arg_stack; 7.33 + VectorSet _arg_returned; 7.34 + VectorSet _dirty; 7.35 enum{ ARG_OFFSET_MAX = 31}; 7.36 uint *_arg_modified; 7.37 7.38 @@ -54,7 +50,7 @@ 7.39 bool _allocated_escapes; 7.40 bool _unknown_modified; 7.41 7.42 - ciObjectList _dependencies; 7.43 + GrowableArray<ciObject *> _dependencies; 7.44 7.45 ciMethodBlocks *_methodBlocks; 7.46 7.47 @@ -68,20 +64,10 @@ 7.48 private: 7.49 // helper functions 7.50 bool is_argument(int i) { return i >= 0 && i < _arg_size; } 7.51 - 7.52 - void raw_push(int i) { _stack.push(i); } 7.53 - int raw_pop() { return _stack.is_empty() ? -1 : _stack.pop(); } 7.54 - void apush(int i) { raw_push(i); } 7.55 - void spush() { raw_push(-1); } 7.56 - void lpush() { spush(); spush(); } 7.57 - int apop() { return raw_pop(); } 7.58 - void spop() { assert(_stack.is_empty() || _stack.top() == -1, ""); raw_pop(); } 7.59 - void lpop() { spop(); spop(); } 7.60 - 7.61 void set_returned(ArgumentMap vars); 7.62 bool is_argument(ArgumentMap vars); 7.63 bool is_arg_stack(ArgumentMap vars); 7.64 - void clear_bits(ArgumentMap vars, BitMap &bs); 7.65 + void clear_bits(ArgumentMap vars, VectorSet &bs); 7.66 void set_method_escape(ArgumentMap vars); 7.67 void set_global_escape(ArgumentMap vars); 7.68 void set_dirty(ArgumentMap vars); 7.69 @@ -116,25 +102,25 @@ 7.70 ciMethodData* methodData() const { return _methodData; } 7.71 BCEscapeAnalyzer* parent() const { return _parent; } 7.72 int level() const { return _level; } 7.73 - ciObjectList* dependencies() { return &_dependencies; } 7.74 + GrowableArray<ciObject *>* dependencies() { return &_dependencies; } 7.75 bool has_dependencies() const { return !_dependencies.is_empty(); } 7.76 7.77 // retrieval of interprocedural escape information 7.78 7.79 // The given argument does not escape the callee. 7.80 bool is_arg_local(int i) const { 7.81 - return !_conservative && _arg_local.at(i); 7.82 + return !_conservative && _arg_local.test(i); 7.83 } 7.84 7.85 // The given argument escapes the callee, but does not become globally 7.86 // reachable. 7.87 bool is_arg_stack(int i) const { 7.88 - return !_conservative && _arg_stack.at(i); 7.89 + return !_conservative && _arg_stack.test(i); 7.90 } 7.91 7.92 // The given argument does not escape globally, and may be returned. 7.93 bool is_arg_returned(int i) const { 7.94 - return !_conservative && _arg_returned.at(i); } 7.95 + return !_conservative && _arg_returned.test(i); } 7.96 7.97 // True iff only input arguments are returned. 7.98 bool is_return_local() const {
8.1 --- a/src/share/vm/ci/ciInstanceKlass.cpp Wed Jul 14 17:52:18 2010 -0400 8.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Thu Jul 15 13:48:01 2010 -0700 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. 8.6 + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -44,9 +44,7 @@ 8.11 _flags = ciFlags(access_flags); 8.12 _has_finalizer = access_flags.has_finalizer(); 8.13 _has_subklass = ik->subklass() != NULL; 8.14 - _is_initialized = ik->is_initialized(); 8.15 - // Next line must follow and use the result of the previous line: 8.16 - _is_linked = _is_initialized || ik->is_linked(); 8.17 + _init_state = (instanceKlass::ClassState)ik->get_init_state(); 8.18 _nonstatic_field_size = ik->nonstatic_field_size(); 8.19 _has_nonstatic_fields = ik->has_nonstatic_fields(); 8.20 _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: 8.21 @@ -91,8 +89,7 @@ 8.22 : ciKlass(name, ciInstanceKlassKlass::make()) 8.23 { 8.24 assert(name->byte_at(0) != '[', "not an instance klass"); 8.25 - _is_initialized = false; 8.26 - _is_linked = false; 8.27 + _init_state = (instanceKlass::ClassState)0; 8.28 _nonstatic_field_size = -1; 8.29 _has_nonstatic_fields = false; 8.30 _nonstatic_fields = NULL; 8.31 @@ -109,21 +106,10 @@ 8.32 8.33 // ------------------------------------------------------------------ 8.34 // ciInstanceKlass::compute_shared_is_initialized 8.35 -bool ciInstanceKlass::compute_shared_is_initialized() { 8.36 +void ciInstanceKlass::compute_shared_init_state() { 8.37 GUARDED_VM_ENTRY( 8.38 instanceKlass* ik = get_instanceKlass(); 8.39 - _is_initialized = ik->is_initialized(); 8.40 - return _is_initialized; 8.41 - ) 8.42 -} 8.43 - 8.44 -// ------------------------------------------------------------------ 8.45 -// ciInstanceKlass::compute_shared_is_linked 8.46 -bool ciInstanceKlass::compute_shared_is_linked() { 8.47 - GUARDED_VM_ENTRY( 8.48 - instanceKlass* ik = get_instanceKlass(); 8.49 - _is_linked = ik->is_linked(); 8.50 - return _is_linked; 8.51 + _init_state = (instanceKlass::ClassState)ik->get_init_state(); 8.52 ) 8.53 } 8.54
9.1 --- a/src/share/vm/ci/ciInstanceKlass.hpp Wed Jul 14 17:52:18 2010 -0400 9.2 +++ b/src/share/vm/ci/ciInstanceKlass.hpp Thu Jul 15 13:48:01 2010 -0700 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. 9.6 + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -39,9 +39,8 @@ 9.11 jobject _loader; 9.12 jobject _protection_domain; 9.13 9.14 + instanceKlass::ClassState _init_state; // state of class 9.15 bool _is_shared; 9.16 - bool _is_initialized; 9.17 - bool _is_linked; 9.18 bool _has_finalizer; 9.19 bool _has_subklass; 9.20 bool _has_nonstatic_fields; 9.21 @@ -87,27 +86,34 @@ 9.22 9.23 bool is_shared() { return _is_shared; } 9.24 9.25 - bool compute_shared_is_initialized(); 9.26 - bool compute_shared_is_linked(); 9.27 + void compute_shared_init_state(); 9.28 bool compute_shared_has_subklass(); 9.29 int compute_shared_nof_implementors(); 9.30 int compute_nonstatic_fields(); 9.31 GrowableArray<ciField*>* compute_nonstatic_fields_impl(GrowableArray<ciField*>* super_fields); 9.32 9.33 + // Update the init_state for shared klasses 9.34 + void update_if_shared(instanceKlass::ClassState expected) { 9.35 + if (_is_shared && _init_state != expected) { 9.36 + if (is_loaded()) compute_shared_init_state(); 9.37 + } 9.38 + } 9.39 + 9.40 public: 9.41 // Has this klass been initialized? 9.42 bool is_initialized() { 9.43 - if (_is_shared && !_is_initialized) { 9.44 - return is_loaded() && compute_shared_is_initialized(); 9.45 - } 9.46 - return _is_initialized; 9.47 + update_if_shared(instanceKlass::fully_initialized); 9.48 + return _init_state == instanceKlass::fully_initialized; 9.49 + } 9.50 + // Is this klass being initialized? 9.51 + bool is_being_initialized() { 9.52 + update_if_shared(instanceKlass::being_initialized); 9.53 + return _init_state == instanceKlass::being_initialized; 9.54 } 9.55 // Has this klass been linked? 9.56 bool is_linked() { 9.57 - if (_is_shared && !_is_linked) { 9.58 - return is_loaded() && compute_shared_is_linked(); 9.59 - } 9.60 - return _is_linked; 9.61 + update_if_shared(instanceKlass::linked); 9.62 + return _init_state >= instanceKlass::linked; 9.63 } 9.64 9.65 // General klass information.
10.1 --- a/src/share/vm/ci/ciMethod.cpp Wed Jul 14 17:52:18 2010 -0400 10.2 +++ b/src/share/vm/ci/ciMethod.cpp Thu Jul 15 13:48:01 2010 -0700 10.3 @@ -54,10 +54,10 @@ 10.4 _code = NULL; 10.5 _exception_handlers = NULL; 10.6 _liveness = NULL; 10.7 - _bcea = NULL; 10.8 _method_blocks = NULL; 10.9 #ifdef COMPILER2 10.10 _flow = NULL; 10.11 + _bcea = NULL; 10.12 #endif // COMPILER2 10.13 10.14 ciEnv *env = CURRENT_ENV; 10.15 @@ -121,11 +121,11 @@ 10.16 _intrinsic_id = vmIntrinsics::_none; 10.17 _liveness = NULL; 10.18 _can_be_statically_bound = false; 10.19 - _bcea = NULL; 10.20 _method_blocks = NULL; 10.21 _method_data = NULL; 10.22 #ifdef COMPILER2 10.23 _flow = NULL; 10.24 + _bcea = NULL; 10.25 #endif // COMPILER2 10.26 } 10.27 10.28 @@ -1033,10 +1033,15 @@ 10.29 bool ciMethod::is_initializer () const { FETCH_FLAG_FROM_VM(is_initializer); } 10.30 10.31 BCEscapeAnalyzer *ciMethod::get_bcea() { 10.32 +#ifdef COMPILER2 10.33 if (_bcea == NULL) { 10.34 _bcea = new (CURRENT_ENV->arena()) BCEscapeAnalyzer(this, NULL); 10.35 } 10.36 return _bcea; 10.37 +#else // COMPILER2 10.38 + ShouldNotReachHere(); 10.39 + return NULL; 10.40 +#endif // COMPILER2 10.41 } 10.42 10.43 ciMethodBlocks *ciMethod::get_method_blocks() {
11.1 --- a/src/share/vm/ci/ciMethod.hpp Wed Jul 14 17:52:18 2010 -0400 11.2 +++ b/src/share/vm/ci/ciMethod.hpp Thu Jul 15 13:48:01 2010 -0700 11.3 @@ -48,7 +48,6 @@ 11.4 ciInstanceKlass* _holder; 11.5 ciSignature* _signature; 11.6 ciMethodData* _method_data; 11.7 - BCEscapeAnalyzer* _bcea; 11.8 ciMethodBlocks* _method_blocks; 11.9 11.10 // Code attributes. 11.11 @@ -72,7 +71,8 @@ 11.12 // Optional liveness analyzer. 11.13 MethodLiveness* _liveness; 11.14 #ifdef COMPILER2 11.15 - ciTypeFlow* _flow; 11.16 + ciTypeFlow* _flow; 11.17 + BCEscapeAnalyzer* _bcea; 11.18 #endif 11.19 11.20 ciMethod(methodHandle h_m);
12.1 --- a/src/share/vm/classfile/classLoader.cpp Wed Jul 14 17:52:18 2010 -0400 12.2 +++ b/src/share/vm/classfile/classLoader.cpp Thu Jul 15 13:48:01 2010 -0700 12.3 @@ -1,5 +1,5 @@ 12.4 /* 12.5 - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. 12.6 + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.8 * 12.9 * This code is free software; you can redistribute it and/or modify it 12.10 @@ -832,7 +832,6 @@ 12.11 12.12 12.13 instanceKlassHandle ClassLoader::load_classfile(symbolHandle h_name, TRAPS) { 12.14 - VTuneClassLoadMarker clm; 12.15 ResourceMark rm(THREAD); 12.16 EventMark m("loading class " INTPTR_FORMAT, (address)h_name()); 12.17 ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);
13.1 --- a/src/share/vm/code/codeBlob.cpp Wed Jul 14 17:52:18 2010 -0400 13.2 +++ b/src/share/vm/code/codeBlob.cpp Thu Jul 15 13:48:01 2010 -0700 13.3 @@ -210,6 +210,7 @@ 13.4 { 13.5 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 13.6 blob = new (size) AdapterBlob(size, cb); 13.7 + CodeCache::commit(blob); 13.8 } 13.9 // Track memory usage statistic after releasing CodeCache_lock 13.10 MemoryService::track_code_cache_memory_usage(); 13.11 @@ -281,7 +282,6 @@ 13.12 tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, stub); 13.13 Disassembler::decode(stub->instructions_begin(), stub->instructions_end()); 13.14 } 13.15 - VTune::register_stub(stub_id, stub->instructions_begin(), stub->instructions_end()); 13.16 Forte::register_stub(stub_id, stub->instructions_begin(), stub->instructions_end()); 13.17 13.18 if (JvmtiExport::should_post_dynamic_code_generated()) { 13.19 @@ -356,7 +356,6 @@ 13.20 tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob); 13.21 Disassembler::decode(blob->instructions_begin(), blob->instructions_end()); 13.22 } 13.23 - VTune::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end()); 13.24 Forte::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end()); 13.25 13.26 if (JvmtiExport::should_post_dynamic_code_generated()) { 13.27 @@ -414,7 +413,6 @@ 13.28 tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob); 13.29 Disassembler::decode(blob->instructions_begin(), blob->instructions_end()); 13.30 } 13.31 - VTune::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end()); 13.32 Forte::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end()); 13.33 13.34 if (JvmtiExport::should_post_dynamic_code_generated()) { 13.35 @@ -474,7 +472,6 @@ 13.36 tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob); 13.37 Disassembler::decode(blob->instructions_begin(), blob->instructions_end()); 13.38 } 13.39 - VTune::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end()); 13.40 Forte::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end()); 13.41 13.42 if (JvmtiExport::should_post_dynamic_code_generated()) { 13.43 @@ -533,7 +530,6 @@ 13.44 tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob); 13.45 Disassembler::decode(blob->instructions_begin(), blob->instructions_end()); 13.46 } 13.47 - VTune::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end()); 13.48 Forte::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end()); 13.49 13.50 if (JvmtiExport::should_post_dynamic_code_generated()) {
14.1 --- a/src/share/vm/code/codeCache.cpp Wed Jul 14 17:52:18 2010 -0400 14.2 +++ b/src/share/vm/code/codeCache.cpp Thu Jul 15 13:48:01 2010 -0700 14.3 @@ -93,6 +93,8 @@ 14.4 14.5 CodeHeap * CodeCache::_heap = new CodeHeap(); 14.6 int CodeCache::_number_of_blobs = 0; 14.7 +int CodeCache::_number_of_adapters = 0; 14.8 +int CodeCache::_number_of_nmethods = 0; 14.9 int CodeCache::_number_of_nmethods_with_dependencies = 0; 14.10 bool CodeCache::_needs_cache_clean = false; 14.11 nmethod* CodeCache::_scavenge_root_nmethods = NULL; 14.12 @@ -176,8 +178,14 @@ 14.13 verify_if_often(); 14.14 14.15 print_trace("free", cb); 14.16 - if (cb->is_nmethod() && ((nmethod *)cb)->has_dependencies()) { 14.17 - _number_of_nmethods_with_dependencies--; 14.18 + if (cb->is_nmethod()) { 14.19 + _number_of_nmethods--; 14.20 + if (((nmethod *)cb)->has_dependencies()) { 14.21 + _number_of_nmethods_with_dependencies--; 14.22 + } 14.23 + } 14.24 + if (cb->is_adapter_blob()) { 14.25 + _number_of_adapters--; 14.26 } 14.27 _number_of_blobs--; 14.28 14.29 @@ -191,9 +199,16 @@ 14.30 void CodeCache::commit(CodeBlob* cb) { 14.31 // this is called by nmethod::nmethod, which must already own CodeCache_lock 14.32 assert_locked_or_safepoint(CodeCache_lock); 14.33 - if (cb->is_nmethod() && ((nmethod *)cb)->has_dependencies()) { 14.34 - _number_of_nmethods_with_dependencies++; 14.35 + if (cb->is_nmethod()) { 14.36 + _number_of_nmethods++; 14.37 + if (((nmethod *)cb)->has_dependencies()) { 14.38 + _number_of_nmethods_with_dependencies++; 14.39 + } 14.40 } 14.41 + if (cb->is_adapter_blob()) { 14.42 + _number_of_adapters++; 14.43 + } 14.44 + 14.45 // flush the hardware I-cache 14.46 ICache::invalidate_range(cb->instructions_begin(), cb->instructions_size()); 14.47 }
15.1 --- a/src/share/vm/code/codeCache.hpp Wed Jul 14 17:52:18 2010 -0400 15.2 +++ b/src/share/vm/code/codeCache.hpp Thu Jul 15 13:48:01 2010 -0700 15.3 @@ -1,5 +1,5 @@ 15.4 /* 15.5 - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 15.6 + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 15.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.8 * 15.9 * This code is free software; you can redistribute it and/or modify it 15.10 @@ -43,6 +43,8 @@ 15.11 // 4422213 or 4436291 for details. 15.12 static CodeHeap * _heap; 15.13 static int _number_of_blobs; 15.14 + static int _number_of_adapters; 15.15 + static int _number_of_nmethods; 15.16 static int _number_of_nmethods_with_dependencies; 15.17 static bool _needs_cache_clean; 15.18 static nmethod* _scavenge_root_nmethods; // linked via nm->scavenge_root_link() 15.19 @@ -105,6 +107,8 @@ 15.20 static nmethod* first_nmethod(); 15.21 static nmethod* next_nmethod (CodeBlob* cb); 15.22 static int nof_blobs() { return _number_of_blobs; } 15.23 + static int nof_adapters() { return _number_of_adapters; } 15.24 + static int nof_nmethods() { return _number_of_nmethods; } 15.25 15.26 // GC support 15.27 static void gc_epilogue();
16.1 --- a/src/share/vm/code/nmethod.cpp Wed Jul 14 17:52:18 2010 -0400 16.2 +++ b/src/share/vm/code/nmethod.cpp Thu Jul 15 13:48:01 2010 -0700 16.3 @@ -397,11 +397,6 @@ 16.4 //-------------end of code for ExceptionCache-------------- 16.5 16.6 16.7 -void nmFlags::clear() { 16.8 - assert(sizeof(nmFlags) == sizeof(int), "using more than one word for nmFlags"); 16.9 - *(jint*)this = 0; 16.10 -} 16.11 - 16.12 int nmethod::total_size() const { 16.13 return 16.14 code_size() + 16.15 @@ -419,8 +414,32 @@ 16.16 return NULL; 16.17 } 16.18 16.19 -// %%% This variable is no longer used? 16.20 -int nmethod::_zombie_instruction_size = NativeJump::instruction_size; 16.21 +// Fill in default values for various flag fields 16.22 +void nmethod::init_defaults() { 16.23 + _state = alive; 16.24 + _marked_for_reclamation = 0; 16.25 + _has_flushed_dependencies = 0; 16.26 + _speculatively_disconnected = 0; 16.27 + _has_unsafe_access = 0; 16.28 + _has_method_handle_invokes = 0; 16.29 + _marked_for_deoptimization = 0; 16.30 + _lock_count = 0; 16.31 + _stack_traversal_mark = 0; 16.32 + _unload_reported = false; // jvmti state 16.33 + 16.34 + NOT_PRODUCT(_has_debug_info = false); 16.35 + _oops_do_mark_link = NULL; 16.36 + _jmethod_id = NULL; 16.37 + _osr_link = NULL; 16.38 + _scavenge_root_link = NULL; 16.39 + _scavenge_root_state = 0; 16.40 + _saved_nmethod_link = NULL; 16.41 + _compiler = NULL; 16.42 + 16.43 +#ifdef HAVE_DTRACE_H 16.44 + _trap_offset = 0; 16.45 +#endif // def HAVE_DTRACE_H 16.46 +} 16.47 16.48 16.49 nmethod* nmethod::new_native_nmethod(methodHandle method, 16.50 @@ -580,25 +599,16 @@ 16.51 debug_only(No_Safepoint_Verifier nsv;) 16.52 assert_locked_or_safepoint(CodeCache_lock); 16.53 16.54 - NOT_PRODUCT(_has_debug_info = false); 16.55 - _oops_do_mark_link = NULL; 16.56 + init_defaults(); 16.57 _method = method; 16.58 _entry_bci = InvocationEntryBci; 16.59 - _jmethod_id = NULL; 16.60 - _osr_link = NULL; 16.61 - _scavenge_root_link = NULL; 16.62 - _scavenge_root_state = 0; 16.63 - _saved_nmethod_link = NULL; 16.64 - _compiler = NULL; 16.65 // We have no exception handler or deopt handler make the 16.66 // values something that will never match a pc like the nmethod vtable entry 16.67 _exception_offset = 0; 16.68 _deoptimize_offset = 0; 16.69 _deoptimize_mh_offset = 0; 16.70 _orig_pc_offset = 0; 16.71 -#ifdef HAVE_DTRACE_H 16.72 - _trap_offset = 0; 16.73 -#endif // def HAVE_DTRACE_H 16.74 + 16.75 _stub_offset = data_offset(); 16.76 _consts_offset = data_offset(); 16.77 _oops_offset = data_offset(); 16.78 @@ -616,17 +626,9 @@ 16.79 _exception_cache = NULL; 16.80 _pc_desc_cache.reset_to(NULL); 16.81 16.82 - flags.clear(); 16.83 - flags.state = alive; 16.84 - _markedForDeoptimization = 0; 16.85 - 16.86 - _lock_count = 0; 16.87 - _stack_traversal_mark = 0; 16.88 - 16.89 code_buffer->copy_oops_to(this); 16.90 debug_only(verify_scavenge_root_oops()); 16.91 CodeCache::commit(this); 16.92 - VTune::create_nmethod(this); 16.93 } 16.94 16.95 if (PrintNativeNMethods || PrintDebugInfo || PrintRelocations || PrintDependencies) { 16.96 @@ -674,15 +676,9 @@ 16.97 debug_only(No_Safepoint_Verifier nsv;) 16.98 assert_locked_or_safepoint(CodeCache_lock); 16.99 16.100 - NOT_PRODUCT(_has_debug_info = false); 16.101 - _oops_do_mark_link = NULL; 16.102 + init_defaults(); 16.103 _method = method; 16.104 _entry_bci = InvocationEntryBci; 16.105 - _jmethod_id = NULL; 16.106 - _osr_link = NULL; 16.107 - _scavenge_root_link = NULL; 16.108 - _scavenge_root_state = 0; 16.109 - _compiler = NULL; 16.110 // We have no exception handler or deopt handler make the 16.111 // values something that will never match a pc like the nmethod vtable entry 16.112 _exception_offset = 0; 16.113 @@ -708,17 +704,9 @@ 16.114 _exception_cache = NULL; 16.115 _pc_desc_cache.reset_to(NULL); 16.116 16.117 - flags.clear(); 16.118 - flags.state = alive; 16.119 - _markedForDeoptimization = 0; 16.120 - 16.121 - _lock_count = 0; 16.122 - _stack_traversal_mark = 0; 16.123 - 16.124 code_buffer->copy_oops_to(this); 16.125 debug_only(verify_scavenge_root_oops()); 16.126 CodeCache::commit(this); 16.127 - VTune::create_nmethod(this); 16.128 } 16.129 16.130 if (PrintNMethods || PrintDebugInfo || PrintRelocations || PrintDependencies) { 16.131 @@ -783,21 +771,13 @@ 16.132 debug_only(No_Safepoint_Verifier nsv;) 16.133 assert_locked_or_safepoint(CodeCache_lock); 16.134 16.135 - NOT_PRODUCT(_has_debug_info = false); 16.136 - _oops_do_mark_link = NULL; 16.137 + init_defaults(); 16.138 _method = method; 16.139 - _jmethod_id = NULL; 16.140 + _entry_bci = entry_bci; 16.141 _compile_id = compile_id; 16.142 _comp_level = comp_level; 16.143 - _entry_bci = entry_bci; 16.144 - _osr_link = NULL; 16.145 - _scavenge_root_link = NULL; 16.146 - _scavenge_root_state = 0; 16.147 _compiler = compiler; 16.148 _orig_pc_offset = orig_pc_offset; 16.149 -#ifdef HAVE_DTRACE_H 16.150 - _trap_offset = 0; 16.151 -#endif // def HAVE_DTRACE_H 16.152 _stub_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->stubs()->start()); 16.153 16.154 // Exception handler and deopt handler are in the stub section 16.155 @@ -824,15 +804,6 @@ 16.156 _exception_cache = NULL; 16.157 _pc_desc_cache.reset_to(scopes_pcs_begin()); 16.158 16.159 - flags.clear(); 16.160 - flags.state = alive; 16.161 - _markedForDeoptimization = 0; 16.162 - 16.163 - _unload_reported = false; // jvmti state 16.164 - 16.165 - _lock_count = 0; 16.166 - _stack_traversal_mark = 0; 16.167 - 16.168 // Copy contents of ScopeDescRecorder to nmethod 16.169 code_buffer->copy_oops_to(this); 16.170 debug_info->copy_to(this); 16.171 @@ -844,8 +815,6 @@ 16.172 16.173 CodeCache::commit(this); 16.174 16.175 - VTune::create_nmethod(this); 16.176 - 16.177 // Copy contents of ExceptionHandlerTable to nmethod 16.178 handler_table->copy_to(this); 16.179 nul_chk_table->copy_to(this); 16.180 @@ -991,11 +960,6 @@ 16.181 } 16.182 16.183 16.184 -void nmethod::set_version(int v) { 16.185 - flags.version = v; 16.186 -} 16.187 - 16.188 - 16.189 // Promote one word from an assembly-time handle to a live embedded oop. 16.190 inline void nmethod::initialize_immediate_oop(oop* dest, jobject handle) { 16.191 if (handle == NULL || 16.192 @@ -1142,6 +1106,8 @@ 16.193 // This is a private interface with the sweeper. 16.194 void nmethod::mark_as_seen_on_stack() { 16.195 assert(is_not_entrant(), "must be a non-entrant method"); 16.196 + // Set the traversal mark to ensure that the sweeper does 2 16.197 + // cleaning passes before moving to zombie. 16.198 set_stack_traversal_mark(NMethodSweeper::traversal_count()); 16.199 } 16.200 16.201 @@ -1210,7 +1176,7 @@ 16.202 // for later on. 16.203 CodeCache::set_needs_cache_clean(true); 16.204 } 16.205 - flags.state = unloaded; 16.206 + _state = unloaded; 16.207 16.208 // Log the unloading. 16.209 log_state_change(); 16.210 @@ -1236,21 +1202,21 @@ 16.211 if (LogCompilation) { 16.212 if (xtty != NULL) { 16.213 ttyLocker ttyl; // keep the following output all in one block 16.214 - if (flags.state == unloaded) { 16.215 + if (_state == unloaded) { 16.216 xtty->begin_elem("make_unloaded thread='" UINTX_FORMAT "'", 16.217 os::current_thread_id()); 16.218 } else { 16.219 xtty->begin_elem("make_not_entrant thread='" UINTX_FORMAT "'%s", 16.220 os::current_thread_id(), 16.221 - (flags.state == zombie ? " zombie='1'" : "")); 16.222 + (_state == zombie ? " zombie='1'" : "")); 16.223 } 16.224 log_identity(xtty); 16.225 xtty->stamp(); 16.226 xtty->end_elem(); 16.227 } 16.228 } 16.229 - if (PrintCompilation && flags.state != unloaded) { 16.230 - print_on(tty, flags.state == zombie ? "made zombie " : "made not entrant "); 16.231 + if (PrintCompilation && _state != unloaded) { 16.232 + print_on(tty, _state == zombie ? "made zombie " : "made not entrant "); 16.233 tty->cr(); 16.234 } 16.235 } 16.236 @@ -1261,8 +1227,9 @@ 16.237 16.238 bool was_alive = false; 16.239 16.240 - // Make sure the nmethod is not flushed in case of a safepoint in code below. 16.241 + // Make sure neither the nmethod nor the method is flushed in case of a safepoint in code below. 16.242 nmethodLocker nml(this); 16.243 + methodHandle the_method(method()); 16.244 16.245 { 16.246 // If the method is already zombie there is nothing to do 16.247 @@ -1282,7 +1249,7 @@ 16.248 // Enter critical section. Does not block for safepoint. 16.249 MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); 16.250 16.251 - if (flags.state == state) { 16.252 + if (_state == state) { 16.253 // another thread already performed this transition so nothing 16.254 // to do, but return false to indicate this. 16.255 return false; 16.256 @@ -1293,17 +1260,37 @@ 16.257 if (!is_osr_method() && !is_not_entrant()) { 16.258 NativeJump::patch_verified_entry(entry_point(), verified_entry_point(), 16.259 SharedRuntime::get_handle_wrong_method_stub()); 16.260 - assert (NativeJump::instruction_size == nmethod::_zombie_instruction_size, ""); 16.261 } 16.262 16.263 - was_alive = is_in_use(); // Read state under lock 16.264 + if (is_in_use()) { 16.265 + // It's a true state change, so mark the method as decompiled. 16.266 + // Do it only for transition from alive. 16.267 + inc_decompile_count(); 16.268 + } 16.269 16.270 // Change state 16.271 - flags.state = state; 16.272 + _state = state; 16.273 16.274 // Log the transition once 16.275 log_state_change(); 16.276 16.277 + // Remove nmethod from method. 16.278 + // We need to check if both the _code and _from_compiled_code_entry_point 16.279 + // refer to this nmethod because there is a race in setting these two fields 16.280 + // in methodOop as seen in bugid 4947125. 16.281 + // If the vep() points to the zombie nmethod, the memory for the nmethod 16.282 + // could be flushed and the compiler and vtable stubs could still call 16.283 + // through it. 16.284 + if (method() != NULL && (method()->code() == this || 16.285 + method()->from_compiled_entry() == verified_entry_point())) { 16.286 + HandleMark hm; 16.287 + method()->clear_code(); 16.288 + } 16.289 + 16.290 + if (state == not_entrant) { 16.291 + mark_as_seen_on_stack(); 16.292 + } 16.293 + 16.294 } // leave critical region under Patching_lock 16.295 16.296 // When the nmethod becomes zombie it is no longer alive so the 16.297 @@ -1311,18 +1298,17 @@ 16.298 // state will be flushed later when the transition to zombie 16.299 // happens or they get unloaded. 16.300 if (state == zombie) { 16.301 + // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event 16.302 + // and it hasn't already been reported for this nmethod then report it now. 16.303 + // (the event may have been reported earilier if the GC marked it for unloading). 16.304 + post_compiled_method_unload(); 16.305 + 16.306 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 16.307 flush_dependencies(NULL); 16.308 } else { 16.309 assert(state == not_entrant, "other cases may need to be handled differently"); 16.310 } 16.311 16.312 - if (state == not_entrant) { 16.313 - Events::log("Make nmethod not entrant " INTPTR_FORMAT, this); 16.314 - } else { 16.315 - Events::log("Make nmethod zombie " INTPTR_FORMAT, this); 16.316 - } 16.317 - 16.318 if (TraceCreateZombies) { 16.319 tty->print_cr("nmethod <" INTPTR_FORMAT "> code made %s", this, (state == not_entrant) ? "not entrant" : "zombie"); 16.320 } 16.321 @@ -1330,47 +1316,6 @@ 16.322 // Make sweeper aware that there is a zombie method that needs to be removed 16.323 NMethodSweeper::notify(this); 16.324 16.325 - // not_entrant only stuff 16.326 - if (state == not_entrant) { 16.327 - mark_as_seen_on_stack(); 16.328 - } 16.329 - 16.330 - if (was_alive) { 16.331 - // It's a true state change, so mark the method as decompiled. 16.332 - // Do it only for transition from alive. 16.333 - inc_decompile_count(); 16.334 - } 16.335 - 16.336 - // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event 16.337 - // and it hasn't already been reported for this nmethod then report it now. 16.338 - // (the event may have been reported earilier if the GC marked it for unloading). 16.339 - if (state == zombie) { 16.340 - post_compiled_method_unload(); 16.341 - } 16.342 - 16.343 - 16.344 - // Zombie only stuff 16.345 - if (state == zombie) { 16.346 - VTune::delete_nmethod(this); 16.347 - } 16.348 - 16.349 - // Check whether method got unloaded at a safepoint before this, 16.350 - // if so we can skip the flushing steps below 16.351 - if (method() == NULL) return true; 16.352 - 16.353 - // Remove nmethod from method. 16.354 - // We need to check if both the _code and _from_compiled_code_entry_point 16.355 - // refer to this nmethod because there is a race in setting these two fields 16.356 - // in methodOop as seen in bugid 4947125. 16.357 - // If the vep() points to the zombie nmethod, the memory for the nmethod 16.358 - // could be flushed and the compiler and vtable stubs could still call 16.359 - // through it. 16.360 - if (method()->code() == this || 16.361 - method()->from_compiled_entry() == verified_entry_point()) { 16.362 - HandleMark hm; 16.363 - method()->clear_code(); 16.364 - } 16.365 - 16.366 return true; 16.367 } 16.368 16.369 @@ -2109,7 +2054,6 @@ 16.370 16.371 void nmethod_init() { 16.372 // make sure you didn't forget to adjust the filler fields 16.373 - assert(sizeof(nmFlags) <= 4, "nmFlags occupies more than a word"); 16.374 assert(sizeof(nmethod) % oopSize == 0, "nmethod size must be multiple of a word"); 16.375 } 16.376 16.377 @@ -2345,7 +2289,6 @@ 16.378 tty->print("((nmethod*) "INTPTR_FORMAT ") ", this); 16.379 tty->print(" for method " INTPTR_FORMAT , (address)method()); 16.380 tty->print(" { "); 16.381 - if (version()) tty->print("v%d ", version()); 16.382 if (is_in_use()) tty->print("in_use "); 16.383 if (is_not_entrant()) tty->print("not_entrant "); 16.384 if (is_zombie()) tty->print("zombie ");
17.1 --- a/src/share/vm/code/nmethod.hpp Wed Jul 14 17:52:18 2010 -0400 17.2 +++ b/src/share/vm/code/nmethod.hpp Thu Jul 15 13:48:01 2010 -0700 17.3 @@ -78,29 +78,8 @@ 17.4 17.5 17.6 // nmethods (native methods) are the compiled code versions of Java methods. 17.7 - 17.8 -struct nmFlags { 17.9 - friend class VMStructs; 17.10 - unsigned int version:8; // version number (0 = first version) 17.11 - unsigned int age:4; // age (in # of sweep steps) 17.12 - 17.13 - unsigned int state:2; // {alive, zombie, unloaded) 17.14 - 17.15 - unsigned int isUncommonRecompiled:1; // recompiled because of uncommon trap? 17.16 - unsigned int isToBeRecompiled:1; // to be recompiled as soon as it matures 17.17 - unsigned int hasFlushedDependencies:1; // Used for maintenance of dependencies 17.18 - unsigned int markedForReclamation:1; // Used by NMethodSweeper 17.19 - 17.20 - unsigned int has_unsafe_access:1; // May fault due to unsafe access. 17.21 - unsigned int has_method_handle_invokes:1; // Has this method MethodHandle invokes? 17.22 - 17.23 - unsigned int speculatively_disconnected:1; // Marked for potential unload 17.24 - 17.25 - void clear(); 17.26 -}; 17.27 - 17.28 - 17.29 -// A nmethod contains: 17.30 +// 17.31 +// An nmethod contains: 17.32 // - header (the nmethod structure) 17.33 // [Relocation] 17.34 // - relocation information 17.35 @@ -131,8 +110,6 @@ 17.36 friend class CodeCache; // non-perm oops 17.37 private: 17.38 // Shared fields for all nmethod's 17.39 - static int _zombie_instruction_size; 17.40 - 17.41 methodOop _method; 17.42 int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method 17.43 jmethodID _jmethod_id; // Cache of method()->jmethod_id() 17.44 @@ -147,6 +124,11 @@ 17.45 17.46 AbstractCompiler* _compiler; // The compiler which compiled this nmethod 17.47 17.48 + // offsets for entry points 17.49 + address _entry_point; // entry point with class check 17.50 + address _verified_entry_point; // entry point without class check 17.51 + address _osr_entry_point; // entry point for on stack replacement 17.52 + 17.53 // Offsets for different nmethod parts 17.54 int _exception_offset; 17.55 // All deoptee's will resume execution at this location described by 17.56 @@ -175,23 +157,31 @@ 17.57 // pc during a deopt. 17.58 int _orig_pc_offset; 17.59 17.60 - int _compile_id; // which compilation made this nmethod 17.61 - int _comp_level; // compilation level 17.62 + int _compile_id; // which compilation made this nmethod 17.63 + int _comp_level; // compilation level 17.64 17.65 - // offsets for entry points 17.66 - address _entry_point; // entry point with class check 17.67 - address _verified_entry_point; // entry point without class check 17.68 - address _osr_entry_point; // entry point for on stack replacement 17.69 + // protected by CodeCache_lock 17.70 + bool _has_flushed_dependencies; // Used for maintenance of dependencies (CodeCache_lock) 17.71 + bool _speculatively_disconnected; // Marked for potential unload 17.72 17.73 - nmFlags flags; // various flags to keep track of nmethod state 17.74 - bool _markedForDeoptimization; // Used for stack deoptimization 17.75 + bool _marked_for_reclamation; // Used by NMethodSweeper (set only by sweeper) 17.76 + bool _marked_for_deoptimization; // Used for stack deoptimization 17.77 + 17.78 + // used by jvmti to track if an unload event has been posted for this nmethod. 17.79 + bool _unload_reported; 17.80 + 17.81 + // set during construction 17.82 + unsigned int _has_unsafe_access:1; // May fault due to unsafe access. 17.83 + unsigned int _has_method_handle_invokes:1; // Has this method MethodHandle invokes? 17.84 + 17.85 + // Protected by Patching_lock 17.86 + unsigned char _state; // {alive, not_entrant, zombie, unloaded) 17.87 + 17.88 enum { alive = 0, 17.89 not_entrant = 1, // uncommon trap has happened but activations may still exist 17.90 zombie = 2, 17.91 unloaded = 3 }; 17.92 17.93 - // used by jvmti to track if an unload event has been posted for this nmethod. 17.94 - bool _unload_reported; 17.95 17.96 jbyte _scavenge_root_state; 17.97 17.98 @@ -270,15 +260,15 @@ 17.99 bool make_not_entrant_or_zombie(unsigned int state); 17.100 void inc_decompile_count(); 17.101 17.102 - // used to check that writes to nmFlags are done consistently. 17.103 - static void check_safepoint() PRODUCT_RETURN; 17.104 - 17.105 // Used to manipulate the exception cache 17.106 void add_exception_cache_entry(ExceptionCache* new_entry); 17.107 ExceptionCache* exception_cache_entry_for_exception(Handle exception); 17.108 17.109 // Inform external interfaces that a compiled method has been unloaded 17.110 - inline void post_compiled_method_unload(); 17.111 + void post_compiled_method_unload(); 17.112 + 17.113 + // Initailize fields to their default values 17.114 + void init_defaults(); 17.115 17.116 public: 17.117 // create nmethod with entry_bci 17.118 @@ -393,11 +383,11 @@ 17.119 address verified_entry_point() const { return _verified_entry_point; } // if klass is correct 17.120 17.121 // flag accessing and manipulation 17.122 - bool is_in_use() const { return flags.state == alive; } 17.123 - bool is_alive() const { return flags.state == alive || flags.state == not_entrant; } 17.124 - bool is_not_entrant() const { return flags.state == not_entrant; } 17.125 - bool is_zombie() const { return flags.state == zombie; } 17.126 - bool is_unloaded() const { return flags.state == unloaded; } 17.127 + bool is_in_use() const { return _state == alive; } 17.128 + bool is_alive() const { return _state == alive || _state == not_entrant; } 17.129 + bool is_not_entrant() const { return _state == not_entrant; } 17.130 + bool is_zombie() const { return _state == zombie; } 17.131 + bool is_unloaded() const { return _state == unloaded; } 17.132 17.133 // Make the nmethod non entrant. The nmethod will continue to be 17.134 // alive. It is used when an uncommon trap happens. Returns true 17.135 @@ -410,37 +400,33 @@ 17.136 bool unload_reported() { return _unload_reported; } 17.137 void set_unload_reported() { _unload_reported = true; } 17.138 17.139 - bool is_marked_for_deoptimization() const { return _markedForDeoptimization; } 17.140 - void mark_for_deoptimization() { _markedForDeoptimization = true; } 17.141 + bool is_marked_for_deoptimization() const { return _marked_for_deoptimization; } 17.142 + void mark_for_deoptimization() { _marked_for_deoptimization = true; } 17.143 17.144 void make_unloaded(BoolObjectClosure* is_alive, oop cause); 17.145 17.146 bool has_dependencies() { return dependencies_size() != 0; } 17.147 void flush_dependencies(BoolObjectClosure* is_alive); 17.148 - bool has_flushed_dependencies() { return flags.hasFlushedDependencies; } 17.149 - void set_has_flushed_dependencies() { 17.150 + bool has_flushed_dependencies() { return _has_flushed_dependencies; } 17.151 + void set_has_flushed_dependencies() { 17.152 assert(!has_flushed_dependencies(), "should only happen once"); 17.153 - flags.hasFlushedDependencies = 1; 17.154 + _has_flushed_dependencies = 1; 17.155 } 17.156 17.157 - bool is_marked_for_reclamation() const { return flags.markedForReclamation; } 17.158 - void mark_for_reclamation() { flags.markedForReclamation = 1; } 17.159 - void unmark_for_reclamation() { flags.markedForReclamation = 0; } 17.160 + bool is_marked_for_reclamation() const { return _marked_for_reclamation; } 17.161 + void mark_for_reclamation() { _marked_for_reclamation = 1; } 17.162 17.163 - bool has_unsafe_access() const { return flags.has_unsafe_access; } 17.164 - void set_has_unsafe_access(bool z) { flags.has_unsafe_access = z; } 17.165 + bool has_unsafe_access() const { return _has_unsafe_access; } 17.166 + void set_has_unsafe_access(bool z) { _has_unsafe_access = z; } 17.167 17.168 - bool has_method_handle_invokes() const { return flags.has_method_handle_invokes; } 17.169 - void set_has_method_handle_invokes(bool z) { flags.has_method_handle_invokes = z; } 17.170 + bool has_method_handle_invokes() const { return _has_method_handle_invokes; } 17.171 + void set_has_method_handle_invokes(bool z) { _has_method_handle_invokes = z; } 17.172 17.173 - bool is_speculatively_disconnected() const { return flags.speculatively_disconnected; } 17.174 - void set_speculatively_disconnected(bool z) { flags.speculatively_disconnected = z; } 17.175 + bool is_speculatively_disconnected() const { return _speculatively_disconnected; } 17.176 + void set_speculatively_disconnected(bool z) { _speculatively_disconnected = z; } 17.177 17.178 int comp_level() const { return _comp_level; } 17.179 17.180 - int version() const { return flags.version; } 17.181 - void set_version(int v); 17.182 - 17.183 // Support for oops in scopes and relocs: 17.184 // Note: index 0 is reserved for null. 17.185 oop oop_at(int index) const { return index == 0 ? (oop) NULL: *oop_addr_at(index); }
18.1 --- a/src/share/vm/code/vtableStubs.cpp Wed Jul 14 17:52:18 2010 -0400 18.2 +++ b/src/share/vm/code/vtableStubs.cpp Thu Jul 15 13:48:01 2010 -0700 18.3 @@ -1,5 +1,5 @@ 18.4 /* 18.5 - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. 18.6 + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 18.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.8 * 18.9 * This code is free software; you can redistribute it and/or modify it 18.10 @@ -50,7 +50,6 @@ 18.11 } 18.12 _chunk = blob->instructions_begin(); 18.13 _chunk_end = _chunk + bytes; 18.14 - VTune::register_stub("vtable stub", _chunk, _chunk_end); 18.15 Forte::register_stub("vtable stub", _chunk, _chunk_end); 18.16 // Notify JVMTI about this stub. The event will be recorded by the enclosing 18.17 // JvmtiDynamicCodeEventCollector and posted when this thread has released
19.1 --- a/src/share/vm/includeDB_compiler2 Wed Jul 14 17:52:18 2010 -0400 19.2 +++ b/src/share/vm/includeDB_compiler2 Thu Jul 15 13:48:01 2010 -0700 19.3 @@ -89,6 +89,21 @@ 19.4 19.5 allocation.hpp c2_globals.hpp 19.6 19.7 +bcEscapeAnalyzer.cpp bcEscapeAnalyzer.hpp 19.8 +bcEscapeAnalyzer.cpp bitMap.inline.hpp 19.9 +bcEscapeAnalyzer.cpp bytecode.hpp 19.10 +bcEscapeAnalyzer.cpp ciConstant.hpp 19.11 +bcEscapeAnalyzer.cpp ciField.hpp 19.12 +bcEscapeAnalyzer.cpp ciMethodBlocks.hpp 19.13 +bcEscapeAnalyzer.cpp ciStreams.hpp 19.14 + 19.15 +bcEscapeAnalyzer.hpp allocation.hpp 19.16 +bcEscapeAnalyzer.hpp ciMethod.hpp 19.17 +bcEscapeAnalyzer.hpp ciMethodData.hpp 19.18 +bcEscapeAnalyzer.hpp dependencies.hpp 19.19 +bcEscapeAnalyzer.hpp growableArray.hpp 19.20 +bcEscapeAnalyzer.hpp vectset.hpp 19.21 + 19.22 block.cpp allocation.inline.hpp 19.23 block.cpp block.hpp 19.24 block.cpp cfgnode.hpp 19.25 @@ -239,6 +254,7 @@ 19.26 ciEnv.cpp compileLog.hpp 19.27 ciEnv.cpp runtime.hpp 19.28 19.29 +ciMethod.cpp bcEscapeAnalyzer.hpp 19.30 ciMethod.cpp ciTypeFlow.hpp 19.31 ciMethod.cpp methodOop.hpp 19.32
20.1 --- a/src/share/vm/includeDB_core Wed Jul 14 17:52:18 2010 -0400 20.2 +++ b/src/share/vm/includeDB_core Thu Jul 15 13:48:01 2010 -0700 20.3 @@ -301,20 +301,6 @@ 20.4 barrierSet.inline.hpp barrierSet.hpp 20.5 barrierSet.inline.hpp cardTableModRefBS.hpp 20.6 20.7 -bcEscapeAnalyzer.cpp bcEscapeAnalyzer.hpp 20.8 -bcEscapeAnalyzer.cpp bitMap.inline.hpp 20.9 -bcEscapeAnalyzer.cpp bytecode.hpp 20.10 -bcEscapeAnalyzer.cpp ciConstant.hpp 20.11 -bcEscapeAnalyzer.cpp ciField.hpp 20.12 -bcEscapeAnalyzer.cpp ciMethodBlocks.hpp 20.13 -bcEscapeAnalyzer.cpp ciStreams.hpp 20.14 - 20.15 -bcEscapeAnalyzer.hpp allocation.hpp 20.16 -bcEscapeAnalyzer.hpp ciMethod.hpp 20.17 -bcEscapeAnalyzer.hpp ciMethodData.hpp 20.18 -bcEscapeAnalyzer.hpp dependencies.hpp 20.19 -bcEscapeAnalyzer.hpp growableArray.hpp 20.20 - 20.21 biasedLocking.cpp biasedLocking.hpp 20.22 biasedLocking.cpp klass.inline.hpp 20.23 biasedLocking.cpp markOop.hpp 20.24 @@ -665,7 +651,6 @@ 20.25 20.26 ciMethod.cpp abstractCompiler.hpp 20.27 ciMethod.cpp allocation.inline.hpp 20.28 -ciMethod.cpp bcEscapeAnalyzer.hpp 20.29 ciMethod.cpp bitMap.inline.hpp 20.30 ciMethod.cpp ciCallProfile.hpp 20.31 ciMethod.cpp ciExceptionHandler.hpp 20.32 @@ -964,7 +949,6 @@ 20.33 classLoader.cpp timer.hpp 20.34 classLoader.cpp universe.inline.hpp 20.35 classLoader.cpp vmSymbols.hpp 20.36 -classLoader.cpp vtune.hpp 20.37 20.38 classLoader.hpp classFileParser.hpp 20.39 classLoader.hpp perfData.hpp 20.40 @@ -1004,7 +988,6 @@ 20.41 codeBlob.cpp safepoint.hpp 20.42 codeBlob.cpp sharedRuntime.hpp 20.43 codeBlob.cpp vframe.hpp 20.44 -codeBlob.cpp vtune.hpp 20.45 20.46 codeBlob.hpp codeBuffer.hpp 20.47 codeBlob.hpp frame.hpp 20.48 @@ -2167,7 +2150,6 @@ 20.49 interpreter.cpp stubRoutines.hpp 20.50 interpreter.cpp templateTable.hpp 20.51 interpreter.cpp timer.hpp 20.52 -interpreter.cpp vtune.hpp 20.53 20.54 interpreter.hpp cppInterpreter.hpp 20.55 interpreter.hpp stubs.hpp 20.56 @@ -2323,7 +2305,6 @@ 20.57 java.cpp vmError.hpp 20.58 java.cpp vm_operations.hpp 20.59 java.cpp vm_version_<arch>.hpp 20.60 -java.cpp vtune.hpp 20.61 20.62 java.hpp os.hpp 20.63 20.64 @@ -3050,7 +3031,6 @@ 20.65 nmethod.cpp scopeDesc.hpp 20.66 nmethod.cpp sharedRuntime.hpp 20.67 nmethod.cpp sweeper.hpp 20.68 -nmethod.cpp vtune.hpp 20.69 nmethod.cpp xmlstream.hpp 20.70 20.71 nmethod.hpp codeBlob.hpp 20.72 @@ -3773,7 +3753,6 @@ 20.73 sharedRuntime.cpp vmSymbols.hpp 20.74 sharedRuntime.cpp vmreg_<arch>.inline.hpp 20.75 sharedRuntime.cpp vtableStubs.hpp 20.76 -sharedRuntime.cpp vtune.hpp 20.77 sharedRuntime.cpp xmlstream.hpp 20.78 20.79 sharedRuntime.hpp allocation.hpp 20.80 @@ -3937,7 +3916,6 @@ 20.81 stubCodeGenerator.cpp forte.hpp 20.82 stubCodeGenerator.cpp oop.inline.hpp 20.83 stubCodeGenerator.cpp stubCodeGenerator.hpp 20.84 -stubCodeGenerator.cpp vtune.hpp 20.85 20.86 stubCodeGenerator.hpp allocation.hpp 20.87 stubCodeGenerator.hpp assembler.hpp 20.88 @@ -4458,7 +4436,6 @@ 20.89 universe.cpp universe.inline.hpp 20.90 universe.cpp vmSymbols.hpp 20.91 universe.cpp vm_operations.hpp 20.92 -universe.cpp vtune.hpp 20.93 20.94 universe.hpp growableArray.hpp 20.95 universe.hpp handles.hpp 20.96 @@ -4721,7 +4698,6 @@ 20.97 vtableStubs.cpp resourceArea.hpp 20.98 vtableStubs.cpp sharedRuntime.hpp 20.99 vtableStubs.cpp vtableStubs.hpp 20.100 -vtableStubs.cpp vtune.hpp 20.101 20.102 vtableStubs.hpp allocation.hpp 20.103 20.104 @@ -4735,11 +4711,6 @@ 20.105 vtableStubs_<arch_model>.cpp vmreg_<arch>.inline.hpp 20.106 vtableStubs_<arch_model>.cpp vtableStubs.hpp 20.107 20.108 -vtune.hpp allocation.hpp 20.109 - 20.110 -vtune_<os_family>.cpp interpreter.hpp 20.111 -vtune_<os_family>.cpp vtune.hpp 20.112 - 20.113 watermark.hpp allocation.hpp 20.114 watermark.hpp globalDefinitions.hpp 20.115
21.1 --- a/src/share/vm/interpreter/interpreter.cpp Wed Jul 14 17:52:18 2010 -0400 21.2 +++ b/src/share/vm/interpreter/interpreter.cpp Thu Jul 15 13:48:01 2010 -0700 21.3 @@ -99,11 +99,6 @@ 21.4 #endif // PRODUCT 21.5 // need to hit every safepoint in order to call zapping routine 21.6 // register the interpreter 21.7 - VTune::register_stub( 21.8 - "Interpreter", 21.9 - AbstractInterpreter::code()->code_start(), 21.10 - AbstractInterpreter::code()->code_end() 21.11 - ); 21.12 Forte::register_stub( 21.13 "Interpreter", 21.14 AbstractInterpreter::code()->code_start(),
22.1 --- a/src/share/vm/opto/doCall.cpp Wed Jul 14 17:52:18 2010 -0400 22.2 +++ b/src/share/vm/opto/doCall.cpp Thu Jul 15 13:48:01 2010 -0700 22.3 @@ -343,7 +343,8 @@ 22.4 // being initialized. Uncommon-trap for not-initialized static or 22.5 // v-calls. Let interface calls happen. 22.6 ciInstanceKlass* holder_klass = dest_method->holder(); 22.7 - if (!holder_klass->is_initialized() && 22.8 + if (!holder_klass->is_being_initialized() && 22.9 + !holder_klass->is_initialized() && 22.10 !holder_klass->is_interface()) { 22.11 uncommon_trap(Deoptimization::Reason_uninitialized, 22.12 Deoptimization::Action_reinterpret,
23.1 --- a/src/share/vm/opto/parse.hpp Wed Jul 14 17:52:18 2010 -0400 23.2 +++ b/src/share/vm/opto/parse.hpp Thu Jul 15 13:48:01 2010 -0700 23.3 @@ -480,6 +480,7 @@ 23.4 bool push_constant(ciConstant con, bool require_constant = false); 23.5 23.6 // implementation of object creation bytecodes 23.7 + void emit_guard_for_new(ciInstanceKlass* klass); 23.8 void do_new(); 23.9 void do_newarray(BasicType elemtype); 23.10 void do_anewarray();
24.1 --- a/src/share/vm/opto/parseHelper.cpp Wed Jul 14 17:52:18 2010 -0400 24.2 +++ b/src/share/vm/opto/parseHelper.cpp Thu Jul 15 13:48:01 2010 -0700 24.3 @@ -1,5 +1,5 @@ 24.4 /* 24.5 - * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. 24.6 + * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. 24.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 24.8 * 24.9 * This code is free software; you can redistribute it and/or modify it 24.10 @@ -197,6 +197,43 @@ 24.11 } 24.12 24.13 24.14 +void Parse::emit_guard_for_new(ciInstanceKlass* klass) { 24.15 + // Emit guarded new 24.16 + // if (klass->_init_thread != current_thread || 24.17 + // klass->_init_state != being_initialized) 24.18 + // uncommon_trap 24.19 + Node* cur_thread = _gvn.transform( new (C, 1) ThreadLocalNode() ); 24.20 + Node* merge = new (C, 3) RegionNode(3); 24.21 + _gvn.set_type(merge, Type::CONTROL); 24.22 + Node* kls = makecon(TypeKlassPtr::make(klass)); 24.23 + 24.24 + Node* init_thread_offset = _gvn.MakeConX(instanceKlass::init_thread_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()); 24.25 + Node* adr_node = basic_plus_adr(kls, kls, init_thread_offset); 24.26 + Node* init_thread = make_load(NULL, adr_node, TypeRawPtr::BOTTOM, T_ADDRESS); 24.27 + Node *tst = Bool( CmpP( init_thread, cur_thread), BoolTest::eq); 24.28 + IfNode* iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN); 24.29 + set_control(IfTrue(iff)); 24.30 + merge->set_req(1, IfFalse(iff)); 24.31 + 24.32 + Node* init_state_offset = _gvn.MakeConX(instanceKlass::init_state_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()); 24.33 + adr_node = basic_plus_adr(kls, kls, init_state_offset); 24.34 + Node* init_state = make_load(NULL, adr_node, TypeInt::INT, T_INT); 24.35 + Node* being_init = _gvn.intcon(instanceKlass::being_initialized); 24.36 + tst = Bool( CmpI( init_state, being_init), BoolTest::eq); 24.37 + iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN); 24.38 + set_control(IfTrue(iff)); 24.39 + merge->set_req(2, IfFalse(iff)); 24.40 + 24.41 + PreserveJVMState pjvms(this); 24.42 + record_for_igvn(merge); 24.43 + set_control(merge); 24.44 + 24.45 + uncommon_trap(Deoptimization::Reason_uninitialized, 24.46 + Deoptimization::Action_reinterpret, 24.47 + klass); 24.48 +} 24.49 + 24.50 + 24.51 //------------------------------do_new----------------------------------------- 24.52 void Parse::do_new() { 24.53 kill_dead_locals(); 24.54 @@ -206,7 +243,7 @@ 24.55 assert(will_link, "_new: typeflow responsibility"); 24.56 24.57 // Should initialize, or throw an InstantiationError? 24.58 - if (!klass->is_initialized() || 24.59 + if (!klass->is_initialized() && !klass->is_being_initialized() || 24.60 klass->is_abstract() || klass->is_interface() || 24.61 klass->name() == ciSymbol::java_lang_Class() || 24.62 iter().is_unresolved_klass()) { 24.63 @@ -215,6 +252,9 @@ 24.64 klass); 24.65 return; 24.66 } 24.67 + if (klass->is_being_initialized()) { 24.68 + emit_guard_for_new(klass); 24.69 + } 24.70 24.71 Node* kls = makecon(TypeKlassPtr::make(klass)); 24.72 Node* obj = new_instance(kls);
25.1 --- a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp Wed Jul 14 17:52:18 2010 -0400 25.2 +++ b/src/share/vm/prims/jvmtiCodeBlobEvents.cpp Thu Jul 15 13:48:01 2010 -0700 25.3 @@ -118,7 +118,6 @@ 25.4 for (int i=0; i<_global_code_blobs->length(); i++) { 25.5 JvmtiCodeBlobDesc* scb = _global_code_blobs->at(i); 25.6 if (addr == scb->code_begin()) { 25.7 - ShouldNotReachHere(); 25.8 return; 25.9 } 25.10 } 25.11 @@ -206,11 +205,11 @@ 25.12 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 25.13 nmethod* current = CodeCache::first_nmethod(); 25.14 while (current != NULL) { 25.15 - // Lock the nmethod so it can't be freed 25.16 - nmethodLocker nml(current); 25.17 - 25.18 // Only notify for live nmethods 25.19 if (current->is_alive()) { 25.20 + // Lock the nmethod so it can't be freed 25.21 + nmethodLocker nml(current); 25.22 + 25.23 // Don't hold the lock over the notify or jmethodID creation 25.24 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 25.25 current->get_and_cache_jmethod_id();
26.1 --- a/src/share/vm/runtime/globals.hpp Wed Jul 14 17:52:18 2010 -0400 26.2 +++ b/src/share/vm/runtime/globals.hpp Thu Jul 15 13:48:01 2010 -0700 26.3 @@ -2541,9 +2541,6 @@ 26.4 "Enable String cache capabilities on String.java") \ 26.5 \ 26.6 /* statistics */ \ 26.7 - develop(bool, UseVTune, false, \ 26.8 - "enable support for Intel's VTune profiler") \ 26.9 - \ 26.10 develop(bool, CountCompiledCalls, false, \ 26.11 "counts method invocations") \ 26.12 \
27.1 --- a/src/share/vm/runtime/init.cpp Wed Jul 14 17:52:18 2010 -0400 27.2 +++ b/src/share/vm/runtime/init.cpp Thu Jul 15 13:48:01 2010 -0700 27.3 @@ -34,7 +34,6 @@ 27.4 27.5 // Initialization done by Java thread in init_globals() 27.6 void management_init(); 27.7 -void vtune_init(); 27.8 void bytecodes_init(); 27.9 void classLoader_init(); 27.10 void codeCache_init(); 27.11 @@ -82,7 +81,6 @@ 27.12 jint init_globals() { 27.13 HandleMark hm; 27.14 management_init(); 27.15 - vtune_init(); 27.16 bytecodes_init(); 27.17 classLoader_init(); 27.18 codeCache_init();
28.1 --- a/src/share/vm/runtime/java.cpp Wed Jul 14 17:52:18 2010 -0400 28.2 +++ b/src/share/vm/runtime/java.cpp Thu Jul 15 13:48:01 2010 -0700 28.3 @@ -1,5 +1,5 @@ 28.4 /* 28.5 - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 28.6 + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 28.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 28.8 * 28.9 * This code is free software; you can redistribute it and/or modify it 28.10 @@ -432,8 +432,6 @@ 28.11 print_statistics(); 28.12 Universe::heap()->print_tracing_info(); 28.13 28.14 - VTune::exit(); 28.15 - 28.16 { MutexLocker ml(BeforeExit_lock); 28.17 _before_exit_status = BEFORE_EXIT_DONE; 28.18 BeforeExit_lock->notify_all();
29.1 --- a/src/share/vm/runtime/sharedRuntime.cpp Wed Jul 14 17:52:18 2010 -0400 29.2 +++ b/src/share/vm/runtime/sharedRuntime.cpp Thu Jul 15 13:48:01 2010 -0700 29.3 @@ -2251,7 +2251,6 @@ 29.4 B->name(), 29.5 fingerprint->as_string(), 29.6 B->instructions_begin()); 29.7 - VTune::register_stub(blob_id, B->instructions_begin(), B->instructions_end()); 29.8 Forte::register_stub(blob_id, B->instructions_begin(), B->instructions_end()); 29.9 29.10 if (JvmtiExport::should_post_dynamic_code_generated()) {
30.1 --- a/src/share/vm/runtime/stubCodeGenerator.cpp Wed Jul 14 17:52:18 2010 -0400 30.2 +++ b/src/share/vm/runtime/stubCodeGenerator.cpp Thu Jul 15 13:48:01 2010 -0700 30.3 @@ -1,5 +1,5 @@ 30.4 /* 30.5 - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. 30.6 + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 30.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 30.8 * 30.9 * This code is free software; you can redistribute it and/or modify it 30.10 @@ -132,7 +132,6 @@ 30.11 _cdesc->set_end(_cgen->assembler()->pc()); 30.12 assert(StubCodeDesc::_list == _cdesc, "expected order on list"); 30.13 _cgen->stub_epilog(_cdesc); 30.14 - VTune::register_stub(_cdesc->name(), _cdesc->begin(), _cdesc->end()); 30.15 Forte::register_stub(_cdesc->name(), _cdesc->begin(), _cdesc->end()); 30.16 30.17 if (JvmtiExport::should_post_dynamic_code_generated()) {
31.1 --- a/src/share/vm/runtime/sweeper.cpp Wed Jul 14 17:52:18 2010 -0400 31.2 +++ b/src/share/vm/runtime/sweeper.cpp Thu Jul 15 13:48:01 2010 -0700 31.3 @@ -1,5 +1,5 @@ 31.4 /* 31.5 - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. 31.6 + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 31.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 31.8 * 31.9 * This code is free software; you can redistribute it and/or modify it 31.10 @@ -27,14 +27,15 @@ 31.11 31.12 long NMethodSweeper::_traversals = 0; // No. of stack traversals performed 31.13 nmethod* NMethodSweeper::_current = NULL; // Current nmethod 31.14 -int NMethodSweeper::_seen = 0 ; // No. of blobs we have currently processed in current pass of CodeCache 31.15 -int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass 31.16 +int NMethodSweeper::_seen = 0 ; // No. of nmethods we have currently processed in current pass of CodeCache 31.17 + 31.18 +volatile int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass 31.19 +volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress. 31.20 31.21 jint NMethodSweeper::_locked_seen = 0; 31.22 jint NMethodSweeper::_not_entrant_seen_on_stack = 0; 31.23 bool NMethodSweeper::_rescan = false; 31.24 bool NMethodSweeper::_do_sweep = false; 31.25 -jint NMethodSweeper::_sweep_started = 0; 31.26 bool NMethodSweeper::_was_full = false; 31.27 jint NMethodSweeper::_advise_to_sweep = 0; 31.28 jlong NMethodSweeper::_last_was_full = 0; 31.29 @@ -108,23 +109,14 @@ 31.30 // code cache is filling up 31.31 _last_was_full = os::javaTimeMillis(); 31.32 31.33 - if (PrintMethodFlushing) { 31.34 - tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler", 31.35 - CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 31.36 - } 31.37 - if (LogCompilation && (xtty != NULL)) { 31.38 - ttyLocker ttyl; 31.39 - xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", 31.40 - CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 31.41 - xtty->stamp(); 31.42 - xtty->end_elem(); 31.43 - } 31.44 + log_sweep("restart_compiler"); 31.45 } 31.46 } 31.47 } 31.48 } 31.49 31.50 void NMethodSweeper::possibly_sweep() { 31.51 + assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode"); 31.52 if ((!MethodFlushing) || (!_do_sweep)) return; 31.53 31.54 if (_invocations > 0) { 31.55 @@ -133,32 +125,31 @@ 31.56 if (old != 0) { 31.57 return; 31.58 } 31.59 - sweep_code_cache(); 31.60 + if (_invocations > 0) { 31.61 + sweep_code_cache(); 31.62 + _invocations--; 31.63 + } 31.64 + _sweep_started = 0; 31.65 } 31.66 - _sweep_started = 0; 31.67 } 31.68 31.69 void NMethodSweeper::sweep_code_cache() { 31.70 #ifdef ASSERT 31.71 jlong sweep_start; 31.72 - if(PrintMethodFlushing) { 31.73 + if (PrintMethodFlushing) { 31.74 sweep_start = os::javaTimeMillis(); 31.75 } 31.76 #endif 31.77 if (PrintMethodFlushing && Verbose) { 31.78 - tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_blobs(), _invocations); 31.79 + tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _invocations); 31.80 } 31.81 31.82 - // We want to visit all nmethods after NmethodSweepFraction invocations. 31.83 - // If invocation is 1 we do the rest 31.84 - int todo = CodeCache::nof_blobs(); 31.85 - if (_invocations > 1) { 31.86 - todo = (CodeCache::nof_blobs() - _seen) / _invocations; 31.87 - } 31.88 - 31.89 - // Compilers may check to sweep more often than stack scans happen, 31.90 - // don't keep trying once it is all scanned 31.91 - _invocations--; 31.92 + // We want to visit all nmethods after NmethodSweepFraction 31.93 + // invocations so divide the remaining number of nmethods by the 31.94 + // remaining number of invocations. This is only an estimate since 31.95 + // the number of nmethods changes during the sweep so the final 31.96 + // stage must iterate until it there are no more nmethods. 31.97 + int todo = (CodeCache::nof_nmethods() - _seen) / _invocations; 31.98 31.99 assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here"); 31.100 assert(!CodeCache_lock->owned_by_self(), "just checking"); 31.101 @@ -166,11 +157,12 @@ 31.102 { 31.103 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 31.104 31.105 - for(int i = 0; i < todo && _current != NULL; i++) { 31.106 + // The last invocation iterates until there are no more nmethods 31.107 + for (int i = 0; (i < todo || _invocations == 1) && _current != NULL; i++) { 31.108 31.109 - // Since we will give up the CodeCache_lock, always skip ahead to an nmethod. 31.110 - // Other blobs can be deleted by other threads 31.111 - // Read next before we potentially delete current 31.112 + // Since we will give up the CodeCache_lock, always skip ahead 31.113 + // to the next nmethod. Other blobs can be deleted by other 31.114 + // threads but nmethods are only reclaimed by the sweeper. 31.115 nmethod* next = CodeCache::next_nmethod(_current); 31.116 31.117 // Now ready to process nmethod and give up CodeCache_lock 31.118 @@ -183,6 +175,8 @@ 31.119 } 31.120 } 31.121 31.122 + assert(_invocations > 1 || _current == NULL, "must have scanned the whole cache"); 31.123 + 31.124 if (_current == NULL && !_rescan && (_locked_seen || _not_entrant_seen_on_stack)) { 31.125 // we've completed a scan without making progress but there were 31.126 // nmethods we were unable to process either because they were 31.127 @@ -201,6 +195,10 @@ 31.128 tty->print_cr("### sweeper: sweep time(%d): " INT64_FORMAT, _invocations, sweep_end - sweep_start); 31.129 } 31.130 #endif 31.131 + 31.132 + if (_invocations == 1) { 31.133 + log_sweep("finished"); 31.134 + } 31.135 } 31.136 31.137 31.138 @@ -223,7 +221,7 @@ 31.139 if (nm->is_zombie()) { 31.140 // If it is first time, we see nmethod then we mark it. Otherwise, 31.141 // we reclame it. When we have seen a zombie method twice, we know that 31.142 - // there are no inline caches that referes to it. 31.143 + // there are no inline caches that refer to it. 31.144 if (nm->is_marked_for_reclamation()) { 31.145 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); 31.146 if (PrintMethodFlushing && Verbose) { 31.147 @@ -320,16 +318,8 @@ 31.148 jlong curr_interval = now - _last_was_full; 31.149 if (curr_interval < max_interval) { 31.150 _rescan = true; 31.151 - if (PrintMethodFlushing) { 31.152 - tty->print_cr("### handle full too often, turning off compiler"); 31.153 - } 31.154 - if (LogCompilation && (xtty != NULL)) { 31.155 - ttyLocker ttyl; 31.156 - xtty->begin_elem("disable_compiler flushing_interval='" UINT64_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", 31.157 - curr_interval/1000, CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 31.158 - xtty->stamp(); 31.159 - xtty->end_elem(); 31.160 - } 31.161 + log_sweep("disable_compiler", "flushing_interval='" UINT64_FORMAT "'", 31.162 + curr_interval/1000); 31.163 return; 31.164 } 31.165 } 31.166 @@ -349,17 +339,7 @@ 31.167 31.168 if ((!was_full()) && (is_full)) { 31.169 if (!CodeCache::needs_flushing()) { 31.170 - if (PrintMethodFlushing) { 31.171 - tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler", 31.172 - CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 31.173 - } 31.174 - if (LogCompilation && (xtty != NULL)) { 31.175 - ttyLocker ttyl; 31.176 - xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", 31.177 - CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 31.178 - xtty->stamp(); 31.179 - xtty->end_elem(); 31.180 - } 31.181 + log_sweep("restart_compiler"); 31.182 CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); 31.183 return; 31.184 } 31.185 @@ -368,17 +348,7 @@ 31.186 // Traverse the code cache trying to dump the oldest nmethods 31.187 uint curr_max_comp_id = CompileBroker::get_compilation_id(); 31.188 uint flush_target = ((curr_max_comp_id - _highest_marked) >> 1) + _highest_marked; 31.189 - if (PrintMethodFlushing && Verbose) { 31.190 - tty->print_cr("### Cleaning code cache: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes", 31.191 - CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 31.192 - } 31.193 - if (LogCompilation && (xtty != NULL)) { 31.194 - ttyLocker ttyl; 31.195 - xtty->begin_elem("start_cleaning_code_cache live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", 31.196 - CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 31.197 - xtty->stamp(); 31.198 - xtty->end_elem(); 31.199 - } 31.200 + log_sweep("start_cleaning"); 31.201 31.202 nmethod* nm = CodeCache::alive_nmethod(CodeCache::first()); 31.203 jint disconnected = 0; 31.204 @@ -411,13 +381,9 @@ 31.205 nm = CodeCache::alive_nmethod(CodeCache::next(nm)); 31.206 } 31.207 31.208 - if (LogCompilation && (xtty != NULL)) { 31.209 - ttyLocker ttyl; 31.210 - xtty->begin_elem("stop_cleaning_code_cache disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", 31.211 - disconnected, made_not_entrant, CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); 31.212 - xtty->stamp(); 31.213 - xtty->end_elem(); 31.214 - } 31.215 + log_sweep("stop_cleaning", 31.216 + "disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "'", 31.217 + disconnected, made_not_entrant); 31.218 31.219 // Shut off compiler. Sweeper will start over with a new stack scan and 31.220 // traversal cycle and turn it back on if it clears enough space. 31.221 @@ -435,3 +401,38 @@ 31.222 } 31.223 #endif 31.224 } 31.225 + 31.226 + 31.227 +// Print out some state information about the current sweep and the 31.228 +// state of the code cache if it's requested. 31.229 +void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { 31.230 + if (PrintMethodFlushing) { 31.231 + ttyLocker ttyl; 31.232 + tty->print("### sweeper: %s ", msg); 31.233 + if (format != NULL) { 31.234 + va_list ap; 31.235 + va_start(ap, format); 31.236 + tty->vprint(format, ap); 31.237 + va_end(ap); 31.238 + } 31.239 + tty->print_cr(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'" 31.240 + " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", 31.241 + CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity()); 31.242 + } 31.243 + 31.244 + if (LogCompilation && (xtty != NULL)) { 31.245 + ttyLocker ttyl; 31.246 + xtty->begin_elem("sweeper state='%s' traversals='" INTX_FORMAT "' ", msg, (intx)traversal_count()); 31.247 + if (format != NULL) { 31.248 + va_list ap; 31.249 + va_start(ap, format); 31.250 + xtty->vprint(format, ap); 31.251 + va_end(ap); 31.252 + } 31.253 + xtty->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'" 31.254 + " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", 31.255 + CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity()); 31.256 + xtty->stamp(); 31.257 + xtty->end_elem(); 31.258 + } 31.259 +}
32.1 --- a/src/share/vm/runtime/sweeper.hpp Wed Jul 14 17:52:18 2010 -0400 32.2 +++ b/src/share/vm/runtime/sweeper.hpp Thu Jul 15 13:48:01 2010 -0700 32.3 @@ -1,5 +1,5 @@ 32.4 /* 32.5 - * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. 32.6 + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 32.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.8 * 32.9 * This code is free software; you can redistribute it and/or modify it 32.10 @@ -31,12 +31,13 @@ 32.11 static long _traversals; // Stack traversal count 32.12 static nmethod* _current; // Current nmethod 32.13 static int _seen; // Nof. nmethod we have currently processed in current pass of CodeCache 32.14 - static int _invocations; // No. of invocations left until we are completed with this pass 32.15 + 32.16 + static volatile int _invocations; // No. of invocations left until we are completed with this pass 32.17 + static volatile int _sweep_started; // Flag to control conc sweeper 32.18 32.19 static bool _rescan; // Indicates that we should do a full rescan of the 32.20 // of the code cache looking for work to do. 32.21 static bool _do_sweep; // Flag to skip the conc sweep if no stack scan happened 32.22 - static jint _sweep_started; // Flag to control conc sweeper 32.23 static int _locked_seen; // Number of locked nmethods encountered during the scan 32.24 static int _not_entrant_seen_on_stack; // Number of not entrant nmethod were are still on stack 32.25 32.26 @@ -47,6 +48,9 @@ 32.27 static long _was_full_traversal; // trav number at last emergency unloading 32.28 32.29 static void process_nmethod(nmethod *nm); 32.30 + 32.31 + static void log_sweep(const char* msg, const char* format = NULL, ...); 32.32 + 32.33 public: 32.34 static long traversal_count() { return _traversals; } 32.35
33.1 --- a/src/share/vm/runtime/vmStructs.cpp Wed Jul 14 17:52:18 2010 -0400 33.2 +++ b/src/share/vm/runtime/vmStructs.cpp Thu Jul 15 13:48:01 2010 -0700 33.3 @@ -614,7 +614,6 @@ 33.4 /* NMethods (NOTE: incomplete, but only a little) */ \ 33.5 /**************************************************/ \ 33.6 \ 33.7 - static_field(nmethod, _zombie_instruction_size, int) \ 33.8 nonstatic_field(nmethod, _method, methodOop) \ 33.9 nonstatic_field(nmethod, _entry_bci, int) \ 33.10 nonstatic_field(nmethod, _osr_link, nmethod*) \
34.1 --- a/src/share/vm/runtime/vtune.hpp Wed Jul 14 17:52:18 2010 -0400 34.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 34.3 @@ -1,55 +0,0 @@ 34.4 -/* 34.5 - * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. 34.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 34.7 - * 34.8 - * This code is free software; you can redistribute it and/or modify it 34.9 - * under the terms of the GNU General Public License version 2 only, as 34.10 - * published by the Free Software Foundation. 34.11 - * 34.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 34.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 34.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 34.15 - * version 2 for more details (a copy is included in the LICENSE file that 34.16 - * accompanied this code). 34.17 - * 34.18 - * You should have received a copy of the GNU General Public License version 34.19 - * 2 along with this work; if not, write to the Free Software Foundation, 34.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 34.21 - * 34.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 34.23 - * or visit www.oracle.com if you need additional information or have any 34.24 - * questions. 34.25 - * 34.26 - */ 34.27 - 34.28 -// Interface to Intel's VTune profiler. 34.29 - 34.30 -class VTune : AllStatic { 34.31 - public: 34.32 - static void create_nmethod(nmethod* nm); // register newly created nmethod 34.33 - static void delete_nmethod(nmethod* nm); // unregister nmethod before discarding it 34.34 - 34.35 - static void register_stub(const char* name, address start, address end); 34.36 - // register internal VM stub 34.37 - static void start_GC(); // start/end of GC or scavenge 34.38 - static void end_GC(); 34.39 - 34.40 - static void start_class_load(); // start/end of class loading 34.41 - static void end_class_load(); 34.42 - 34.43 - static void exit(); // VM exit 34.44 -}; 34.45 - 34.46 - 34.47 -// helper objects 34.48 -class VTuneGCMarker : StackObj { 34.49 - public: 34.50 - VTuneGCMarker() { VTune::start_GC(); } 34.51 - ~VTuneGCMarker() { VTune::end_GC(); } 34.52 -}; 34.53 - 34.54 -class VTuneClassLoadMarker : StackObj { 34.55 - public: 34.56 - VTuneClassLoadMarker() { VTune::start_class_load(); } 34.57 - ~VTuneClassLoadMarker() { VTune::end_class_load(); } 34.58 -};