6965184: possible races in make_not_entrant_or_zombie
authornever
Thu, 08 Jul 2010 14:29:44 -0700
changeset 5924 dc9d04930c82
parent 5915 406168b53eb0
child 5925 a30fef61d0b7
6965184: possible races in make_not_entrant_or_zombie Reviewed-by: kvn
hotspot/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java
hotspot/src/os/linux/vm/vtune_linux.cpp
hotspot/src/os/solaris/vm/vtune_solaris.cpp
hotspot/src/os/windows/vm/vtune_windows.cpp
hotspot/src/share/vm/classfile/classLoader.cpp
hotspot/src/share/vm/code/codeBlob.cpp
hotspot/src/share/vm/code/codeCache.cpp
hotspot/src/share/vm/code/codeCache.hpp
hotspot/src/share/vm/code/nmethod.cpp
hotspot/src/share/vm/code/nmethod.hpp
hotspot/src/share/vm/code/vtableStubs.cpp
hotspot/src/share/vm/includeDB_core
hotspot/src/share/vm/interpreter/interpreter.cpp
hotspot/src/share/vm/runtime/globals.hpp
hotspot/src/share/vm/runtime/init.cpp
hotspot/src/share/vm/runtime/java.cpp
hotspot/src/share/vm/runtime/sharedRuntime.cpp
hotspot/src/share/vm/runtime/stubCodeGenerator.cpp
hotspot/src/share/vm/runtime/sweeper.cpp
hotspot/src/share/vm/runtime/sweeper.hpp
hotspot/src/share/vm/runtime/vmStructs.cpp
hotspot/src/share/vm/runtime/vtune.hpp
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Thu Jul 08 14:29:44 2010 -0700
@@ -35,7 +35,6 @@
 
 public class NMethod extends CodeBlob {
   private static long          pcDescSize;
-  private static CIntegerField zombieInstructionSizeField;
   private static sun.jvm.hotspot.types.OopField methodField;
   /** != InvocationEntryBci if this nmethod is an on-stack replacement method */
   private static CIntegerField entryBCIField;
@@ -88,7 +87,6 @@
   private static void initialize(TypeDataBase db) {
     Type type = db.lookupType("nmethod");
 
-    zombieInstructionSizeField  = type.getCIntegerField("_zombie_instruction_size");
     methodField                 = type.getOopField("_method");
     entryBCIField               = type.getCIntegerField("_entry_bci");
     osrLinkField                = type.getAddressField("_osr_link");
--- a/hotspot/src/os/linux/vm/vtune_linux.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "incls/_precompiled.incl"
-#include "incls/_vtune_linux.cpp.incl"
-
-// empty implementation
-
-void VTune::start_GC() {}
-void VTune::end_GC() {}
-void VTune::start_class_load() {}
-void VTune::end_class_load() {}
-void VTune::exit() {}
-void VTune::register_stub(const char* name, address start, address end) {}
-
-void VTune::create_nmethod(nmethod* nm) {}
-void VTune::delete_nmethod(nmethod* nm) {}
-
-void vtune_init() {}
-
-
-// Reconciliation History
-// vtune_solaris.cpp    1.8 99/07/12 23:54:21
-// End
--- a/hotspot/src/os/solaris/vm/vtune_solaris.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "incls/_precompiled.incl"
-#include "incls/_vtune_solaris.cpp.incl"
-
-// empty implementation
-
-void VTune::start_GC() {}
-void VTune::end_GC() {}
-void VTune::start_class_load() {}
-void VTune::end_class_load() {}
-void VTune::exit() {}
-void VTune::register_stub(const char* name, address start, address end) {}
-
-void VTune::create_nmethod(nmethod* nm) {}
-void VTune::delete_nmethod(nmethod* nm) {}
-
-void vtune_init() {}
--- a/hotspot/src/os/windows/vm/vtune_windows.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,290 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "incls/_precompiled.incl"
-#include "incls/_vtune_windows.cpp.incl"
-
-static int current_method_ID = 0;
-
-// ------------- iJITProf.h -------------------
-// defined by Intel -- do not change
-
-#include "windows.h"
-
-extern "C" {
-  enum iJITP_Event {
-    ExceptionOccurred_S,                  // Java exception
-    ExceptionOccurred_IDS,
-
-    Shutdown,                             // VM exit
-
-    ThreadCreate,                         // threads
-    ThreadDestroy,
-    ThreadSwitch,
-
-    ClassLoadStart,                       // class loading
-    ClassLoadEnd,
-
-    GCStart,                              // GC
-    GCEnd,
-
-    NMethodCreate = 13,                   // nmethod creation
-    NMethodDelete
-
-    // rest of event types omitted (call profiling not supported yet)
-  };
-
-  // version number -- 0 if VTune not installed
-  int WINAPI iJitP_VersionNumber();
-
-  enum iJITP_ModeFlags {
-    NoNotification = 0x0,                // don't call vtune
-    NotifyNMethodCreate   = 0x1,         // notify NMethod_Create
-    NotifyNMethodDelete   = 0x2,         // notify NMethod_Create
-    NotifyMethodEnter     = 0x4,         // method entry
-    NotifyMethodExit      = 0x8,         // method exit
-    NotifyShutdown        = 0x10,        // VM exit
-    NotifyGC              = 0x20,        // GC
-  };
-
-  // call back function type
-  typedef void (WINAPI *ModeChangedFn)(iJITP_ModeFlags flags);
-
-  // -------------  VTune method interfaces ----------------------
-  typedef void  (WINAPI *RegisterCallbackFn)(ModeChangedFn fn);   // register callback
-  typedef int   (WINAPI *NotifyEventFn)(iJITP_Event, void* event_data);
-
-  // specific event data structures
-
-  // data for NMethodCreate
-
-  struct VTuneObj {                       // base class for allocation
-                                          // (can't use CHeapObj -- has vtable ptr)
-    void* operator new(size_t size) { return os::malloc(size); }
-    void  operator delete(void* p)  { fatal("never delete VTune data"); }
-  };
-
-  struct LineNumberInfo : VTuneObj {      // PC-to-line number mapping
-    unsigned long offset;                 // byte offset from start of method
-    unsigned long line_num;               // corresponding line number
-  };
-
-  struct MethodLoadInfo : VTuneObj {
-    unsigned long methodID;               // unique method ID
-    const char* name;                     // method name
-    unsigned long instr_start;            // start address
-    unsigned long instr_size;             // length in bytes
-    unsigned long line_number_size;       // size of line number table
-    LineNumberInfo* line_number_table;    // line number mapping
-    unsigned long classID;                // unique class ID
-    char* class_file_name;                // fully qualified class file name
-    char* source_file_name;               // fully qualified source file name
-
-    MethodLoadInfo(nmethod* nm);          // for real nmethods
-    MethodLoadInfo(const char* vm_name, address start, address end);
-                                          // for "nmethods" like stubs, interpreter, etc
-
-  };
-
-  // data for NMethodDelete
-  struct MethodInfo : VTuneObj {
-    unsigned long methodID;               // unique method ID
-    unsigned long classID;                // (added for convenience -- not part of Intel interface)
-
-    MethodInfo(methodOop m);
-  };
-};
-
-MethodInfo::MethodInfo(methodOop m) {
-  // just give it a new ID -- we're not compiling methods twice (usually)
-  // (and even if we did, one might want to see the two versions separately)
-  methodID = ++current_method_ID;
-}
-
-MethodLoadInfo::MethodLoadInfo(const char* vm_name, address start, address end) {
-  classID  = 0;
-  methodID = ++current_method_ID;
-  name = vm_name;
-  instr_start = (unsigned long)start;
-  instr_size = end - start;
-  line_number_size = 0;
-  line_number_table = NULL;
-  class_file_name = source_file_name = "HotSpot JVM";
-}
-
-MethodLoadInfo::MethodLoadInfo(nmethod* nm) {
-  methodOop m = nm->method();
-  MethodInfo info(m);
-  classID  = info.classID;
-  methodID = info.methodID;
-  name = strdup(m->name()->as_C_string());
-  instr_start = (unsigned long)nm->instructions_begin();
-  instr_size = nm->code_size();
-  line_number_size = 0;
-  line_number_table = NULL;
-  klassOop kl = m->method_holder();
-  char* class_name = Klass::cast(kl)->name()->as_C_string();
-  char* file_name = NEW_C_HEAP_ARRAY(char, strlen(class_name) + 1);
-  strcpy(file_name, class_name);
-  class_file_name = file_name;
-  char* src_name = NEW_C_HEAP_ARRAY(char, strlen(class_name) + strlen(".java") + 1);
-  strcpy(src_name, class_name);
-  strcat(src_name, ".java");
-  source_file_name = src_name;
-}
-
-// --------------------- DLL loading functions ------------------------
-
-#define DLLNAME "iJitProf.dll"
-
-static HINSTANCE load_lib(char* name) {
-  HINSTANCE lib = NULL;
-  HKEY hk;
-
-  // try to get VTune directory from the registry
-  if (RegOpenKey(HKEY_CURRENT_USER, "Software\\VB and VBA Program Settings\\VTune\\StartUp", &hk) == ERROR_SUCCESS) {
-    for (int i = 0; true; i++) {
-      char szName[MAX_PATH + 1];
-      char szVal [MAX_PATH + 1];
-      DWORD cbName, cbVal;
-
-      cbName = cbVal = MAX_PATH + 1;
-      if (RegEnumValue(hk, i, szName, &cbName, NULL, NULL, (LPBYTE)szVal, &cbVal) == ERROR_SUCCESS) {
-        // get VTune directory
-        if (!strcmp(szName, name)) {
-          char*p = szVal;
-          while (*p == ' ') p++;    // trim
-          char* q = p + strlen(p) - 1;
-          while (*q == ' ') *(q--) = '\0';
-
-          // chdir to the VTune dir
-          GetCurrentDirectory(MAX_PATH + 1, szName);
-          SetCurrentDirectory(p);
-          // load lib
-          lib = LoadLibrary(strcat(strcat(p, "\\"), DLLNAME));
-          if (lib != NULL && WizardMode) tty->print_cr("*loaded VTune DLL %s", p);
-          // restore current dir
-          SetCurrentDirectory(szName);
-          break;
-        }
-      } else {
-        break;
-      }
-    }
-  }
-  return lib;
-}
-
-static RegisterCallbackFn iJIT_RegisterCallback = NULL;
-static NotifyEventFn      iJIT_NotifyEvent      = NULL;
-
-static bool load_iJIT_funcs() {
-  // first try to load from PATH
-  HINSTANCE lib = LoadLibrary(DLLNAME);
-  if (lib != NULL && WizardMode) tty->print_cr("*loaded VTune DLL %s via PATH", DLLNAME);
-
-  // if not successful, try to look in the VTUNE directory
-  if (lib == NULL) lib = load_lib("VTUNEDIR30");
-  if (lib == NULL) lib = load_lib("VTUNEDIR25");
-  if (lib == NULL) lib = load_lib("VTUNEDIR");
-
-  if (lib == NULL) return false;    // unsuccessful
-
-  // try to load the functions
-  iJIT_RegisterCallback = (RegisterCallbackFn)GetProcAddress(lib, "iJIT_RegisterCallback");
-  iJIT_NotifyEvent      = (NotifyEventFn)     GetProcAddress(lib, "iJIT_NotifyEvent");
-
-  if (!iJIT_RegisterCallback) tty->print_cr("*couldn't find VTune entry point iJIT_RegisterCallback");
-  if (!iJIT_NotifyEvent)      tty->print_cr("*couldn't find VTune entry point iJIT_NotifyEvent");
-  return iJIT_RegisterCallback != NULL && iJIT_NotifyEvent != NULL;
-}
-
-// --------------------- VTune class ------------------------
-
-static bool active = false;
-static int  flags  = 0;
-
-void VTune::start_GC() {
-  if (active && (flags & NotifyGC)) iJIT_NotifyEvent(GCStart, NULL);
-}
-
-void VTune::end_GC() {
-  if (active && (flags & NotifyGC)) iJIT_NotifyEvent(GCEnd, NULL);
-}
-
-void VTune::start_class_load() {
-  // not yet implemented in VTune
-}
-
-void VTune::end_class_load() {
-  // not yet implemented in VTune
-}
-
-void VTune::exit() {
-  if (active && (flags & NotifyShutdown)) iJIT_NotifyEvent(Shutdown, NULL);
-}
-
-void VTune::register_stub(const char* name, address start, address end) {
-  if (flags & NotifyNMethodCreate) {
-    MethodLoadInfo* info = new MethodLoadInfo(name, start, end);
-    if (PrintMiscellaneous && WizardMode && Verbose) {
-      tty->print_cr("NMethodCreate %s (%d): %#x..%#x", info->name, info->methodID,
-                    info->instr_start, info->instr_start + info->instr_size);
-    }
-    iJIT_NotifyEvent(NMethodCreate, info);
-  }
-}
-
-void VTune::create_nmethod(nmethod* nm) {
-  if (flags & NotifyNMethodCreate) {
-    MethodLoadInfo* info = new MethodLoadInfo(nm);
-    if (PrintMiscellaneous && WizardMode && Verbose) {
-      tty->print_cr("NMethodCreate %s (%d): %#x..%#x", info->name, info->methodID,
-                    info->instr_start, info->instr_start + info->instr_size);
-    }
-    iJIT_NotifyEvent(NMethodCreate, info);
-  }
-}
-
-void VTune::delete_nmethod(nmethod* nm) {
-  if (flags & NotifyNMethodDelete) {
-    MethodInfo* info = new MethodInfo(nm->method());
-    iJIT_NotifyEvent(NMethodDelete, info);
-  }
-}
-
-static void set_flags(int new_flags) {
-  flags = new_flags;
-  // if (WizardMode) tty->print_cr("*new VTune flags: %#x", flags);
-}
-
-void vtune_init() {
-  if (!UseVTune) return;
-  active = load_iJIT_funcs();
-  if (active) {
-    iJIT_RegisterCallback((ModeChangedFn)set_flags);
-  } else {
-    assert(flags == 0, "flags shouldn't be set");
-  }
-}
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Thu Jul 08 14:29:44 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -832,7 +832,6 @@
 
 
 instanceKlassHandle ClassLoader::load_classfile(symbolHandle h_name, TRAPS) {
-  VTuneClassLoadMarker clm;
   ResourceMark rm(THREAD);
   EventMark m("loading class " INTPTR_FORMAT, (address)h_name());
   ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);
--- a/hotspot/src/share/vm/code/codeBlob.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/code/codeBlob.cpp	Thu Jul 08 14:29:44 2010 -0700
@@ -210,6 +210,7 @@
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
     blob = new (size) AdapterBlob(size, cb);
+    CodeCache::commit(blob);
   }
   // Track memory usage statistic after releasing CodeCache_lock
   MemoryService::track_code_cache_memory_usage();
@@ -281,7 +282,6 @@
       tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, stub);
       Disassembler::decode(stub->instructions_begin(), stub->instructions_end());
     }
