src/os/windows/vm/vtune_windows.cpp

Wed, 01 Apr 2009 16:38:01 -0400

author
phh
date
Wed, 01 Apr 2009 16:38:01 -0400
changeset 1126
956304450e80
parent 435
a61af66fc99e
child 1907
c18cbe5936b8
permissions
-rw-r--r--

6819213: revive sun.boot.library.path
Summary: Support multiplex and mutable sun.boot.library.path
Reviewed-by: acorn, dcubed, xlu

     1 /*
     2  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 #include "incls/_precompiled.incl"
    26 #include "incls/_vtune_windows.cpp.incl"
    28 static int current_method_ID = 0;
    30 // ------------- iJITProf.h -------------------
    31 // defined by Intel -- do not change
    33 #include "windows.h"
    35 extern "C" {
    36   enum iJITP_Event {
    37     ExceptionOccurred_S,                  // Java exception
    38     ExceptionOccurred_IDS,
    40     Shutdown,                             // VM exit
    42     ThreadCreate,                         // threads
    43     ThreadDestroy,
    44     ThreadSwitch,
    46     ClassLoadStart,                       // class loading
    47     ClassLoadEnd,
    49     GCStart,                              // GC
    50     GCEnd,
    52     NMethodCreate = 13,                   // nmethod creation
    53     NMethodDelete
    55     // rest of event types omitted (call profiling not supported yet)
    56   };
    58   // version number -- 0 if VTune not installed
    59   int WINAPI iJitP_VersionNumber();
    61   enum iJITP_ModeFlags {
    62     NoNotification = 0x0,                // don't call vtune
    63     NotifyNMethodCreate   = 0x1,         // notify NMethod_Create
    64     NotifyNMethodDelete   = 0x2,         // notify NMethod_Create
    65     NotifyMethodEnter     = 0x4,         // method entry
    66     NotifyMethodExit      = 0x8,         // method exit
    67     NotifyShutdown        = 0x10,        // VM exit
    68     NotifyGC              = 0x20,        // GC
    69   };
    71   // call back function type
    72   typedef void (WINAPI *ModeChangedFn)(iJITP_ModeFlags flags);
    74   // -------------  VTune method interfaces ----------------------
    75   typedef void  (WINAPI *RegisterCallbackFn)(ModeChangedFn fn);   // register callback
    76   typedef int   (WINAPI *NotifyEventFn)(iJITP_Event, void* event_data);
    78   // specific event data structures
    80   // data for NMethodCreate
    82   struct VTuneObj {                       // base class for allocation
    83                                           // (can't use CHeapObj -- has vtable ptr)
    84     void* operator new(size_t size) { return os::malloc(size); }
    85     void  operator delete(void* p)  { fatal("never delete VTune data"); }
    86   };
    88   struct LineNumberInfo : VTuneObj {      // PC-to-line number mapping
    89     unsigned long offset;                 // byte offset from start of method
    90     unsigned long line_num;               // corresponding line number
    91   };
    93   struct MethodLoadInfo : VTuneObj {
    94     unsigned long methodID;               // unique method ID
    95     const char* name;                     // method name
    96     unsigned long instr_start;            // start address
    97     unsigned long instr_size;             // length in bytes
    98     unsigned long line_number_size;       // size of line number table
    99     LineNumberInfo* line_number_table;    // line number mapping
   100     unsigned long classID;                // unique class ID
   101     char* class_file_name;                // fully qualified class file name
   102     char* source_file_name;               // fully qualified source file name
   104     MethodLoadInfo(nmethod* nm);          // for real nmethods
   105     MethodLoadInfo(const char* vm_name, address start, address end);
   106                                           // for "nmethods" like stubs, interpreter, etc
   108   };
   110   // data for NMethodDelete
   111   struct MethodInfo : VTuneObj {
   112     unsigned long methodID;               // unique method ID
   113     unsigned long classID;                // (added for convenience -- not part of Intel interface)
   115     MethodInfo(methodOop m);
   116   };
   117 };
   119 MethodInfo::MethodInfo(methodOop m) {
   120   // just give it a new ID -- we're not compiling methods twice (usually)
   121   // (and even if we did, one might want to see the two versions separately)
   122   methodID = ++current_method_ID;
   123 }
   125 MethodLoadInfo::MethodLoadInfo(const char* vm_name, address start, address end) {
   126   classID  = 0;
   127   methodID = ++current_method_ID;
   128   name = vm_name;
   129   instr_start = (unsigned long)start;
   130   instr_size = end - start;
   131   line_number_size = 0;
   132   line_number_table = NULL;
   133   class_file_name = source_file_name = "HotSpot JVM";
   134 }
   136 MethodLoadInfo::MethodLoadInfo(nmethod* nm) {
   137   methodOop m = nm->method();
   138   MethodInfo info(m);
   139   classID  = info.classID;
   140   methodID = info.methodID;
   141   name = strdup(m->name()->as_C_string());
   142   instr_start = (unsigned long)nm->instructions_begin();
   143   instr_size = nm->code_size();
   144   line_number_size = 0;
   145   line_number_table = NULL;
   146   klassOop kl = m->method_holder();
   147   char* class_name = Klass::cast(kl)->name()->as_C_string();
   148   char* file_name = NEW_C_HEAP_ARRAY(char, strlen(class_name) + 1);
   149   strcpy(file_name, class_name);
   150   class_file_name = file_name;
   151   char* src_name = NEW_C_HEAP_ARRAY(char, strlen(class_name) + strlen(".java") + 1);
   152   strcpy(src_name, class_name);
   153   strcat(src_name, ".java");
   154   source_file_name = src_name;
   155 }
   157 // --------------------- DLL loading functions ------------------------
   159 #define DLLNAME "iJitProf.dll"
   161 static HINSTANCE load_lib(char* name) {
   162   HINSTANCE lib = NULL;
   163   HKEY hk;
   165   // try to get VTune directory from the registry
   166   if (RegOpenKey(HKEY_CURRENT_USER, "Software\\VB and VBA Program Settings\\VTune\\StartUp", &hk) == ERROR_SUCCESS) {
   167     for (int i = 0; true; i++) {
   168       char szName[MAX_PATH + 1];
   169       char szVal [MAX_PATH + 1];
   170       DWORD cbName, cbVal;
   172       cbName = cbVal = MAX_PATH + 1;
   173       if (RegEnumValue(hk, i, szName, &cbName, NULL, NULL, (LPBYTE)szVal, &cbVal) == ERROR_SUCCESS) {
   174         // get VTune directory
   175         if (!strcmp(szName, name)) {
   176           char*p = szVal;
   177           while (*p == ' ') p++;    // trim
   178           char* q = p + strlen(p) - 1;
   179           while (*q == ' ') *(q--) = '\0';
   181           // chdir to the VTune dir
   182           GetCurrentDirectory(MAX_PATH + 1, szName);
   183           SetCurrentDirectory(p);
   184           // load lib
   185           lib = LoadLibrary(strcat(strcat(p, "\\"), DLLNAME));
   186           if (lib != NULL && WizardMode) tty->print_cr("*loaded VTune DLL %s", p);
   187           // restore current dir
   188           SetCurrentDirectory(szName);
   189           break;
   190         }
   191       } else {
   192         break;
   193       }
   194     }
   195   }
   196   return lib;
   197 }
   199 static RegisterCallbackFn iJIT_RegisterCallback = NULL;
   200 static NotifyEventFn      iJIT_NotifyEvent      = NULL;
   202 static bool load_iJIT_funcs() {
   203   // first try to load from PATH
   204   HINSTANCE lib = LoadLibrary(DLLNAME);
   205   if (lib != NULL && WizardMode) tty->print_cr("*loaded VTune DLL %s via PATH", DLLNAME);
   207   // if not successful, try to look in the VTUNE directory
   208   if (lib == NULL) lib = load_lib("VTUNEDIR30");
   209   if (lib == NULL) lib = load_lib("VTUNEDIR25");
   210   if (lib == NULL) lib = load_lib("VTUNEDIR");
   212   if (lib == NULL) return false;    // unsuccessful
   214   // try to load the functions
   215   iJIT_RegisterCallback = (RegisterCallbackFn)GetProcAddress(lib, "iJIT_RegisterCallback");
   216   iJIT_NotifyEvent      = (NotifyEventFn)     GetProcAddress(lib, "iJIT_NotifyEvent");
   218   if (!iJIT_RegisterCallback) tty->print_cr("*couldn't find VTune entry point iJIT_RegisterCallback");
   219   if (!iJIT_NotifyEvent)      tty->print_cr("*couldn't find VTune entry point iJIT_NotifyEvent");
   220   return iJIT_RegisterCallback != NULL && iJIT_NotifyEvent != NULL;
   221 }
   223 // --------------------- VTune class ------------------------
   225 static bool active = false;
   226 static int  flags  = 0;
   228 void VTune::start_GC() {
   229   if (active && (flags & NotifyGC)) iJIT_NotifyEvent(GCStart, NULL);
   230 }
   232 void VTune::end_GC() {
   233   if (active && (flags & NotifyGC)) iJIT_NotifyEvent(GCEnd, NULL);
   234 }
   236 void VTune::start_class_load() {
   237   // not yet implemented in VTune
   238 }
   240 void VTune::end_class_load() {
   241   // not yet implemented in VTune
   242 }
   244 void VTune::exit() {
   245   if (active && (flags & NotifyShutdown)) iJIT_NotifyEvent(Shutdown, NULL);
   246 }
   248 void VTune::register_stub(const char* name, address start, address end) {
   249   if (flags & NotifyNMethodCreate) {
   250     MethodLoadInfo* info = new MethodLoadInfo(name, start, end);
   251     if (PrintMiscellaneous && WizardMode && Verbose) {
   252       tty->print_cr("NMethodCreate %s (%d): %#x..%#x", info->name, info->methodID,
   253                     info->instr_start, info->instr_start + info->instr_size);
   254     }
   255     iJIT_NotifyEvent(NMethodCreate, info);
   256   }
   257 }
   259 void VTune::create_nmethod(nmethod* nm) {
   260   if (flags & NotifyNMethodCreate) {
   261     MethodLoadInfo* info = new MethodLoadInfo(nm);
   262     if (PrintMiscellaneous && WizardMode && Verbose) {
   263       tty->print_cr("NMethodCreate %s (%d): %#x..%#x", info->name, info->methodID,
   264                     info->instr_start, info->instr_start + info->instr_size);
   265     }
   266     iJIT_NotifyEvent(NMethodCreate, info);
   267   }
   268 }
   270 void VTune::delete_nmethod(nmethod* nm) {
   271   if (flags & NotifyNMethodDelete) {
   272     MethodInfo* info = new MethodInfo(nm->method());
   273     iJIT_NotifyEvent(NMethodDelete, info);
   274   }
   275 }
   277 static void set_flags(int new_flags) {
   278   flags = new_flags;
   279   // if (WizardMode) tty->print_cr("*new VTune flags: %#x", flags);
   280 }
   282 void vtune_init() {
   283   if (!UseVTune) return;
   284   active = load_iJIT_funcs();
   285   if (active) {
   286     iJIT_RegisterCallback((ModeChangedFn)set_flags);
   287   } else {
   288     assert(flags == 0, "flags shouldn't be set");
   289   }
   290 }

mercurial