-    VTune::register_stub(stub_id, stub->instructions_begin(), stub->instructions_end());
     Forte::register_stub(stub_id, stub->instructions_begin(), stub->instructions_end());
 
     if (JvmtiExport::should_post_dynamic_code_generated()) {
@@ -356,7 +356,6 @@
       tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
       Disassembler::decode(blob->instructions_begin(), blob->instructions_end());
     }
-    VTune::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end());
     Forte::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end());
 
     if (JvmtiExport::should_post_dynamic_code_generated()) {
@@ -414,7 +413,6 @@
       tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
       Disassembler::decode(blob->instructions_begin(), blob->instructions_end());
     }
-    VTune::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end());
     Forte::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end());
 
     if (JvmtiExport::should_post_dynamic_code_generated()) {
@@ -474,7 +472,6 @@
       tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
       Disassembler::decode(blob->instructions_begin(), blob->instructions_end());
     }
-    VTune::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end());
     Forte::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end());
 
     if (JvmtiExport::should_post_dynamic_code_generated()) {
@@ -533,7 +530,6 @@
       tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
       Disassembler::decode(blob->instructions_begin(), blob->instructions_end());
     }
-    VTune::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end());
     Forte::register_stub(blob_id, blob->instructions_begin(), blob->instructions_end());
 
     if (JvmtiExport::should_post_dynamic_code_generated()) {
--- a/hotspot/src/share/vm/code/codeCache.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Thu Jul 08 14:29:44 2010 -0700
@@ -93,6 +93,8 @@
 
 CodeHeap * CodeCache::_heap = new CodeHeap();
 int CodeCache::_number_of_blobs = 0;
+int CodeCache::_number_of_adapters = 0;
+int CodeCache::_number_of_nmethods = 0;
 int CodeCache::_number_of_nmethods_with_dependencies = 0;
 bool CodeCache::_needs_cache_clean = false;
 nmethod* CodeCache::_scavenge_root_nmethods = NULL;
@@ -176,8 +178,14 @@
   verify_if_often();
 
   print_trace("free", cb);
-  if (cb->is_nmethod() && ((nmethod *)cb)->has_dependencies()) {
-    _number_of_nmethods_with_dependencies--;
+  if (cb->is_nmethod()) {
+    _number_of_nmethods--;
+    if (((nmethod *)cb)->has_dependencies()) {
+      _number_of_nmethods_with_dependencies--;
+    }
+  }
+  if (cb->is_adapter_blob()) {
+    _number_of_adapters--;
   }
   _number_of_blobs--;
 
@@ -191,9 +199,16 @@
 void CodeCache::commit(CodeBlob* cb) {
   // this is called by nmethod::nmethod, which must already own CodeCache_lock
   assert_locked_or_safepoint(CodeCache_lock);
-  if (cb->is_nmethod() && ((nmethod *)cb)->has_dependencies()) {
-    _number_of_nmethods_with_dependencies++;
+  if (cb->is_nmethod()) {
+    _number_of_nmethods++;
+    if (((nmethod *)cb)->has_dependencies()) {
+      _number_of_nmethods_with_dependencies++;
+    }
   }
+  if (cb->is_adapter_blob()) {
+    _number_of_adapters++;
+  }
+
   // flush the hardware I-cache
   ICache::invalidate_range(cb->instructions_begin(), cb->instructions_size());
 }
--- a/hotspot/src/share/vm/code/codeCache.hpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/code/codeCache.hpp	Thu Jul 08 14:29:44 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,8 @@
   // 4422213 or 4436291 for details.
   static CodeHeap * _heap;
   static int _number_of_blobs;
+  static int _number_of_adapters;
+  static int _number_of_nmethods;
   static int _number_of_nmethods_with_dependencies;
   static bool _needs_cache_clean;
   static nmethod* _scavenge_root_nmethods;  // linked via nm->scavenge_root_link()
@@ -105,6 +107,8 @@
   static nmethod* first_nmethod();
   static nmethod* next_nmethod (CodeBlob* cb);
   static int       nof_blobs()                 { return _number_of_blobs; }
+  static int       nof_adapters()              { return _number_of_adapters; }
+  static int       nof_nmethods()              { return _number_of_nmethods; }
 
   // GC support
   static void gc_epilogue();
--- a/hotspot/src/share/vm/code/nmethod.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Thu Jul 08 14:29:44 2010 -0700
@@ -397,11 +397,6 @@
 //-------------end of code for ExceptionCache--------------
 
 
-void nmFlags::clear() {
-  assert(sizeof(nmFlags) == sizeof(int), "using more than one word for nmFlags");
-  *(jint*)this = 0;
-}
-
 int nmethod::total_size() const {
   return
     code_size()          +
@@ -419,8 +414,32 @@
   return NULL;
 }
 
-// %%% This variable is no longer used?
-int nmethod::_zombie_instruction_size = NativeJump::instruction_size;
+// Fill in default values for various flag fields
+void nmethod::init_defaults() {
+  _state                      = alive;
+  _marked_for_reclamation     = 0;
+  _has_flushed_dependencies   = 0;
+  _speculatively_disconnected = 0;
+  _has_unsafe_access          = 0;
+  _has_method_handle_invokes  = 0;
+  _marked_for_deoptimization  = 0;
+  _lock_count                 = 0;
+  _stack_traversal_mark       = 0;
+  _unload_reported            = false;           // jvmti state
+
+  NOT_PRODUCT(_has_debug_info = false);
+  _oops_do_mark_link       = NULL;
+  _jmethod_id              = NULL;
+  _osr_link                = NULL;
+  _scavenge_root_link      = NULL;
+  _scavenge_root_state     = 0;
+  _saved_nmethod_link      = NULL;
+  _compiler                = NULL;
+
+#ifdef HAVE_DTRACE_H
+  _trap_offset             = 0;
+#endif // def HAVE_DTRACE_H
+}
 
 
 nmethod* nmethod::new_native_nmethod(methodHandle method,
@@ -580,25 +599,16 @@
     debug_only(No_Safepoint_Verifier nsv;)
     assert_locked_or_safepoint(CodeCache_lock);
 
-    NOT_PRODUCT(_has_debug_info = false);
-    _oops_do_mark_link       = NULL;
+    init_defaults();
     _method                  = method;
     _entry_bci               = InvocationEntryBci;
-    _jmethod_id              = NULL;
-    _osr_link                = NULL;
-    _scavenge_root_link      = NULL;
-    _scavenge_root_state     = 0;
-    _saved_nmethod_link      = NULL;
-    _compiler                = NULL;
     // We have no exception handler or deopt handler make the
     // values something that will never match a pc like the nmethod vtable entry
     _exception_offset        = 0;
     _deoptimize_offset       = 0;
     _deoptimize_mh_offset    = 0;
     _orig_pc_offset          = 0;
-#ifdef HAVE_DTRACE_H
-    _trap_offset             = 0;
-#endif // def HAVE_DTRACE_H
+
     _stub_offset             = data_offset();
     _consts_offset           = data_offset();
     _oops_offset             = data_offset();
@@ -616,17 +626,9 @@
     _exception_cache         = NULL;
     _pc_desc_cache.reset_to(NULL);
 
-    flags.clear();
-    flags.state              = alive;
-    _markedForDeoptimization = 0;
-
-    _lock_count = 0;
-    _stack_traversal_mark    = 0;
-
     code_buffer->copy_oops_to(this);
     debug_only(verify_scavenge_root_oops());
     CodeCache::commit(this);
-    VTune::create_nmethod(this);
   }
 
   if (PrintNativeNMethods || PrintDebugInfo || PrintRelocations || PrintDependencies) {
@@ -674,15 +676,9 @@
     debug_only(No_Safepoint_Verifier nsv;)
     assert_locked_or_safepoint(CodeCache_lock);
 
-    NOT_PRODUCT(_has_debug_info = false);
-    _oops_do_mark_link       = NULL;
+    init_defaults();
     _method                  = method;
     _entry_bci               = InvocationEntryBci;
-    _jmethod_id              = NULL;
-    _osr_link                = NULL;
-    _scavenge_root_link      = NULL;
-    _scavenge_root_state     = 0;
-    _compiler                = NULL;
     // We have no exception handler or deopt handler make the
     // values something that will never match a pc like the nmethod vtable entry
     _exception_offset        = 0;
@@ -708,17 +704,9 @@
     _exception_cache         = NULL;
     _pc_desc_cache.reset_to(NULL);
 
-    flags.clear();
-    flags.state              = alive;
-    _markedForDeoptimization = 0;
-
-    _lock_count = 0;
-    _stack_traversal_mark    = 0;
-
     code_buffer->copy_oops_to(this);
     debug_only(verify_scavenge_root_oops());
     CodeCache::commit(this);
-    VTune::create_nmethod(this);
   }
 
   if (PrintNMethods || PrintDebugInfo || PrintRelocations || PrintDependencies) {
@@ -783,21 +771,13 @@
     debug_only(No_Safepoint_Verifier nsv;)
     assert_locked_or_safepoint(CodeCache_lock);
 
-    NOT_PRODUCT(_has_debug_info = false);
-    _oops_do_mark_link       = NULL;
+    init_defaults();
     _method                  = method;
-    _jmethod_id              = NULL;
+    _entry_bci               = entry_bci;
     _compile_id              = compile_id;
     _comp_level              = comp_level;
-    _entry_bci               = entry_bci;
-    _osr_link                = NULL;
-    _scavenge_root_link      = NULL;
-    _scavenge_root_state     = 0;
     _compiler                = compiler;
     _orig_pc_offset          = orig_pc_offset;
-#ifdef HAVE_DTRACE_H
-    _trap_offset             = 0;
-#endif // def HAVE_DTRACE_H
     _stub_offset             = instructions_offset() + code_buffer->total_offset_of(code_buffer->stubs()->start());
 
     // Exception handler and deopt handler are in the stub section
@@ -824,15 +804,6 @@
     _exception_cache         = NULL;
     _pc_desc_cache.reset_to(scopes_pcs_begin());
 
-    flags.clear();
-    flags.state              = alive;
-    _markedForDeoptimization = 0;
-
-    _unload_reported         = false;           // jvmti state
-
-    _lock_count = 0;
-    _stack_traversal_mark    = 0;
-
     // Copy contents of ScopeDescRecorder to nmethod
     code_buffer->copy_oops_to(this);
     debug_info->copy_to(this);
@@ -844,8 +815,6 @@
 
     CodeCache::commit(this);
 
-    VTune::create_nmethod(this);
-
     // Copy contents of ExceptionHandlerTable to nmethod
     handler_table->copy_to(this);
     nul_chk_table->copy_to(this);
@@ -991,11 +960,6 @@
 }
 
 
-void nmethod::set_version(int v) {
-  flags.version = v;
-}
-
-
 // Promote one word from an assembly-time handle to a live embedded oop.
 inline void nmethod::initialize_immediate_oop(oop* dest, jobject handle) {
   if (handle == NULL ||
@@ -1142,6 +1106,8 @@
 // This is a private interface with the sweeper.
 void nmethod::mark_as_seen_on_stack() {
   assert(is_not_entrant(), "must be a non-entrant method");
+  // Set the traversal mark to ensure that the sweeper does 2
+  // cleaning passes before moving to zombie.
   set_stack_traversal_mark(NMethodSweeper::traversal_count());
 }
 
@@ -1210,7 +1176,7 @@
     // for later on.
     CodeCache::set_needs_cache_clean(true);
   }
-  flags.state = unloaded;
+  _state = unloaded;
 
   // Log the unloading.
   log_state_change();
@@ -1236,21 +1202,21 @@
   if (LogCompilation) {
     if (xtty != NULL) {
       ttyLocker ttyl;  // keep the following output all in one block
-      if (flags.state == unloaded) {
+      if (_state == unloaded) {
         xtty->begin_elem("make_unloaded thread='" UINTX_FORMAT "'",
                          os::current_thread_id());
       } else {
         xtty->begin_elem("make_not_entrant thread='" UINTX_FORMAT "'%s",
                          os::current_thread_id(),
-                         (flags.state == zombie ? " zombie='1'" : ""));
+                         (_state == zombie ? " zombie='1'" : ""));
       }
       log_identity(xtty);
       xtty->stamp();
       xtty->end_elem();
     }
   }
-  if (PrintCompilation && flags.state != unloaded) {
-    print_on(tty, flags.state == zombie ? "made zombie " : "made not entrant ");
+  if (PrintCompilation && _state != unloaded) {
+    print_on(tty, _state == zombie ? "made zombie " : "made not entrant ");
     tty->cr();
   }
 }
@@ -1261,8 +1227,9 @@
 
   bool was_alive = false;
 
-  // Make sure the nmethod is not flushed in case of a safepoint in code below.
+  // Make sure neither the nmethod nor the method is flushed in case of a safepoint in code below.
   nmethodLocker nml(this);
+  methodHandle the_method(method());
 
   {
     // If the method is already zombie there is nothing to do
@@ -1282,7 +1249,7 @@
     // Enter critical section.  Does not block for safepoint.
     MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
 
-    if (flags.state == state) {
+    if (_state == state) {
       // another thread already performed this transition so nothing
       // to do, but return false to indicate this.
       return false;
@@ -1293,17 +1260,37 @@
     if (!is_osr_method() && !is_not_entrant()) {
       NativeJump::patch_verified_entry(entry_point(), verified_entry_point(),
                   SharedRuntime::get_handle_wrong_method_stub());
-      assert (NativeJump::instruction_size == nmethod::_zombie_instruction_size, "");
     }
 
-    was_alive = is_in_use(); // Read state under lock
+    if (is_in_use()) {
+      // It's a true state change, so mark the method as decompiled.
+      // Do it only for transition from alive.
+      inc_decompile_count();
+    }
 
     // Change state
-    flags.state = state;
+    _state = state;
 
     // Log the transition once
     log_state_change();
 
+    // Remove nmethod from method.
+    // We need to check if both the _code and _from_compiled_code_entry_point
+    // refer to this nmethod because there is a race in setting these two fields
+    // in methodOop as seen in bugid 4947125.
+    // If the vep() points to the zombie nmethod, the memory for the nmethod
+    // could be flushed and the compiler and vtable stubs could still call
+    // through it.
+    if (method() != NULL && (method()->code() == this ||
+                             method()->from_compiled_entry() == verified_entry_point())) {
+      HandleMark hm;
+      method()->clear_code();
+    }
+
+    if (state == not_entrant) {
+      mark_as_seen_on_stack();
+    }
+
   } // leave critical region under Patching_lock
 
   // When the nmethod becomes zombie it is no longer alive so the
@@ -1311,18 +1298,17 @@
   // state will be flushed later when the transition to zombie
   // happens or they get unloaded.
   if (state == zombie) {
+    // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event
+    // and it hasn't already been reported for this nmethod then report it now.
+    // (the event may have been reported earilier if the GC marked it for unloading).
+    post_compiled_method_unload();
+
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
     flush_dependencies(NULL);
   } else {
     assert(state == not_entrant, "other cases may need to be handled differently");
   }
 
-  if (state == not_entrant) {
-    Events::log("Make nmethod not entrant " INTPTR_FORMAT, this);
-  } else {
-    Events::log("Make nmethod zombie " INTPTR_FORMAT, this);
-  }
-
   if (TraceCreateZombies) {
     tty->print_cr("nmethod <" INTPTR_FORMAT "> code made %s", this, (state == not_entrant) ? "not entrant" : "zombie");
   }
@@ -1330,47 +1316,6 @@
   // Make sweeper aware that there is a zombie method that needs to be removed
   NMethodSweeper::notify(this);
 
-  // not_entrant only stuff
-  if (state == not_entrant) {
-    mark_as_seen_on_stack();
-  }
-
-  if (was_alive) {
-    // It's a true state change, so mark the method as decompiled.
-    // Do it only for transition from alive.
-    inc_decompile_count();
-  }
-
-  // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event
-  // and it hasn't already been reported for this nmethod then report it now.
-  // (the event may have been reported earilier if the GC marked it for unloading).
-  if (state == zombie) {
-    post_compiled_method_unload();
-  }
-
-
-  // Zombie only stuff
-  if (state == zombie) {
-    VTune::delete_nmethod(this);
-  }
-
-  // Check whether method got unloaded at a safepoint before this,
-  // if so we can skip the flushing steps below
-  if (method() == NULL) return true;
-
-  // Remove nmethod from method.
-  // We need to check if both the _code and _from_compiled_code_entry_point
-  // refer to this nmethod because there is a race in setting these two fields
-  // in methodOop as seen in bugid 4947125.
-  // If the vep() points to the zombie nmethod, the memory for the nmethod
-  // could be flushed and the compiler and vtable stubs could still call
-  // through it.
-  if (method()->code() == this ||
-      method()->from_compiled_entry() == verified_entry_point()) {
-    HandleMark hm;
-    method()->clear_code();
-  }
-
   return true;
 }
 
@@ -2109,7 +2054,6 @@
 
 void nmethod_init() {
   // make sure you didn't forget to adjust the filler fields
-  assert(sizeof(nmFlags) <= 4,           "nmFlags occupies more than a word");
   assert(sizeof(nmethod) % oopSize == 0, "nmethod size must be multiple of a word");
 }
 
@@ -2345,7 +2289,6 @@
     tty->print("((nmethod*) "INTPTR_FORMAT ") ", this);
     tty->print(" for method " INTPTR_FORMAT , (address)method());
     tty->print(" { ");
-    if (version())        tty->print("v%d ", version());
     if (is_in_use())      tty->print("in_use ");
     if (is_not_entrant()) tty->print("not_entrant ");
     if (is_zombie())      tty->print("zombie ");
--- a/hotspot/src/share/vm/code/nmethod.hpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/code/nmethod.hpp	Thu Jul 08 14:29:44 2010 -0700
@@ -78,29 +78,8 @@
 
 
 // nmethods (native methods) are the compiled code versions of Java methods.
-
-struct nmFlags {
-  friend class VMStructs;
-  unsigned int version:8;                    // version number (0 = first version)
-  unsigned int age:4;                        // age (in # of sweep steps)
-
-  unsigned int state:2;                      // {alive, zombie, unloaded)
-
-  unsigned int isUncommonRecompiled:1;       // recompiled because of uncommon trap?
-  unsigned int isToBeRecompiled:1;           // to be recompiled as soon as it matures
-  unsigned int hasFlushedDependencies:1;     // Used for maintenance of dependencies
-  unsigned int markedForReclamation:1;       // Used by NMethodSweeper
-
-  unsigned int has_unsafe_access:1;          // May fault due to unsafe access.
-  unsigned int has_method_handle_invokes:1;  // Has this method MethodHandle invokes?
-
-  unsigned int speculatively_disconnected:1; // Marked for potential unload
-
-  void clear();
-};
-
-
-// A nmethod contains:
+//
+// An nmethod contains:
 //  - header                 (the nmethod structure)
 //  [Relocation]
 //  - relocation information
@@ -131,8 +110,6 @@
   friend class CodeCache;  // non-perm oops
  private:
   // Shared fields for all nmethod's
-  static int _zombie_instruction_size;
-
   methodOop _method;
   int       _entry_bci;        // != InvocationEntryBci if this nmethod is an on-stack replacement method
   jmethodID _jmethod_id;       // Cache of method()->jmethod_id()
@@ -147,6 +124,11 @@
 
   AbstractCompiler* _compiler; // The compiler which compiled this nmethod
 
+  // offsets for entry points
+  address _entry_point;                      // entry point with class check
+  address _verified_entry_point;             // entry point without class check
+  address _osr_entry_point;                  // entry point for on stack replacement
+
   // Offsets for different nmethod parts
   int _exception_offset;
   // All deoptee's will resume execution at this location described by
@@ -175,23 +157,31 @@
   // pc during a deopt.
   int _orig_pc_offset;
 
-  int _compile_id;                     // which compilation made this nmethod
-  int _comp_level;                     // compilation level
+  int _compile_id;                           // which compilation made this nmethod
+  int _comp_level;                           // compilation level
+
+  // protected by CodeCache_lock
+  bool _has_flushed_dependencies;            // Used for maintenance of dependencies (CodeCache_lock)
+  bool _speculatively_disconnected;          // Marked for potential unload
+
+  bool _marked_for_reclamation;              // Used by NMethodSweeper (set only by sweeper)
+  bool _marked_for_deoptimization;           // Used for stack deoptimization
 
-  // offsets for entry points
-  address _entry_point;                // entry point with class check
-  address _verified_entry_point;       // entry point without class check
-  address _osr_entry_point;            // entry point for on stack replacement
+  // used by jvmti to track if an unload event has been posted for this nmethod.
+  bool _unload_reported;
 
-  nmFlags flags;           // various flags to keep track of nmethod state
-  bool _markedForDeoptimization;       // Used for stack deoptimization
+  // set during construction
+  unsigned int _has_unsafe_access:1;         // May fault due to unsafe access.
+  unsigned int _has_method_handle_invokes:1; // Has this method MethodHandle invokes?
+
+  // Protected by Patching_lock
+  unsigned char _state;                      // {alive, not_entrant, zombie, unloaded)
+
   enum { alive        = 0,
          not_entrant  = 1, // uncommon trap has happened but activations may still exist
          zombie       = 2,
          unloaded     = 3 };
 
-  // used by jvmti to track if an unload event has been posted for this nmethod.
-  bool _unload_reported;
 
   jbyte _scavenge_root_state;
 
@@ -270,15 +260,15 @@
   bool make_not_entrant_or_zombie(unsigned int state);
   void inc_decompile_count();
 
-  // used to check that writes to nmFlags are done consistently.
-  static void check_safepoint() PRODUCT_RETURN;
-
   // Used to manipulate the exception cache
   void add_exception_cache_entry(ExceptionCache* new_entry);
   ExceptionCache* exception_cache_entry_for_exception(Handle exception);
 
   // Inform external interfaces that a compiled method has been unloaded
-  inline void post_compiled_method_unload();
+  void post_compiled_method_unload();
+
+  // Initailize fields to their default values
+  void init_defaults();
 
  public:
   // create nmethod with entry_bci
@@ -393,11 +383,11 @@
   address verified_entry_point() const            { return _verified_entry_point;    } // if klass is correct
 
   // flag accessing and manipulation
-  bool  is_in_use() const                         { return flags.state == alive; }
-  bool  is_alive() const                          { return flags.state == alive || flags.state == not_entrant; }
-  bool  is_not_entrant() const                    { return flags.state == not_entrant; }
-  bool  is_zombie() const                         { return flags.state == zombie; }
-  bool  is_unloaded() const                       { return flags.state == unloaded;   }
+  bool  is_in_use() const                         { return _state == alive; }
+  bool  is_alive() const                          { return _state == alive || _state == not_entrant; }
+  bool  is_not_entrant() const                    { return _state == not_entrant; }
+  bool  is_zombie() const                         { return _state == zombie; }
+  bool  is_unloaded() const                       { return _state == unloaded;   }
 
   // Make the nmethod non entrant. The nmethod will continue to be
   // alive.  It is used when an uncommon trap happens.  Returns true
@@ -410,37 +400,33 @@
   bool  unload_reported()                         { return _unload_reported; }
   void  set_unload_reported()                     { _unload_reported = true; }
 
-  bool  is_marked_for_deoptimization() const      { return _markedForDeoptimization; }
-  void  mark_for_deoptimization()                 { _markedForDeoptimization = true; }
+  bool  is_marked_for_deoptimization() const      { return _marked_for_deoptimization; }
+  void  mark_for_deoptimization()                 { _marked_for_deoptimization = true; }
 
   void  make_unloaded(BoolObjectClosure* is_alive, oop cause);
 
   bool has_dependencies()                         { return dependencies_size() != 0; }
   void flush_dependencies(BoolObjectClosure* is_alive);
-  bool  has_flushed_dependencies()                { return flags.hasFlushedDependencies; }
-  void  set_has_flushed_dependencies()            {
+  bool has_flushed_dependencies()                 { return _has_flushed_dependencies; }
+  void set_has_flushed_dependencies()             {
     assert(!has_flushed_dependencies(), "should only happen once");
-    flags.hasFlushedDependencies = 1;
+    _has_flushed_dependencies = 1;
   }
 
-  bool  is_marked_for_reclamation() const         { return flags.markedForReclamation; }
-  void  mark_for_reclamation()                    { flags.markedForReclamation = 1; }
-  void  unmark_for_reclamation()                  { flags.markedForReclamation = 0; }
+  bool  is_marked_for_reclamation() const         { return _marked_for_reclamation; }
+  void  mark_for_reclamation()                    { _marked_for_reclamation = 1; }
+
+  bool  has_unsafe_access() const                 { return _has_unsafe_access; }
+  void  set_has_unsafe_access(bool z)             { _has_unsafe_access = z; }
 
-  bool  has_unsafe_access() const                 { return flags.has_unsafe_access; }
-  void  set_has_unsafe_access(bool z)             { flags.has_unsafe_access = z; }
+  bool  has_method_handle_invokes() const         { return _has_method_handle_invokes; }
+  void  set_has_method_handle_invokes(bool z)     { _has_method_handle_invokes = z; }
 
-  bool  has_method_handle_invokes() const         { return flags.has_method_handle_invokes; }
-  void  set_has_method_handle_invokes(bool z)     { flags.has_method_handle_invokes = z; }
-
-  bool  is_speculatively_disconnected() const     { return flags.speculatively_disconnected; }
-  void  set_speculatively_disconnected(bool z)     { flags.speculatively_disconnected = z; }
+  bool  is_speculatively_disconnected() const     { return _speculatively_disconnected; }
+  void  set_speculatively_disconnected(bool z)     { _speculatively_disconnected = z; }
 
   int   comp_level() const                        { return _comp_level; }
 
-  int   version() const                           { return flags.version; }
-  void  set_version(int v);
-
   // Support for oops in scopes and relocs:
   // Note: index 0 is reserved for null.
   oop   oop_at(int index) const                   { return index == 0 ? (oop) NULL: *oop_addr_at(index); }
--- a/hotspot/src/share/vm/code/vtableStubs.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/code/vtableStubs.cpp	Thu Jul 08 14:29:44 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,7 +50,6 @@
     }
     _chunk = blob->instructions_begin();
     _chunk_end = _chunk + bytes;
-    VTune::register_stub("vtable stub", _chunk, _chunk_end);
     Forte::register_stub("vtable stub", _chunk, _chunk_end);
     // Notify JVMTI about this stub. The event will be recorded by the enclosing
     // JvmtiDynamicCodeEventCollector and posted when this thread has released
--- a/hotspot/src/share/vm/includeDB_core	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/includeDB_core	Thu Jul 08 14:29:44 2010 -0700
@@ -964,7 +964,6 @@
 classLoader.cpp                         timer.hpp
 classLoader.cpp                         universe.inline.hpp
 classLoader.cpp                         vmSymbols.hpp
-classLoader.cpp                         vtune.hpp
 
 classLoader.hpp                         classFileParser.hpp
 classLoader.hpp                         perfData.hpp
@@ -1004,7 +1003,6 @@
 codeBlob.cpp                            safepoint.hpp
 codeBlob.cpp                            sharedRuntime.hpp
 codeBlob.cpp                            vframe.hpp
-codeBlob.cpp                            vtune.hpp
 
 codeBlob.hpp                            codeBuffer.hpp
 codeBlob.hpp                            frame.hpp
@@ -2167,7 +2165,6 @@
 interpreter.cpp                         stubRoutines.hpp
 interpreter.cpp                         templateTable.hpp
 interpreter.cpp                         timer.hpp
-interpreter.cpp                         vtune.hpp
 
 interpreter.hpp                         cppInterpreter.hpp
 interpreter.hpp                         stubs.hpp
@@ -2323,7 +2320,6 @@
 java.cpp                                vmError.hpp
 java.cpp                                vm_operations.hpp
 java.cpp                                vm_version_<arch>.hpp
-java.cpp                                vtune.hpp
 
 java.hpp                                os.hpp
 
@@ -3050,7 +3046,6 @@
 nmethod.cpp                             scopeDesc.hpp
 nmethod.cpp                             sharedRuntime.hpp
 nmethod.cpp                             sweeper.hpp
-nmethod.cpp                             vtune.hpp
 nmethod.cpp                             xmlstream.hpp
 
 nmethod.hpp                             codeBlob.hpp
@@ -3773,7 +3768,6 @@
 sharedRuntime.cpp                       vmSymbols.hpp
 sharedRuntime.cpp                       vmreg_<arch>.inline.hpp
 sharedRuntime.cpp                       vtableStubs.hpp
-sharedRuntime.cpp                       vtune.hpp
 sharedRuntime.cpp                       xmlstream.hpp
 
 sharedRuntime.hpp                       allocation.hpp
@@ -3937,7 +3931,6 @@
 stubCodeGenerator.cpp                   forte.hpp
 stubCodeGenerator.cpp                   oop.inline.hpp
 stubCodeGenerator.cpp                   stubCodeGenerator.hpp
-stubCodeGenerator.cpp                   vtune.hpp
 
 stubCodeGenerator.hpp                   allocation.hpp
 stubCodeGenerator.hpp                   assembler.hpp
@@ -4458,7 +4451,6 @@
 universe.cpp                            universe.inline.hpp
 universe.cpp                            vmSymbols.hpp
 universe.cpp                            vm_operations.hpp
-universe.cpp                            vtune.hpp
 
 universe.hpp                            growableArray.hpp
 universe.hpp                            handles.hpp
@@ -4721,7 +4713,6 @@
 vtableStubs.cpp                         resourceArea.hpp
 vtableStubs.cpp                         sharedRuntime.hpp
 vtableStubs.cpp                         vtableStubs.hpp
-vtableStubs.cpp                         vtune.hpp
 
 vtableStubs.hpp                         allocation.hpp
 
@@ -4735,11 +4726,6 @@
 vtableStubs_<arch_model>.cpp            vmreg_<arch>.inline.hpp
 vtableStubs_<arch_model>.cpp            vtableStubs.hpp
 
-vtune.hpp                               allocation.hpp
-
-vtune_<os_family>.cpp                   interpreter.hpp
-vtune_<os_family>.cpp                   vtune.hpp
-
 watermark.hpp                           allocation.hpp
 watermark.hpp                           globalDefinitions.hpp
 
--- a/hotspot/src/share/vm/interpreter/interpreter.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreter.cpp	Thu Jul 08 14:29:44 2010 -0700
@@ -99,11 +99,6 @@
 #endif // PRODUCT
   // need to hit every safepoint in order to call zapping routine
   // register the interpreter
-  VTune::register_stub(
-    "Interpreter",
-    AbstractInterpreter::code()->code_start(),
-    AbstractInterpreter::code()->code_end()
-  );
   Forte::register_stub(
     "Interpreter",
     AbstractInterpreter::code()->code_start(),
--- a/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Thu Jul 08 14:29:44 2010 -0700
@@ -2541,9 +2541,6 @@
           "Enable String cache capabilities on String.java")                \
                                                                             \
   /* statistics */                                                          \
-  develop(bool, UseVTune, false,                                            \
-          "enable support for Intel's VTune profiler")                      \
-                                                                            \
   develop(bool, CountCompiledCalls, false,                                  \
           "counts method invocations")                                      \
                                                                             \
--- a/hotspot/src/share/vm/runtime/init.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/runtime/init.cpp	Thu Jul 08 14:29:44 2010 -0700
@@ -34,7 +34,6 @@
 
 // Initialization done by Java thread in init_globals()
 void management_init();
-void vtune_init();
 void bytecodes_init();
 void classLoader_init();
 void codeCache_init();
@@ -82,7 +81,6 @@
 jint init_globals() {
   HandleMark hm;
   management_init();
-  vtune_init();
   bytecodes_init();
   classLoader_init();
   codeCache_init();
--- a/hotspot/src/share/vm/runtime/java.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/runtime/java.cpp	Thu Jul 08 14:29:44 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -432,8 +432,6 @@
   print_statistics();
   Universe::heap()->print_tracing_info();
 
-  VTune::exit();
-
   { MutexLocker ml(BeforeExit_lock);
     _before_exit_status = BEFORE_EXIT_DONE;
     BeforeExit_lock->notify_all();
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Jul 08 14:29:44 2010 -0700
@@ -2251,7 +2251,6 @@
                  B->name(),
                  fingerprint->as_string(),
                  B->instructions_begin());
-    VTune::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
     Forte::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
 
     if (JvmtiExport::should_post_dynamic_code_generated()) {
--- a/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp	Thu Jul 08 14:29:44 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -132,7 +132,6 @@
   _cdesc->set_end(_cgen->assembler()->pc());
   assert(StubCodeDesc::_list == _cdesc, "expected order on list");
   _cgen->stub_epilog(_cdesc);
-  VTune::register_stub(_cdesc->name(), _cdesc->begin(), _cdesc->end());
   Forte::register_stub(_cdesc->name(), _cdesc->begin(), _cdesc->end());
 
   if (JvmtiExport::should_post_dynamic_code_generated()) {
--- a/hotspot/src/share/vm/runtime/sweeper.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp	Thu Jul 08 14:29:44 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,14 +27,15 @@
 
 long      NMethodSweeper::_traversals = 0;   // No. of stack traversals performed
 nmethod*  NMethodSweeper::_current = NULL;   // Current nmethod
-int       NMethodSweeper::_seen = 0 ;        // No. of blobs we have currently processed in current pass of CodeCache
-int       NMethodSweeper::_invocations = 0;  // No. of invocations left until we are completed with this pass
+int       NMethodSweeper::_seen = 0 ;        // No. of nmethods we have currently processed in current pass of CodeCache
+
+volatile int NMethodSweeper::_invocations = 0;   // No. of invocations left until we are completed with this pass
+volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress.
 
 jint      NMethodSweeper::_locked_seen = 0;
 jint      NMethodSweeper::_not_entrant_seen_on_stack = 0;
 bool      NMethodSweeper::_rescan = false;
 bool      NMethodSweeper::_do_sweep = false;
-jint      NMethodSweeper::_sweep_started = 0;
 bool      NMethodSweeper::_was_full = false;
 jint      NMethodSweeper::_advise_to_sweep = 0;
 jlong     NMethodSweeper::_last_was_full = 0;
@@ -108,23 +109,14 @@
         // code cache is filling up
         _last_was_full = os::javaTimeMillis();
 
-        if (PrintMethodFlushing) {
-          tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler",
-            CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
-        }
-        if (LogCompilation && (xtty != NULL)) {
-          ttyLocker ttyl;
-          xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
-                           CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
-          xtty->stamp();
-          xtty->end_elem();
-        }
+        log_sweep("restart_compiler");
       }
     }
   }
 }
 
 void NMethodSweeper::possibly_sweep() {
+  assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode");
   if ((!MethodFlushing) || (!_do_sweep)) return;
 
   if (_invocations > 0) {
@@ -133,32 +125,31 @@
     if (old != 0) {
       return;
     }
-    sweep_code_cache();
+    if (_invocations > 0) {
+      sweep_code_cache();
+      _invocations--;
+    }
+    _sweep_started = 0;
   }
-  _sweep_started = 0;
 }
 
 void NMethodSweeper::sweep_code_cache() {
 #ifdef ASSERT
   jlong sweep_start;
-  if(PrintMethodFlushing) {
+  if (PrintMethodFlushing) {
     sweep_start = os::javaTimeMillis();
   }
 #endif
   if (PrintMethodFlushing && Verbose) {
-    tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_blobs(), _invocations);
+    tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _invocations);
   }
 
-  // We want to visit all nmethods after NmethodSweepFraction invocations.
-  // If invocation is 1 we do the rest
-  int todo = CodeCache::nof_blobs();
-  if (_invocations > 1) {
-    todo = (CodeCache::nof_blobs() - _seen) / _invocations;
-  }
-
-  // Compilers may check to sweep more often than stack scans happen,
-  // don't keep trying once it is all scanned
-  _invocations--;
+  // We want to visit all nmethods after NmethodSweepFraction
+  // invocations so divide the remaining number of nmethods by the
+  // remaining number of invocations.  This is only an estimate since
+  // the number of nmethods changes during the sweep so the final
+  // stage must iterate until it there are no more nmethods.
+  int todo = (CodeCache::nof_nmethods() - _seen) / _invocations;
 
   assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here");
   assert(!CodeCache_lock->owned_by_self(), "just checking");
@@ -166,11 +157,12 @@
   {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
 
-    for(int i = 0; i < todo && _current != NULL; i++) {
+    // The last invocation iterates until there are no more nmethods
+    for (int i = 0; (i < todo || _invocations == 1) && _current != NULL; i++) {
 
-      // Since we will give up the CodeCache_lock, always skip ahead to an nmethod.
-      // Other blobs can be deleted by other threads
-      // Read next before we potentially delete current
+      // Since we will give up the CodeCache_lock, always skip ahead
+      // to the next nmethod.  Other blobs can be deleted by other
+      // threads but nmethods are only reclaimed by the sweeper.
       nmethod* next = CodeCache::next_nmethod(_current);
 
       // Now ready to process nmethod and give up CodeCache_lock
@@ -183,6 +175,8 @@
     }
   }
 
+  assert(_invocations > 1 || _current == NULL, "must have scanned the whole cache");
+
   if (_current == NULL && !_rescan && (_locked_seen || _not_entrant_seen_on_stack)) {
     // we've completed a scan without making progress but there were
     // nmethods we were unable to process either because they were
@@ -201,6 +195,10 @@
     tty->print_cr("### sweeper:      sweep time(%d): " INT64_FORMAT, _invocations, sweep_end - sweep_start);
   }
 #endif
+
+  if (_invocations == 1) {
+    log_sweep("finished");
+  }
 }
 
 
@@ -223,7 +221,7 @@
   if (nm->is_zombie()) {
     // If it is first time, we see nmethod then we mark it. Otherwise,
     // we reclame it. When we have seen a zombie method twice, we know that
-    // there are no inline caches that referes to it.
+    // there are no inline caches that refer to it.
     if (nm->is_marked_for_reclamation()) {
       assert(!nm->is_locked_by_vm(), "must not flush locked nmethods");
       if (PrintMethodFlushing && Verbose) {
@@ -320,16 +318,8 @@
     jlong curr_interval = now - _last_was_full;
     if (curr_interval < max_interval) {
       _rescan = true;
-      if (PrintMethodFlushing) {
-        tty->print_cr("### handle full too often, turning off compiler");
-      }
-      if (LogCompilation && (xtty != NULL)) {
-        ttyLocker ttyl;
-        xtty->begin_elem("disable_compiler flushing_interval='" UINT64_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
-                         curr_interval/1000, CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
-        xtty->stamp();
-        xtty->end_elem();
-      }
+      log_sweep("disable_compiler", "flushing_interval='" UINT64_FORMAT "'",
+                           curr_interval/1000);
       return;
     }
   }
@@ -349,17 +339,7 @@
 
   if ((!was_full()) && (is_full)) {
     if (!CodeCache::needs_flushing()) {
-      if (PrintMethodFlushing) {
-        tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler",
-          CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
-      }
-      if (LogCompilation && (xtty != NULL)) {
-        ttyLocker ttyl;
-        xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
-                         CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
-        xtty->stamp();
-        xtty->end_elem();
-      }
+      log_sweep("restart_compiler");
       CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation);
       return;
     }
@@ -368,17 +348,7 @@
   // Traverse the code cache trying to dump the oldest nmethods
   uint curr_max_comp_id = CompileBroker::get_compilation_id();
   uint flush_target = ((curr_max_comp_id - _highest_marked) >> 1) + _highest_marked;
-  if (PrintMethodFlushing && Verbose) {
-    tty->print_cr("### Cleaning code cache: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes",
-        CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
-  }
-  if (LogCompilation && (xtty != NULL)) {
-    ttyLocker ttyl;
-    xtty->begin_elem("start_cleaning_code_cache live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
-                      CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
-    xtty->stamp();
-    xtty->end_elem();
-  }
+  log_sweep("start_cleaning");
 
   nmethod* nm = CodeCache::alive_nmethod(CodeCache::first());
   jint disconnected = 0;
@@ -411,13 +381,9 @@
     nm = CodeCache::alive_nmethod(CodeCache::next(nm));
   }
 
-  if (LogCompilation && (xtty != NULL)) {
-    ttyLocker ttyl;
-    xtty->begin_elem("stop_cleaning_code_cache disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
-                      disconnected, made_not_entrant, CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
-    xtty->stamp();
-    xtty->end_elem();
-  }
+  log_sweep("stop_cleaning",
+                       "disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "'",
+                       disconnected, made_not_entrant);
 
   // Shut off compiler. Sweeper will start over with a new stack scan and
   // traversal cycle and turn it back on if it clears enough space.
@@ -435,3 +401,38 @@
   }
 #endif
 }
+
+
+// Print out some state information about the current sweep and the
+// state of the code cache if it's requested.
+void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) {
+  if (PrintMethodFlushing) {
+    ttyLocker ttyl;
+    tty->print("### sweeper: %s ", msg);
+    if (format != NULL) {
+      va_list ap;
+      va_start(ap, format);
+      tty->vprint(format, ap);
+      va_end(ap);
+    }
+    tty->print_cr(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'"
+                  " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
+                  CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity());
+  }
+
+  if (LogCompilation && (xtty != NULL)) {
+    ttyLocker ttyl;
+    xtty->begin_elem("sweeper state='%s' traversals=`" INTX_FORMAT "' ", msg, (intx)traversal_count());
+    if (format != NULL) {
+      va_list ap;
+      va_start(ap, format);
+      xtty->vprint(format, ap);
+      va_end(ap);
+    }
+    xtty->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'"
+                " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
+                CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity());
+    xtty->stamp();
+    xtty->end_elem();
+  }
+}
--- a/hotspot/src/share/vm/runtime/sweeper.hpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/runtime/sweeper.hpp	Thu Jul 08 14:29:44 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,12 +31,13 @@
   static long      _traversals;   // Stack traversal count
   static nmethod*  _current;      // Current nmethod
   static int       _seen;         // Nof. nmethod we have currently processed in current pass of CodeCache
-  static int       _invocations;  // No. of invocations left until we are completed with this pass
+
+  static volatile int      _invocations;   // No. of invocations left until we are completed with this pass
+  static volatile int      _sweep_started; // Flag to control conc sweeper
 
   static bool      _rescan;          // Indicates that we should do a full rescan of the
                                      // of the code cache looking for work to do.
   static bool      _do_sweep;        // Flag to skip the conc sweep if no stack scan happened
-  static jint      _sweep_started;   // Flag to control conc sweeper
   static int       _locked_seen;     // Number of locked nmethods encountered during the scan
   static int       _not_entrant_seen_on_stack; // Number of not entrant nmethod were are still on stack
 
@@ -47,6 +48,9 @@
   static long      _was_full_traversal;   // trav number at last emergency unloading
 
   static void process_nmethod(nmethod *nm);
+
+  static void log_sweep(const char* msg, const char* format = NULL, ...);
+
  public:
   static long traversal_count() { return _traversals; }
 
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Wed Jul 07 12:40:01 2010 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Jul 08 14:29:44 2010 -0700
@@ -614,7 +614,6 @@
   /* NMethods (NOTE: incomplete, but only a little) */                                                                               \
   /**************************************************/                                                                               \
                                                                                                                                      \
-     static_field(nmethod,             _zombie_instruction_size,                      int)                                   \
   nonstatic_field(nmethod,             _method,                                       methodOop)                             \
   nonstatic_field(nmethod,             _entry_bci,                                    int)                                   \
   nonstatic_field(nmethod,             _osr_link,                                     nmethod*)                              \
--- a/hotspot/src/share/vm/runtime/vtune.hpp	Wed Jul 07 12:40:01 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-// Interface to Intel's VTune profiler.
-
-class VTune : AllStatic {
- public:
-   static void create_nmethod(nmethod* nm);      // register newly created nmethod
-   static void delete_nmethod(nmethod* nm);      // unregister nmethod before discarding it
-
-   static void register_stub(const char* name, address start, address end);
-                                                 // register internal VM stub
-   static void start_GC();                       // start/end of GC or scavenge
-   static void end_GC();
-
-   static void start_class_load();               // start/end of class loading
-   static void end_class_load();
-
-   static void exit();                           // VM exit
-};
-
-
-// helper objects
-class VTuneGCMarker : StackObj {
- public:
-   VTuneGCMarker() { VTune::start_GC(); }
-  ~VTuneGCMarker() { VTune::end_GC(); }
-};
-
-class VTuneClassLoadMarker : StackObj {
- public:
-   VTuneClassLoadMarker() { VTune::start_class_load(); }
-  ~VTuneClassLoadMarker() { VTune::end_class_load(); }
-};