hotspot/src/share/vm/runtime/fprofiler.cpp
changeset 47108 942ca8282fe5
parent 47082 9edc44958198
parent 47107 8356043b90f0
child 47110 da4f32bce2b9
equal deleted inserted replaced
47082:9edc44958198 47108:942ca8282fe5
     1 /*
       
     2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "precompiled.hpp"
       
    26 #include "classfile/classLoader.hpp"
       
    27 #include "code/codeCache.hpp"
       
    28 #include "code/vtableStubs.hpp"
       
    29 #include "gc/shared/collectedHeap.inline.hpp"
       
    30 #include "interpreter/interpreter.hpp"
       
    31 #include "memory/allocation.inline.hpp"
       
    32 #include "memory/resourceArea.hpp"
       
    33 #include "memory/universe.inline.hpp"
       
    34 #include "oops/oop.inline.hpp"
       
    35 #include "oops/symbol.hpp"
       
    36 #include "runtime/deoptimization.hpp"
       
    37 #include "runtime/fprofiler.hpp"
       
    38 #include "runtime/mutexLocker.hpp"
       
    39 #include "runtime/stubCodeGenerator.hpp"
       
    40 #include "runtime/stubRoutines.hpp"
       
    41 #include "runtime/task.hpp"
       
    42 #include "runtime/thread.inline.hpp"
       
    43 #include "runtime/vframe.hpp"
       
    44 #include "utilities/macros.hpp"
       
    45 
       
    46 // Static fields of FlatProfiler
       
    47 int               FlatProfiler::received_gc_ticks   = 0;
       
    48 int               FlatProfiler::vm_operation_ticks  = 0;
       
    49 int               FlatProfiler::threads_lock_ticks  = 0;
       
    50 int               FlatProfiler::class_loader_ticks  = 0;
       
    51 int               FlatProfiler::extra_ticks         = 0;
       
    52 int               FlatProfiler::blocked_ticks       = 0;
       
    53 int               FlatProfiler::deopt_ticks         = 0;
       
    54 int               FlatProfiler::unknown_ticks       = 0;
       
    55 int               FlatProfiler::interpreter_ticks   = 0;
       
    56 int               FlatProfiler::compiler_ticks      = 0;
       
    57 int               FlatProfiler::received_ticks      = 0;
       
    58 int               FlatProfiler::delivered_ticks     = 0;
       
    59 int*              FlatProfiler::bytecode_ticks      = NULL;
       
    60 int*              FlatProfiler::bytecode_ticks_stub = NULL;
       
    61 int               FlatProfiler::all_int_ticks       = 0;
       
    62 int               FlatProfiler::all_comp_ticks      = 0;
       
    63 int               FlatProfiler::all_ticks           = 0;
       
    64 bool              FlatProfiler::full_profile_flag   = false;
       
    65 ThreadProfiler*   FlatProfiler::thread_profiler     = NULL;
       
    66 ThreadProfiler*   FlatProfiler::vm_thread_profiler  = NULL;
       
    67 FlatProfilerTask* FlatProfiler::task                = NULL;
       
    68 elapsedTimer      FlatProfiler::timer;
       
    69 int               FlatProfiler::interval_ticks_previous = 0;
       
    70 IntervalData*     FlatProfiler::interval_data       = NULL;
       
    71 
       
    72 ThreadProfiler::ThreadProfiler() {
       
    73   // Space for the ProfilerNodes
       
    74   const int area_size = 1 * ProfilerNodeSize * 1024;
       
    75   area_bottom = AllocateHeap(area_size, mtInternal);
       
    76   area_top    = area_bottom;
       
    77   area_limit  = area_bottom + area_size;
       
    78 
       
    79   // ProfilerNode pointer table
       
    80   table = NEW_C_HEAP_ARRAY(ProfilerNode*, table_size, mtInternal);
       
    81   initialize();
       
    82   engaged = false;
       
    83 }
       
    84 
       
    85 ThreadProfiler::~ThreadProfiler() {
       
    86   FreeHeap(area_bottom);
       
    87   area_bottom = NULL;
       
    88   area_top = NULL;
       
    89   area_limit = NULL;
       
    90   FreeHeap(table);
       
    91   table = NULL;
       
    92 }
       
    93 
       
    94 // Statics for ThreadProfiler
       
    95 int ThreadProfiler::table_size = 1024;
       
    96 
       
    97 int ThreadProfiler::entry(int  value) {
       
    98   value = (value > 0) ? value : -value;
       
    99   return value % table_size;
       
   100 }
       
   101 
       
   102 ThreadProfilerMark::ThreadProfilerMark(ThreadProfilerMark::Region r) {
       
   103   _r = r;
       
   104   _pp = NULL;
       
   105   assert(((r > ThreadProfilerMark::noRegion) && (r < ThreadProfilerMark::maxRegion)), "ThreadProfilerMark::Region out of bounds");
       
   106   Thread* tp = Thread::current();
       
   107   if (tp != NULL && tp->is_Java_thread()) {
       
   108     JavaThread* jtp = (JavaThread*) tp;
       
   109     ThreadProfiler* pp = jtp->get_thread_profiler();
       
   110     _pp = pp;
       
   111     if (pp != NULL) {
       
   112       pp->region_flag[r] = true;
       
   113     }
       
   114   }
       
   115 }
       
   116 
       
   117 ThreadProfilerMark::~ThreadProfilerMark() {
       
   118   if (_pp != NULL) {
       
   119     _pp->region_flag[_r] = false;
       
   120   }
       
   121   _pp = NULL;
       
   122 }
       
   123 
       
   124 // Random other statics
       
   125 static const int col1 = 2;      // position of output column 1
       
   126 static const int col2 = 11;     // position of output column 2
       
   127 static const int col3 = 25;     // position of output column 3
       
   128 static const int col4 = 55;     // position of output column 4
       
   129 
       
   130 
       
   131 // Used for detailed profiling of nmethods.
       
   132 class PCRecorder : AllStatic {
       
   133  private:
       
   134   static int*    counters;
       
   135   static address base;
       
   136   enum {
       
   137    bucket_size = 16
       
   138   };
       
   139   static int     index_for(address pc) { return (pc - base)/bucket_size;   }
       
   140   static address pc_for(int index)     { return base + (index * bucket_size); }
       
   141   static int     size() {
       
   142     return ((int)CodeCache::max_capacity())/bucket_size * BytesPerWord;
       
   143   }
       
   144  public:
       
   145   static address bucket_start_for(address pc) {
       
   146     if (counters == NULL) return NULL;
       
   147     return pc_for(index_for(pc));
       
   148   }
       
   149   static int bucket_count_for(address pc)  { return counters[index_for(pc)]; }
       
   150   static void init();
       
   151   static void record(address pc);
       
   152   static void print();
       
   153   static void print_blobs(CodeBlob* cb);
       
   154 };
       
   155 
       
   156 int*    PCRecorder::counters = NULL;
       
   157 address PCRecorder::base     = NULL;
       
   158 
       
   159 void PCRecorder::init() {
       
   160   MutexLockerEx lm(CodeCache_lock, Mutex::_no_safepoint_check_flag);
       
   161   int s = size();
       
   162   counters = NEW_C_HEAP_ARRAY(int, s, mtInternal);
       
   163   for (int index = 0; index < s; index++) {
       
   164     counters[index] = 0;
       
   165   }
       
   166   base = CodeCache::low_bound();
       
   167 }
       
   168 
       
   169 void PCRecorder::record(address pc) {
       
   170   if (counters == NULL) return;
       
   171   assert(CodeCache::contains(pc), "must be in CodeCache");
       
   172   counters[index_for(pc)]++;
       
   173 }
       
   174 
       
   175 
       
   176 address FlatProfiler::bucket_start_for(address pc) {
       
   177   return PCRecorder::bucket_start_for(pc);
       
   178 }
       
   179 
       
   180 int FlatProfiler::bucket_count_for(address pc) {
       
   181   return PCRecorder::bucket_count_for(pc);
       
   182 }
       
   183 
       
   184 void PCRecorder::print() {
       
   185   if (counters == NULL) return;
       
   186 
       
   187   tty->cr();
       
   188   tty->print_cr("Printing compiled methods with PC buckets having more than " INTX_FORMAT " ticks", ProfilerPCTickThreshold);
       
   189   tty->print_cr("===================================================================");
       
   190   tty->cr();
       
   191 
       
   192   GrowableArray<CodeBlob*>* candidates = new GrowableArray<CodeBlob*>(20);
       
   193 
       
   194 
       
   195   int s;
       
   196   {
       
   197     MutexLockerEx lm(CodeCache_lock, Mutex::_no_safepoint_check_flag);
       
   198     s = size();
       
   199   }
       
   200 
       
   201   for (int index = 0; index < s; index++) {
       
   202     int count = counters[index];
       
   203     if (count > ProfilerPCTickThreshold) {
       
   204       address pc = pc_for(index);
       
   205       CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
       
   206       if (cb != NULL && candidates->find(cb) < 0) {
       
   207         candidates->push(cb);
       
   208       }
       
   209     }
       
   210   }
       
   211   for (int i = 0; i < candidates->length(); i++) {
       
   212     print_blobs(candidates->at(i));
       
   213   }
       
   214 }
       
   215 
       
   216 void PCRecorder::print_blobs(CodeBlob* cb) {
       
   217   if (cb != NULL) {
       
   218     cb->print();
       
   219     if (cb->is_nmethod()) {
       
   220       ((nmethod*)cb)->print_code();
       
   221     }
       
   222     tty->cr();
       
   223   } else {
       
   224     tty->print_cr("stub code");
       
   225   }
       
   226 }
       
   227 
       
   228 class tick_counter {            // holds tick info for one node
       
   229  public:
       
   230   int ticks_in_code;
       
   231   int ticks_in_native;
       
   232 
       
   233   tick_counter()                     {  ticks_in_code = ticks_in_native = 0; }
       
   234   tick_counter(int code, int native) {  ticks_in_code = code; ticks_in_native = native; }
       
   235 
       
   236   int total() const {
       
   237     return (ticks_in_code + ticks_in_native);
       
   238   }
       
   239 
       
   240   void add(tick_counter* a) {
       
   241     ticks_in_code += a->ticks_in_code;
       
   242     ticks_in_native += a->ticks_in_native;
       
   243   }
       
   244 
       
   245   void update(TickPosition where) {
       
   246     switch(where) {
       
   247       case tp_code:     ticks_in_code++;       break;
       
   248       case tp_native:   ticks_in_native++;      break;
       
   249     }
       
   250   }
       
   251 
       
   252   void print_code(outputStream* st, int total_ticks) {
       
   253     st->print("%5.1f%% %5d ", total() * 100.0 / total_ticks, ticks_in_code);
       
   254   }
       
   255 
       
   256   void print_native(outputStream* st) {
       
   257     st->print(" + %5d ", ticks_in_native);
       
   258   }
       
   259 };
       
   260 
       
   261 class ProfilerNode {
       
   262  private:
       
   263   ProfilerNode* _next;
       
   264  public:
       
   265   tick_counter ticks;
       
   266 
       
   267  public:
       
   268 
       
   269   void* operator new(size_t size, ThreadProfiler* tp) throw();
       
   270   void  operator delete(void* p);
       
   271 
       
   272   ProfilerNode() {
       
   273     _next = NULL;
       
   274   }
       
   275 
       
   276   virtual ~ProfilerNode() {
       
   277     if (_next)
       
   278       delete _next;
       
   279   }
       
   280 
       
   281   void set_next(ProfilerNode* n) { _next = n; }
       
   282   ProfilerNode* next()           { return _next; }
       
   283 
       
   284   void update(TickPosition where) { ticks.update(where);}
       
   285   int total_ticks() { return ticks.total(); }
       
   286 
       
   287   virtual bool is_interpreted() const { return false; }
       
   288   virtual bool is_compiled()    const { return false; }
       
   289   virtual bool is_stub()        const { return false; }
       
   290   virtual bool is_runtime_stub() const{ return false; }
       
   291   virtual void oops_do(OopClosure* f) = 0;
       
   292 
       
   293   virtual bool interpreted_match(Method* m) const { return false; }
       
   294   virtual bool compiled_match(Method* m ) const { return false; }
       
   295   virtual bool stub_match(Method* m, const char* name) const { return false; }
       
   296   virtual bool adapter_match() const { return false; }
       
   297   virtual bool runtimeStub_match(const CodeBlob* stub, const char* name) const { return false; }
       
   298   virtual bool unknown_compiled_match(const CodeBlob* cb) const { return false; }
       
   299 
       
   300   static void print_title(outputStream* st) {
       
   301     st->print(" + native");
       
   302     st->fill_to(col3);
       
   303     st->print("Method");
       
   304     st->fill_to(col4);
       
   305     st->cr();
       
   306   }
       
   307 
       
   308   static void print_total(outputStream* st, tick_counter* t, int total, const char* msg) {
       
   309     t->print_code(st, total);
       
   310     st->fill_to(col2);
       
   311     t->print_native(st);
       
   312     st->fill_to(col3);
       
   313     st->print("%s", msg);
       
   314     st->cr();
       
   315   }
       
   316 
       
   317   virtual Method* method()         = 0;
       
   318 
       
   319   virtual void print_method_on(outputStream* st) {
       
   320     int limit;
       
   321     int i;
       
   322     Method* m = method();
       
   323     Symbol* k = m->klass_name();
       
   324     // Print the class name with dots instead of slashes
       
   325     limit = k->utf8_length();
       
   326     for (i = 0 ; i < limit ; i += 1) {
       
   327       char c = (char) k->byte_at(i);
       
   328       if (c == '/') {
       
   329         c = '.';
       
   330       }
       
   331       st->print("%c", c);
       
   332     }
       
   333     if (limit > 0) {
       
   334       st->print(".");
       
   335     }
       
   336     Symbol* n = m->name();
       
   337     limit = n->utf8_length();
       
   338     for (i = 0 ; i < limit ; i += 1) {
       
   339       char c = (char) n->byte_at(i);
       
   340       st->print("%c", c);
       
   341     }
       
   342     if (Verbose || WizardMode) {
       
   343       // Disambiguate overloaded methods
       
   344       Symbol* sig = m->signature();
       
   345       sig->print_symbol_on(st);
       
   346     } else if (MethodHandles::is_signature_polymorphic(m->intrinsic_id()))
       
   347       // compare with Method::print_short_name
       
   348       MethodHandles::print_as_basic_type_signature_on(st, m->signature(), true);
       
   349   }
       
   350 
       
   351   virtual void print(outputStream* st, int total_ticks) {
       
   352     ticks.print_code(st, total_ticks);
       
   353     st->fill_to(col2);
       
   354     ticks.print_native(st);
       
   355     st->fill_to(col3);
       
   356     print_method_on(st);
       
   357     st->cr();
       
   358   }
       
   359 
       
   360   // for hashing into the table
       
   361   static int hash(Method* method) {
       
   362       // The point here is to try to make something fairly unique
       
   363       // out of the fields we can read without grabbing any locks
       
   364       // since the method may be locked when we need the hash.
       
   365       return (
       
   366           method->code_size() ^
       
   367           method->max_stack() ^
       
   368           method->max_locals() ^
       
   369           method->size_of_parameters());
       
   370   }
       
   371 
       
   372   // for sorting
       
   373   static int compare(ProfilerNode** a, ProfilerNode** b) {
       
   374     return (*b)->total_ticks() - (*a)->total_ticks();
       
   375   }
       
   376 };
       
   377 
       
   378 void* ProfilerNode::operator new(size_t size, ThreadProfiler* tp) throw() {
       
   379   void* result = (void*) tp->area_top;
       
   380   tp->area_top += size;
       
   381 
       
   382   if (tp->area_top > tp->area_limit) {
       
   383     fatal("flat profiler buffer overflow");
       
   384   }
       
   385   return result;
       
   386 }
       
   387 
       
   388 void ProfilerNode::operator delete(void* p){
       
   389 }
       
   390 
       
   391 class interpretedNode : public ProfilerNode {
       
   392  private:
       
   393    Method* _method;
       
   394    oop       _class_loader;  // needed to keep metadata for the method alive
       
   395  public:
       
   396    interpretedNode(Method* method, TickPosition where) : ProfilerNode() {
       
   397      _method = method;
       
   398      _class_loader = method->method_holder()->class_loader();
       
   399      update(where);
       
   400    }
       
   401 
       
   402    bool is_interpreted() const { return true; }
       
   403 
       
   404    bool interpreted_match(Method* m) const {
       
   405       return _method == m;
       
   406    }
       
   407 
       
   408    void oops_do(OopClosure* f) {
       
   409      f->do_oop(&_class_loader);
       
   410    }
       
   411 
       
   412    Method* method() { return _method; }
       
   413 
       
   414    static void print_title(outputStream* st) {
       
   415      st->fill_to(col1);
       
   416      st->print("%11s", "Interpreted");
       
   417      ProfilerNode::print_title(st);
       
   418    }
       
   419 
       
   420    void print(outputStream* st, int total_ticks) {
       
   421      ProfilerNode::print(st, total_ticks);
       
   422    }
       
   423 
       
   424    void print_method_on(outputStream* st) {
       
   425      ProfilerNode::print_method_on(st);
       
   426      MethodCounters* mcs = method()->method_counters();
       
   427      if (Verbose && mcs != NULL) mcs->invocation_counter()->print_short();
       
   428    }
       
   429 };
       
   430 
       
   431 class compiledNode : public ProfilerNode {
       
   432  private:
       
   433    Method* _method;
       
   434    oop       _class_loader;  // needed to keep metadata for the method alive
       
   435  public:
       
   436    compiledNode(Method* method, TickPosition where) : ProfilerNode() {
       
   437      _method = method;
       
   438      _class_loader = method->method_holder()->class_loader();
       
   439      update(where);
       
   440   }
       
   441   bool is_compiled()    const { return true; }
       
   442 
       
   443   bool compiled_match(Method* m) const {
       
   444     return _method == m;
       
   445   }
       
   446 
       
   447   Method* method()         { return _method; }
       
   448 
       
   449   void oops_do(OopClosure* f) {
       
   450     f->do_oop(&_class_loader);
       
   451   }
       
   452 
       
   453   static void print_title(outputStream* st) {
       
   454     st->fill_to(col1);
       
   455     st->print("%11s", "Compiled");
       
   456     ProfilerNode::print_title(st);
       
   457   }
       
   458 
       
   459   void print(outputStream* st, int total_ticks) {
       
   460     ProfilerNode::print(st, total_ticks);
       
   461   }
       
   462 
       
   463   void print_method_on(outputStream* st) {
       
   464     ProfilerNode::print_method_on(st);
       
   465   }
       
   466 };
       
   467 
       
   468 class stubNode : public ProfilerNode {
       
   469  private:
       
   470   Method* _method;
       
   471   oop       _class_loader;  // needed to keep metadata for the method alive
       
   472   const char* _symbol;   // The name of the nearest VM symbol (for +ProfileVM). Points to a unique string
       
   473  public:
       
   474    stubNode(Method* method, const char* name, TickPosition where) : ProfilerNode() {
       
   475      _method = method;
       
   476      _class_loader = method->method_holder()->class_loader();
       
   477      _symbol = name;
       
   478      update(where);
       
   479    }
       
   480 
       
   481    bool is_stub() const { return true; }
       
   482 
       
   483    void oops_do(OopClosure* f) {
       
   484      f->do_oop(&_class_loader);
       
   485    }
       
   486 
       
   487    bool stub_match(Method* m, const char* name) const {
       
   488      return (_method == m) && (_symbol == name);
       
   489    }
       
   490 
       
   491    Method* method() { return _method; }
       
   492 
       
   493    static void print_title(outputStream* st) {
       
   494      st->fill_to(col1);
       
   495      st->print("%11s", "Stub");
       
   496      ProfilerNode::print_title(st);
       
   497    }
       
   498 
       
   499    void print(outputStream* st, int total_ticks) {
       
   500      ProfilerNode::print(st, total_ticks);
       
   501    }
       
   502 
       
   503    void print_method_on(outputStream* st) {
       
   504      ProfilerNode::print_method_on(st);
       
   505      print_symbol_on(st);
       
   506    }
       
   507 
       
   508   void print_symbol_on(outputStream* st) {
       
   509     if(_symbol) {
       
   510       st->print("  (%s)", _symbol);
       
   511     }
       
   512   }
       
   513 };
       
   514 
       
   515 class adapterNode : public ProfilerNode {
       
   516  public:
       
   517    adapterNode(TickPosition where) : ProfilerNode() {
       
   518      update(where);
       
   519   }
       
   520   bool is_compiled()    const { return true; }
       
   521 
       
   522   bool adapter_match() const { return true; }
       
   523 
       
   524   Method* method()         { return NULL; }
       
   525 
       
   526   void oops_do(OopClosure* f) {
       
   527     ;
       
   528   }
       
   529 
       
   530   void print(outputStream* st, int total_ticks) {
       
   531     ProfilerNode::print(st, total_ticks);
       
   532   }
       
   533 
       
   534   void print_method_on(outputStream* st) {
       
   535     st->print("%s", "adapters");
       
   536   }
       
   537 };
       
   538 
       
   539 class runtimeStubNode : public ProfilerNode {
       
   540  private:
       
   541   const RuntimeStub* _stub;
       
   542   const char* _symbol;     // The name of the nearest VM symbol when ProfileVM is on. Points to a unique string.
       
   543  public:
       
   544    runtimeStubNode(const CodeBlob* stub, const char* name, TickPosition where) : ProfilerNode(), _stub(NULL),  _symbol(name) {
       
   545      assert(stub->is_runtime_stub(), "wrong code blob");
       
   546      _stub = (RuntimeStub*) stub;
       
   547      update(where);
       
   548    }
       
   549 
       
   550   bool is_runtime_stub() const { return true; }
       
   551 
       
   552   bool runtimeStub_match(const CodeBlob* stub, const char* name) const {
       
   553     assert(stub->is_runtime_stub(), "wrong code blob");
       
   554     return _stub->entry_point() == ((RuntimeStub*)stub)->entry_point() &&
       
   555             (_symbol == name);
       
   556   }
       
   557 
       
   558   Method* method() { return NULL; }
       
   559 
       
   560   static void print_title(outputStream* st) {
       
   561     st->fill_to(col1);
       
   562     st->print("%11s", "Runtime stub");
       
   563     ProfilerNode::print_title(st);
       
   564   }
       
   565 
       
   566   void oops_do(OopClosure* f) {
       
   567     ;
       
   568   }
       
   569 
       
   570   void print(outputStream* st, int total_ticks) {
       
   571     ProfilerNode::print(st, total_ticks);
       
   572   }
       
   573 
       
   574   void print_method_on(outputStream* st) {
       
   575     st->print("%s", _stub->name());
       
   576     print_symbol_on(st);
       
   577   }
       
   578 
       
   579   void print_symbol_on(outputStream* st) {
       
   580     if(_symbol) {
       
   581       st->print("  (%s)", _symbol);
       
   582     }
       
   583   }
       
   584 };
       
   585 
       
   586 
       
   587 class unknown_compiledNode : public ProfilerNode {
       
   588  const char *_name;
       
   589  public:
       
   590    unknown_compiledNode(const CodeBlob* cb, TickPosition where) : ProfilerNode() {
       
   591      if ( cb->is_buffer_blob() )
       
   592        _name = ((const BufferBlob*)cb)->name();
       
   593      else
       
   594        _name = ((const SingletonBlob*)cb)->name();
       
   595      update(where);
       
   596   }
       
   597   bool is_compiled()    const { return true; }
       
   598 
       
   599   bool unknown_compiled_match(const CodeBlob* cb) const {
       
   600      if ( cb->is_buffer_blob() )
       
   601        return !strcmp(((const BufferBlob*)cb)->name(), _name);
       
   602      else
       
   603        return !strcmp(((const SingletonBlob*)cb)->name(), _name);
       
   604   }
       
   605 
       
   606   Method* method()         { return NULL; }
       
   607 
       
   608   void oops_do(OopClosure* f) {
       
   609     ;
       
   610   }
       
   611 
       
   612   void print(outputStream* st, int total_ticks) {
       
   613     ProfilerNode::print(st, total_ticks);
       
   614   }
       
   615 
       
   616   void print_method_on(outputStream* st) {
       
   617     st->print("%s", _name);
       
   618   }
       
   619 };
       
   620 
       
   621 class vmNode : public ProfilerNode {
       
   622  private:
       
   623   const char* _name; // "optional" name obtained by os means such as dll lookup
       
   624  public:
       
   625   vmNode(const TickPosition where) : ProfilerNode() {
       
   626     _name = NULL;
       
   627     update(where);
       
   628   }
       
   629 
       
   630   vmNode(const char* name, const TickPosition where) : ProfilerNode() {
       
   631     _name = os::strdup(name);
       
   632     update(where);
       
   633   }
       
   634 
       
   635   ~vmNode() {
       
   636     if (_name != NULL) {
       
   637       os::free((void*)_name);
       
   638     }
       
   639   }
       
   640 
       
   641   const char *name()    const { return _name; }
       
   642   bool is_compiled()    const { return true; }
       
   643 
       
   644   bool vm_match(const char* name) const { return strcmp(name, _name) == 0; }
       
   645 
       
   646   Method* method()          { return NULL; }
       
   647 
       
   648   static int hash(const char* name){
       
   649     // Compute a simple hash
       
   650     const char* cp = name;
       
   651     int h = 0;
       
   652 
       
   653     if(name != NULL){
       
   654       while(*cp != '\0'){
       
   655         h = (h << 1) ^ *cp;
       
   656         cp++;
       
   657       }
       
   658     }
       
   659     return h;
       
   660   }
       
   661 
       
   662   void oops_do(OopClosure* f) {
       
   663     ;
       
   664   }
       
   665 
       
   666   void print(outputStream* st, int total_ticks) {
       
   667     ProfilerNode::print(st, total_ticks);
       
   668   }
       
   669 
       
   670   void print_method_on(outputStream* st) {
       
   671     if(_name==NULL){
       
   672       st->print("%s", "unknown code");
       
   673     }
       
   674     else {
       
   675       st->print("%s", _name);
       
   676     }
       
   677   }
       
   678 };
       
   679 
       
   680 void ThreadProfiler::interpreted_update(Method* method, TickPosition where) {
       
   681   int index = entry(ProfilerNode::hash(method));
       
   682   if (!table[index]) {
       
   683     table[index] = new (this) interpretedNode(method, where);
       
   684   } else {
       
   685     ProfilerNode* prev = table[index];
       
   686     for(ProfilerNode* node = prev; node; node = node->next()) {
       
   687       if (node->interpreted_match(method)) {
       
   688         node->update(where);
       
   689         return;
       
   690       }
       
   691       prev = node;
       
   692     }
       
   693     prev->set_next(new (this) interpretedNode(method, where));
       
   694   }
       
   695 }
       
   696 
       
   697 void ThreadProfiler::compiled_update(Method* method, TickPosition where) {
       
   698   int index = entry(ProfilerNode::hash(method));
       
   699   if (!table[index]) {
       
   700     table[index] = new (this) compiledNode(method, where);
       
   701   } else {
       
   702     ProfilerNode* prev = table[index];
       
   703     for(ProfilerNode* node = prev; node; node = node->next()) {
       
   704       if (node->compiled_match(method)) {
       
   705         node->update(where);
       
   706         return;
       
   707       }
       
   708       prev = node;
       
   709     }
       
   710     prev->set_next(new (this) compiledNode(method, where));
       
   711   }
       
   712 }
       
   713 
       
   714 void ThreadProfiler::stub_update(Method* method, const char* name, TickPosition where) {
       
   715   int index = entry(ProfilerNode::hash(method));
       
   716   if (!table[index]) {
       
   717     table[index] = new (this) stubNode(method, name, where);
       
   718   } else {
       
   719     ProfilerNode* prev = table[index];
       
   720     for(ProfilerNode* node = prev; node; node = node->next()) {
       
   721       if (node->stub_match(method, name)) {
       
   722         node->update(where);
       
   723         return;
       
   724       }
       
   725       prev = node;
       
   726     }
       
   727     prev->set_next(new (this) stubNode(method, name, where));
       
   728   }
       
   729 }
       
   730 
       
   731 void ThreadProfiler::adapter_update(TickPosition where) {
       
   732   int index = 0;
       
   733   if (!table[index]) {
       
   734     table[index] = new (this) adapterNode(where);
       
   735   } else {
       
   736     ProfilerNode* prev = table[index];
       
   737     for(ProfilerNode* node = prev; node; node = node->next()) {
       
   738       if (node->adapter_match()) {
       
   739         node->update(where);
       
   740         return;
       
   741       }
       
   742       prev = node;
       
   743     }
       
   744     prev->set_next(new (this) adapterNode(where));
       
   745   }
       
   746 }
       
   747 
       
   748 void ThreadProfiler::runtime_stub_update(const CodeBlob* stub, const char* name, TickPosition where) {
       
   749   int index = 0;
       
   750   if (!table[index]) {
       
   751     table[index] = new (this) runtimeStubNode(stub, name, where);
       
   752   } else {
       
   753     ProfilerNode* prev = table[index];
       
   754     for(ProfilerNode* node = prev; node; node = node->next()) {
       
   755       if (node->runtimeStub_match(stub, name)) {
       
   756         node->update(where);
       
   757         return;
       
   758       }
       
   759       prev = node;
       
   760     }
       
   761     prev->set_next(new (this) runtimeStubNode(stub, name, where));
       
   762   }
       
   763 }
       
   764 
       
   765 
       
   766 void ThreadProfiler::unknown_compiled_update(const CodeBlob* cb, TickPosition where) {
       
   767   int index = 0;
       
   768   if (!table[index]) {
       
   769     table[index] = new (this) unknown_compiledNode(cb, where);
       
   770   } else {
       
   771     ProfilerNode* prev = table[index];
       
   772     for(ProfilerNode* node = prev; node; node = node->next()) {
       
   773       if (node->unknown_compiled_match(cb)) {
       
   774         node->update(where);
       
   775         return;
       
   776       }
       
   777       prev = node;
       
   778     }
       
   779     prev->set_next(new (this) unknown_compiledNode(cb, where));
       
   780   }
       
   781 }
       
   782 
       
   783 void ThreadProfiler::vm_update(TickPosition where) {
       
   784   vm_update(NULL, where);
       
   785 }
       
   786 
       
   787 void ThreadProfiler::vm_update(const char* name, TickPosition where) {
       
   788   int index = entry(vmNode::hash(name));
       
   789   assert(index >= 0, "Must be positive");
       
   790   // Note that we call strdup below since the symbol may be resource allocated
       
   791   if (!table[index]) {
       
   792     table[index] = new (this) vmNode(name, where);
       
   793   } else {
       
   794     ProfilerNode* prev = table[index];
       
   795     for(ProfilerNode* node = prev; node; node = node->next()) {
       
   796       if (((vmNode *)node)->vm_match(name)) {
       
   797         node->update(where);
       
   798         return;
       
   799       }
       
   800       prev = node;
       
   801     }
       
   802     prev->set_next(new (this) vmNode(name, where));
       
   803   }
       
   804 }
       
   805 
       
   806 
       
   807 class FlatProfilerTask : public PeriodicTask {
       
   808 public:
       
   809   FlatProfilerTask(int interval_time) : PeriodicTask(interval_time) {}
       
   810   void task();
       
   811 };
       
   812 
       
   813 void FlatProfiler::record_vm_operation() {
       
   814   if (Universe::heap()->is_gc_active()) {
       
   815     FlatProfiler::received_gc_ticks += 1;
       
   816     return;
       
   817   }
       
   818 
       
   819   if (DeoptimizationMarker::is_active()) {
       
   820     FlatProfiler::deopt_ticks += 1;
       
   821     return;
       
   822   }
       
   823 
       
   824   FlatProfiler::vm_operation_ticks += 1;
       
   825 }
       
   826 
       
   827 void FlatProfiler::record_vm_tick() {
       
   828   // Profile the VM Thread itself if needed
       
   829   // This is done without getting the Threads_lock and we can go deep
       
   830   // inside Safepoint, etc.
       
   831   if( ProfileVM  ) {
       
   832     ResourceMark rm;
       
   833     ExtendedPC epc;
       
   834     const char *name = NULL;
       
   835     char buf[256];
       
   836     buf[0] = '\0';
       
   837 
       
   838     vm_thread_profiler->inc_thread_ticks();
       
   839 
       
   840     // Get a snapshot of a current VMThread pc (and leave it running!)
       
   841     // The call may fail in some circumstances
       
   842     epc = os::get_thread_pc(VMThread::vm_thread());
       
   843     if(epc.pc() != NULL) {
       
   844       if (os::dll_address_to_function_name(epc.pc(), buf, sizeof(buf), NULL)) {
       
   845          name = buf;
       
   846       }
       
   847     }
       
   848     if (name != NULL) {
       
   849       vm_thread_profiler->vm_update(name, tp_native);
       
   850     }
       
   851   }
       
   852 }
       
   853 
       
   854 void FlatProfiler::record_thread_ticks() {
       
   855 
       
   856   int maxthreads, suspendedthreadcount;
       
   857   JavaThread** threadsList;
       
   858   bool interval_expired = false;
       
   859 
       
   860   if (ProfileIntervals &&
       
   861       (FlatProfiler::received_ticks >= interval_ticks_previous + ProfileIntervalsTicks)) {
       
   862     interval_expired = true;
       
   863     interval_ticks_previous = FlatProfiler::received_ticks;
       
   864   }
       
   865 
       
   866   // Try not to wait for the Threads_lock
       
   867   if (Threads_lock->try_lock()) {
       
   868     {  // Threads_lock scope
       
   869       maxthreads = Threads::number_of_threads();
       
   870       threadsList = NEW_C_HEAP_ARRAY(JavaThread *, maxthreads, mtInternal);
       
   871       suspendedthreadcount = 0;
       
   872       for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) {
       
   873         if (tp->is_Compiler_thread()) {
       
   874           // Only record ticks for active compiler threads
       
   875           CompilerThread* cthread = (CompilerThread*)tp;
       
   876           if (cthread->task() != NULL) {
       
   877             // The compiler is active.  If we need to access any of the fields
       
   878             // of the compiler task we should suspend the CompilerThread first.
       
   879             FlatProfiler::compiler_ticks += 1;
       
   880             continue;
       
   881           }
       
   882         }
       
   883 
       
   884         // First externally suspend all threads by marking each for
       
   885         // external suspension - so it will stop at its next transition
       
   886         // Then do a safepoint
       
   887         ThreadProfiler* pp = tp->get_thread_profiler();
       
   888         if (pp != NULL && pp->engaged) {
       
   889           MutexLockerEx ml(tp->SR_lock(), Mutex::_no_safepoint_check_flag);
       
   890           if (!tp->is_external_suspend() && !tp->is_exiting()) {
       
   891             tp->set_external_suspend();
       
   892             threadsList[suspendedthreadcount++] = tp;
       
   893           }
       
   894         }
       
   895       }
       
   896       Threads_lock->unlock();
       
   897     }
       
   898     // Suspend each thread. This call should just return
       
   899     // for any threads that have already self-suspended
       
   900     // Net result should be one safepoint
       
   901     for (int j = 0; j < suspendedthreadcount; j++) {
       
   902       JavaThread *tp = threadsList[j];
       
   903       if (tp) {
       
   904         tp->java_suspend();
       
   905       }
       
   906     }
       
   907 
       
   908     // We are responsible for resuming any thread on this list
       
   909     for (int i = 0; i < suspendedthreadcount; i++) {
       
   910       JavaThread *tp = threadsList[i];
       
   911       if (tp) {
       
   912         ThreadProfiler* pp = tp->get_thread_profiler();
       
   913         if (pp != NULL && pp->engaged) {
       
   914           HandleMark hm;
       
   915           FlatProfiler::delivered_ticks += 1;
       
   916           if (interval_expired) {
       
   917           FlatProfiler::interval_record_thread(pp);
       
   918           }
       
   919           // This is the place where we check to see if a user thread is
       
   920           // blocked waiting for compilation.
       
   921           if (tp->blocked_on_compilation()) {
       
   922             pp->compiler_ticks += 1;
       
   923             pp->interval_data_ref()->inc_compiling();
       
   924           } else {
       
   925             pp->record_tick(tp);
       
   926           }
       
   927         }
       
   928         MutexLocker ml(Threads_lock);
       
   929         tp->java_resume();
       
   930       }
       
   931     }
       
   932     if (interval_expired) {
       
   933       FlatProfiler::interval_print();
       
   934       FlatProfiler::interval_reset();
       
   935     }
       
   936 
       
   937     FREE_C_HEAP_ARRAY(JavaThread *, threadsList);
       
   938   } else {
       
   939     // Couldn't get the threads lock, just record that rather than blocking
       
   940     FlatProfiler::threads_lock_ticks += 1;
       
   941   }
       
   942 
       
   943 }
       
   944 
       
   945 void FlatProfilerTask::task() {
       
   946   FlatProfiler::received_ticks += 1;
       
   947 
       
   948   if (ProfileVM) {
       
   949     FlatProfiler::record_vm_tick();
       
   950   }
       
   951 
       
   952   VM_Operation* op = VMThread::vm_operation();
       
   953   if (op != NULL) {
       
   954     FlatProfiler::record_vm_operation();
       
   955     if (SafepointSynchronize::is_at_safepoint()) {
       
   956       return;
       
   957     }
       
   958   }
       
   959   FlatProfiler::record_thread_ticks();
       
   960 }
       
   961 
       
   962 void ThreadProfiler::record_interpreted_tick(JavaThread* thread, frame fr, TickPosition where, int* ticks) {
       
   963   FlatProfiler::all_int_ticks++;
       
   964   if (!FlatProfiler::full_profile()) {
       
   965     return;
       
   966   }
       
   967 
       
   968   if (!fr.is_interpreted_frame_valid(thread)) {
       
   969     // tick came at a bad time
       
   970     interpreter_ticks += 1;
       
   971     FlatProfiler::interpreter_ticks += 1;
       
   972     return;
       
   973   }
       
   974 
       
   975   // The frame has been fully validated so we can trust the method and bci
       
   976 
       
   977   Method* method = *fr.interpreter_frame_method_addr();
       
   978 
       
   979   interpreted_update(method, where);
       
   980 
       
   981   // update byte code table
       
   982   InterpreterCodelet* desc = Interpreter::codelet_containing(fr.pc());
       
   983   if (desc != NULL && desc->bytecode() >= 0) {
       
   984     ticks[desc->bytecode()]++;
       
   985   }
       
   986 }
       
   987 
       
   988 void ThreadProfiler::record_compiled_tick(JavaThread* thread, frame fr, TickPosition where) {
       
   989   const char *name = NULL;
       
   990   TickPosition localwhere = where;
       
   991 
       
   992   FlatProfiler::all_comp_ticks++;
       
   993   if (!FlatProfiler::full_profile()) return;
       
   994 
       
   995   CodeBlob* cb = fr.cb();
       
   996 
       
   997   // For runtime stubs, record as native rather than as compiled
       
   998   if (cb->is_runtime_stub()) {
       
   999     RegisterMap map(thread, false);
       
  1000     fr = fr.sender(&map);
       
  1001     cb = fr.cb();
       
  1002     localwhere = tp_native;
       
  1003  }
       
  1004 
       
  1005   Method* method = cb->is_compiled() ? cb->as_compiled_method()->method() : (Method*) NULL;
       
  1006   if (method == NULL) {
       
  1007     if (cb->is_runtime_stub())
       
  1008       runtime_stub_update(cb, name, localwhere);
       
  1009     else
       
  1010       unknown_compiled_update(cb, localwhere);
       
  1011   }
       
  1012   else {
       
  1013     if (method->is_native()) {
       
  1014       stub_update(method, name, localwhere);
       
  1015     } else {
       
  1016       compiled_update(method, localwhere);
       
  1017     }
       
  1018   }
       
  1019 }
       
  1020 
       
  1021 extern "C" void find(int x);
       
  1022 
       
  1023 
       
  1024 void ThreadProfiler::record_tick_for_running_frame(JavaThread* thread, frame fr) {
       
  1025   // The tick happened in real code -> non VM code
       
  1026   if (fr.is_interpreted_frame()) {
       
  1027     interval_data_ref()->inc_interpreted();
       
  1028     record_interpreted_tick(thread, fr, tp_code, FlatProfiler::bytecode_ticks);
       
  1029     return;
       
  1030   }
       
  1031 
       
  1032   if (CodeCache::contains(fr.pc())) {
       
  1033     interval_data_ref()->inc_compiled();
       
  1034     PCRecorder::record(fr.pc());
       
  1035     record_compiled_tick(thread, fr, tp_code);
       
  1036     return;
       
  1037   }
       
  1038 
       
  1039   if (VtableStubs::stub_containing(fr.pc()) != NULL) {
       
  1040     unknown_ticks_array[ut_vtable_stubs] += 1;
       
  1041     return;
       
  1042   }
       
  1043 
       
  1044   frame caller = fr.profile_find_Java_sender_frame(thread);
       
  1045 
       
  1046   if (caller.sp() != NULL && caller.pc() != NULL) {
       
  1047     record_tick_for_calling_frame(thread, caller);
       
  1048     return;
       
  1049   }
       
  1050 
       
  1051   unknown_ticks_array[ut_running_frame] += 1;
       
  1052   FlatProfiler::unknown_ticks += 1;
       
  1053 }
       
  1054 
       
  1055 void ThreadProfiler::record_tick_for_calling_frame(JavaThread* thread, frame fr) {
       
  1056   // The tick happened in VM code
       
  1057   interval_data_ref()->inc_native();
       
  1058   if (fr.is_interpreted_frame()) {
       
  1059     record_interpreted_tick(thread, fr, tp_native, FlatProfiler::bytecode_ticks_stub);
       
  1060     return;
       
  1061   }
       
  1062   if (CodeCache::contains(fr.pc())) {
       
  1063     record_compiled_tick(thread, fr, tp_native);
       
  1064     return;
       
  1065   }
       
  1066 
       
  1067   frame caller = fr.profile_find_Java_sender_frame(thread);
       
  1068 
       
  1069   if (caller.sp() != NULL && caller.pc() != NULL) {
       
  1070     record_tick_for_calling_frame(thread, caller);
       
  1071     return;
       
  1072   }
       
  1073 
       
  1074   unknown_ticks_array[ut_calling_frame] += 1;
       
  1075   FlatProfiler::unknown_ticks += 1;
       
  1076 }
       
  1077 
       
  1078 void ThreadProfiler::record_tick(JavaThread* thread) {
       
  1079   FlatProfiler::all_ticks++;
       
  1080   thread_ticks += 1;
       
  1081 
       
  1082   // Here's another way to track global state changes.
       
  1083   // When the class loader starts it marks the ThreadProfiler to tell it it is in the class loader
       
  1084   // and we check that here.
       
  1085   // This is more direct, and more than one thread can be in the class loader at a time,
       
  1086   // but it does mean the class loader has to know about the profiler.
       
  1087   if (region_flag[ThreadProfilerMark::classLoaderRegion]) {
       
  1088     class_loader_ticks += 1;
       
  1089     FlatProfiler::class_loader_ticks += 1;
       
  1090     return;
       
  1091   } else if (region_flag[ThreadProfilerMark::extraRegion]) {
       
  1092     extra_ticks += 1;
       
  1093     FlatProfiler::extra_ticks += 1;
       
  1094     return;
       
  1095   }
       
  1096   // Note that the WatcherThread can now stop for safepoints
       
  1097   uint32_t debug_bits = 0;
       
  1098   if (!thread->wait_for_ext_suspend_completion(SuspendRetryCount,
       
  1099       SuspendRetryDelay, &debug_bits)) {
       
  1100     unknown_ticks_array[ut_unknown_thread_state] += 1;
       
  1101     FlatProfiler::unknown_ticks += 1;
       
  1102     return;
       
  1103   }
       
  1104 
       
  1105   frame fr;
       
  1106 
       
  1107   switch (thread->thread_state()) {
       
  1108   case _thread_in_native:
       
  1109   case _thread_in_native_trans:
       
  1110   case _thread_in_vm:
       
  1111   case _thread_in_vm_trans:
       
  1112     if (thread->profile_last_Java_frame(&fr)) {
       
  1113       if (fr.is_runtime_frame()) {
       
  1114         RegisterMap map(thread, false);
       
  1115         fr = fr.sender(&map);
       
  1116       }
       
  1117       record_tick_for_calling_frame(thread, fr);
       
  1118     } else {
       
  1119       unknown_ticks_array[ut_no_last_Java_frame] += 1;
       
  1120       FlatProfiler::unknown_ticks += 1;
       
  1121     }
       
  1122     break;
       
  1123   // handle_special_runtime_exit_condition self-suspends threads in Java
       
  1124   case _thread_in_Java:
       
  1125   case _thread_in_Java_trans:
       
  1126     if (thread->profile_last_Java_frame(&fr)) {
       
  1127       if (fr.is_safepoint_blob_frame()) {
       
  1128         RegisterMap map(thread, false);
       
  1129         fr = fr.sender(&map);
       
  1130       }
       
  1131       record_tick_for_running_frame(thread, fr);
       
  1132     } else {
       
  1133       unknown_ticks_array[ut_no_last_Java_frame] += 1;
       
  1134       FlatProfiler::unknown_ticks += 1;
       
  1135     }
       
  1136     break;
       
  1137   case _thread_blocked:
       
  1138   case _thread_blocked_trans:
       
  1139     if (thread->osthread() && thread->osthread()->get_state() == RUNNABLE) {
       
  1140         if (thread->profile_last_Java_frame(&fr)) {
       
  1141           if (fr.is_safepoint_blob_frame()) {
       
  1142             RegisterMap map(thread, false);
       
  1143             fr = fr.sender(&map);
       
  1144             record_tick_for_running_frame(thread, fr);
       
  1145           } else {
       
  1146             record_tick_for_calling_frame(thread, fr);
       
  1147           }
       
  1148         } else {
       
  1149           unknown_ticks_array[ut_no_last_Java_frame] += 1;
       
  1150           FlatProfiler::unknown_ticks += 1;
       
  1151         }
       
  1152     } else {
       
  1153           blocked_ticks += 1;
       
  1154           FlatProfiler::blocked_ticks += 1;
       
  1155     }
       
  1156     break;
       
  1157   case _thread_uninitialized:
       
  1158   case _thread_new:
       
  1159   // not used, included for completeness
       
  1160   case _thread_new_trans:
       
  1161      unknown_ticks_array[ut_no_last_Java_frame] += 1;
       
  1162      FlatProfiler::unknown_ticks += 1;
       
  1163      break;
       
  1164   default:
       
  1165     unknown_ticks_array[ut_unknown_thread_state] += 1;
       
  1166     FlatProfiler::unknown_ticks += 1;
       
  1167     break;
       
  1168   }
       
  1169   return;
       
  1170 }
       
  1171 
       
  1172 void ThreadProfiler::engage() {
       
  1173   engaged = true;
       
  1174   timer.start();
       
  1175 }
       
  1176 
       
  1177 void ThreadProfiler::disengage() {
       
  1178   engaged = false;
       
  1179   timer.stop();
       
  1180 }
       
  1181 
       
  1182 void ThreadProfiler::initialize() {
       
  1183   for (int index = 0; index < table_size; index++) {
       
  1184     table[index] = NULL;
       
  1185   }
       
  1186   thread_ticks = 0;
       
  1187   blocked_ticks = 0;
       
  1188   compiler_ticks = 0;
       
  1189   interpreter_ticks = 0;
       
  1190   for (int ut = 0; ut < ut_end; ut += 1) {
       
  1191     unknown_ticks_array[ut] = 0;
       
  1192   }
       
  1193   region_flag[ThreadProfilerMark::classLoaderRegion] = false;
       
  1194   class_loader_ticks = 0;
       
  1195   region_flag[ThreadProfilerMark::extraRegion] = false;
       
  1196   extra_ticks = 0;
       
  1197   timer.start();
       
  1198   interval_data_ref()->reset();
       
  1199 }
       
  1200 
       
  1201 void ThreadProfiler::reset() {
       
  1202   timer.stop();
       
  1203   if (table != NULL) {
       
  1204     for (int index = 0; index < table_size; index++) {
       
  1205       ProfilerNode* n = table[index];
       
  1206       if (n != NULL) {
       
  1207         delete n;
       
  1208       }
       
  1209     }
       
  1210   }
       
  1211   initialize();
       
  1212 }
       
  1213 
       
  1214 void FlatProfiler::allocate_table() {
       
  1215   { // Bytecode table
       
  1216     bytecode_ticks      = NEW_C_HEAP_ARRAY(int, Bytecodes::number_of_codes, mtInternal);
       
  1217     bytecode_ticks_stub = NEW_C_HEAP_ARRAY(int, Bytecodes::number_of_codes, mtInternal);
       
  1218     for(int index = 0; index < Bytecodes::number_of_codes; index++) {
       
  1219       bytecode_ticks[index]      = 0;
       
  1220       bytecode_ticks_stub[index] = 0;
       
  1221     }
       
  1222   }
       
  1223 
       
  1224   if (ProfilerRecordPC) PCRecorder::init();
       
  1225 
       
  1226   interval_data         = NEW_C_HEAP_ARRAY(IntervalData, interval_print_size, mtInternal);
       
  1227   FlatProfiler::interval_reset();
       
  1228 }
       
  1229 
       
  1230 void FlatProfiler::engage(JavaThread* mainThread, bool fullProfile) {
       
  1231   full_profile_flag = fullProfile;
       
  1232   if (bytecode_ticks == NULL) {
       
  1233     allocate_table();
       
  1234   }
       
  1235   if(ProfileVM && (vm_thread_profiler == NULL)){
       
  1236     vm_thread_profiler = new ThreadProfiler();
       
  1237   }
       
  1238   if (task == NULL) {
       
  1239     task = new FlatProfilerTask(WatcherThread::delay_interval);
       
  1240     task->enroll();
       
  1241   }
       
  1242   timer.start();
       
  1243   if (mainThread != NULL) {
       
  1244     // When mainThread was created, it might not have a ThreadProfiler
       
  1245     ThreadProfiler* pp = mainThread->get_thread_profiler();
       
  1246     if (pp == NULL) {
       
  1247       mainThread->set_thread_profiler(new ThreadProfiler());
       
  1248     } else {
       
  1249       pp->reset();
       
  1250     }
       
  1251     mainThread->get_thread_profiler()->engage();
       
  1252   }
       
  1253   // This is where we would assign thread_profiler
       
  1254   // if we wanted only one thread_profiler for all threads.
       
  1255   thread_profiler = NULL;
       
  1256 }
       
  1257 
       
  1258 void FlatProfiler::disengage() {
       
  1259   if (!task) {
       
  1260     return;
       
  1261   }
       
  1262   timer.stop();
       
  1263   task->disenroll();
       
  1264   delete task;
       
  1265   task = NULL;
       
  1266   if (thread_profiler != NULL) {
       
  1267     thread_profiler->disengage();
       
  1268   } else {
       
  1269     MutexLocker tl(Threads_lock);
       
  1270     for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) {
       
  1271       ThreadProfiler* pp = tp->get_thread_profiler();
       
  1272       if (pp != NULL) {
       
  1273         pp->disengage();
       
  1274       }
       
  1275     }
       
  1276   }
       
  1277 }
       
  1278 
       
  1279 void FlatProfiler::reset() {
       
  1280   if (task) {
       
  1281     disengage();
       
  1282   }
       
  1283 
       
  1284   class_loader_ticks = 0;
       
  1285   extra_ticks        = 0;
       
  1286   received_gc_ticks  = 0;
       
  1287   vm_operation_ticks = 0;
       
  1288   compiler_ticks     = 0;
       
  1289   deopt_ticks        = 0;
       
  1290   interpreter_ticks  = 0;
       
  1291   blocked_ticks      = 0;
       
  1292   unknown_ticks      = 0;
       
  1293   received_ticks     = 0;
       
  1294   delivered_ticks    = 0;
       
  1295   timer.stop();
       
  1296 }
       
  1297 
       
  1298 bool FlatProfiler::is_active() {
       
  1299   return task != NULL;
       
  1300 }
       
  1301 
       
  1302 void FlatProfiler::print_byte_code_statistics() {
       
  1303   GrowableArray <ProfilerNode*>* array = new GrowableArray<ProfilerNode*>(200);
       
  1304 
       
  1305   tty->print_cr(" Bytecode ticks:");
       
  1306   for (int index = 0; index < Bytecodes::number_of_codes; index++) {
       
  1307     if (FlatProfiler::bytecode_ticks[index] > 0 || FlatProfiler::bytecode_ticks_stub[index] > 0) {
       
  1308       tty->print_cr("  %4d %4d = %s",
       
  1309         FlatProfiler::bytecode_ticks[index],
       
  1310         FlatProfiler::bytecode_ticks_stub[index],
       
  1311         Bytecodes::name( (Bytecodes::Code) index));
       
  1312     }
       
  1313   }
       
  1314   tty->cr();
       
  1315 }
       
  1316 
       
  1317 void print_ticks(const char* title, int ticks, int total) {
       
  1318   if (ticks > 0) {
       
  1319     tty->print("%5.1f%% %5d", ticks * 100.0 / total, ticks);
       
  1320     tty->fill_to(col3);
       
  1321     tty->print("%s", title);
       
  1322     tty->cr();
       
  1323   }
       
  1324 }
       
  1325 
       
  1326 void ThreadProfiler::print(const char* thread_name) {
       
  1327   ResourceMark rm;
       
  1328   MutexLocker ppl(ProfilePrint_lock);
       
  1329   int index = 0; // Declared outside for loops for portability
       
  1330 
       
  1331   if (table == NULL) {
       
  1332     return;
       
  1333   }
       
  1334 
       
  1335   if (thread_ticks <= 0) {
       
  1336     return;
       
  1337   }
       
  1338 
       
  1339   const char* title = "too soon to tell";
       
  1340   double secs = timer.seconds();
       
  1341 
       
  1342   GrowableArray <ProfilerNode*>* array = new GrowableArray<ProfilerNode*>(200);
       
  1343   for(index = 0; index < table_size; index++) {
       
  1344     for(ProfilerNode* node = table[index]; node; node = node->next())
       
  1345       array->append(node);
       
  1346   }
       
  1347 
       
  1348   array->sort(&ProfilerNode::compare);
       
  1349 
       
  1350   // compute total (sanity check)
       
  1351   int active =
       
  1352     class_loader_ticks +
       
  1353     compiler_ticks +
       
  1354     interpreter_ticks +
       
  1355     unknown_ticks();
       
  1356   for (index = 0; index < array->length(); index++) {
       
  1357     active += array->at(index)->ticks.total();
       
  1358   }
       
  1359   int total = active + blocked_ticks;
       
  1360 
       
  1361   tty->cr();
       
  1362   tty->print_cr("Flat profile of %3.2f secs (%d total ticks): %s", secs, total, thread_name);
       
  1363   if (total != thread_ticks) {
       
  1364     print_ticks("Lost ticks", thread_ticks-total, thread_ticks);
       
  1365   }
       
  1366   tty->cr();
       
  1367 
       
  1368   // print interpreted methods
       
  1369   tick_counter interpreted_ticks;
       
  1370   bool has_interpreted_ticks = false;
       
  1371   int print_count = 0;
       
  1372   for (index = 0; index < array->length(); index++) {
       
  1373     ProfilerNode* n = array->at(index);
       
  1374     if (n->is_interpreted()) {
       
  1375       interpreted_ticks.add(&n->ticks);
       
  1376       if (!has_interpreted_ticks) {
       
  1377         interpretedNode::print_title(tty);
       
  1378         has_interpreted_ticks = true;
       
  1379       }
       
  1380       if (print_count++ < ProfilerNumberOfInterpretedMethods) {
       
  1381         n->print(tty, active);
       
  1382       }
       
  1383     }
       
  1384   }
       
  1385   if (has_interpreted_ticks) {
       
  1386     if (print_count <= ProfilerNumberOfInterpretedMethods) {
       
  1387       title = "Total interpreted";
       
  1388     } else {
       
  1389       title = "Total interpreted (including elided)";
       
  1390     }
       
  1391     interpretedNode::print_total(tty, &interpreted_ticks, active, title);
       
  1392     tty->cr();
       
  1393   }
       
  1394 
       
  1395   // print compiled methods
       
  1396   tick_counter compiled_ticks;
       
  1397   bool has_compiled_ticks = false;
       
  1398   print_count = 0;
       
  1399   for (index = 0; index < array->length(); index++) {
       
  1400     ProfilerNode* n = array->at(index);
       
  1401     if (n->is_compiled()) {
       
  1402       compiled_ticks.add(&n->ticks);
       
  1403       if (!has_compiled_ticks) {
       
  1404         compiledNode::print_title(tty);
       
  1405         has_compiled_ticks = true;
       
  1406       }
       
  1407       if (print_count++ < ProfilerNumberOfCompiledMethods) {
       
  1408         n->print(tty, active);
       
  1409       }
       
  1410     }
       
  1411   }
       
  1412   if (has_compiled_ticks) {
       
  1413     if (print_count <= ProfilerNumberOfCompiledMethods) {
       
  1414       title = "Total compiled";
       
  1415     } else {
       
  1416       title = "Total compiled (including elided)";
       
  1417     }
       
  1418     compiledNode::print_total(tty, &compiled_ticks, active, title);
       
  1419     tty->cr();
       
  1420   }
       
  1421 
       
  1422   // print stub methods
       
  1423   tick_counter stub_ticks;
       
  1424   bool has_stub_ticks = false;
       
  1425   print_count = 0;
       
  1426   for (index = 0; index < array->length(); index++) {
       
  1427     ProfilerNode* n = array->at(index);
       
  1428     if (n->is_stub()) {
       
  1429       stub_ticks.add(&n->ticks);
       
  1430       if (!has_stub_ticks) {
       
  1431         stubNode::print_title(tty);
       
  1432         has_stub_ticks = true;
       
  1433       }
       
  1434       if (print_count++ < ProfilerNumberOfStubMethods) {
       
  1435         n->print(tty, active);
       
  1436       }
       
  1437     }
       
  1438   }
       
  1439   if (has_stub_ticks) {
       
  1440     if (print_count <= ProfilerNumberOfStubMethods) {
       
  1441       title = "Total stub";
       
  1442     } else {
       
  1443       title = "Total stub (including elided)";
       
  1444     }
       
  1445     stubNode::print_total(tty, &stub_ticks, active, title);
       
  1446     tty->cr();
       
  1447   }
       
  1448 
       
  1449   // print runtime stubs
       
  1450   tick_counter runtime_stub_ticks;
       
  1451   bool has_runtime_stub_ticks = false;
       
  1452   print_count = 0;
       
  1453   for (index = 0; index < array->length(); index++) {
       
  1454     ProfilerNode* n = array->at(index);
       
  1455     if (n->is_runtime_stub()) {
       
  1456       runtime_stub_ticks.add(&n->ticks);
       
  1457       if (!has_runtime_stub_ticks) {
       
  1458         runtimeStubNode::print_title(tty);
       
  1459         has_runtime_stub_ticks = true;
       
  1460       }
       
  1461       if (print_count++ < ProfilerNumberOfRuntimeStubNodes) {
       
  1462         n->print(tty, active);
       
  1463       }
       
  1464     }
       
  1465   }
       
  1466   if (has_runtime_stub_ticks) {
       
  1467     if (print_count <= ProfilerNumberOfRuntimeStubNodes) {
       
  1468       title = "Total runtime stubs";
       
  1469     } else {
       
  1470       title = "Total runtime stubs (including elided)";
       
  1471     }
       
  1472     runtimeStubNode::print_total(tty, &runtime_stub_ticks, active, title);
       
  1473     tty->cr();
       
  1474   }
       
  1475 
       
  1476   if (blocked_ticks + class_loader_ticks + interpreter_ticks + compiler_ticks + unknown_ticks() != 0) {
       
  1477     tty->fill_to(col1);
       
  1478     tty->print_cr("Thread-local ticks:");
       
  1479     print_ticks("Blocked (of total)",  blocked_ticks,      total);
       
  1480     print_ticks("Class loader",        class_loader_ticks, active);
       
  1481     print_ticks("Extra",               extra_ticks,        active);
       
  1482     print_ticks("Interpreter",         interpreter_ticks,  active);
       
  1483     print_ticks("Compilation",         compiler_ticks,     active);
       
  1484     print_ticks("Unknown: vtable stubs",  unknown_ticks_array[ut_vtable_stubs],         active);
       
  1485     print_ticks("Unknown: null method",   unknown_ticks_array[ut_null_method],          active);
       
  1486     print_ticks("Unknown: running frame", unknown_ticks_array[ut_running_frame],        active);
       
  1487     print_ticks("Unknown: calling frame", unknown_ticks_array[ut_calling_frame],        active);
       
  1488     print_ticks("Unknown: no pc",         unknown_ticks_array[ut_no_pc],                active);
       
  1489     print_ticks("Unknown: no last frame", unknown_ticks_array[ut_no_last_Java_frame],   active);
       
  1490     print_ticks("Unknown: thread_state",  unknown_ticks_array[ut_unknown_thread_state], active);
       
  1491     tty->cr();
       
  1492   }
       
  1493 
       
  1494   if (WizardMode) {
       
  1495     tty->print_cr("Node area used: " INTX_FORMAT " Kb", (area_top - area_bottom) / 1024);
       
  1496   }
       
  1497   reset();
       
  1498 }
       
  1499 
       
  1500 /*
       
  1501 ThreadProfiler::print_unknown(){
       
  1502   if (table == NULL) {
       
  1503     return;
       
  1504   }
       
  1505 
       
  1506   if (thread_ticks <= 0) {
       
  1507     return;
       
  1508   }
       
  1509 } */
       
  1510 
       
  1511 void FlatProfiler::print(int unused) {
       
  1512   ResourceMark rm;
       
  1513   if (thread_profiler != NULL) {
       
  1514     thread_profiler->print("All threads");
       
  1515   } else {
       
  1516     MutexLocker tl(Threads_lock);
       
  1517     for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) {
       
  1518       ThreadProfiler* pp = tp->get_thread_profiler();
       
  1519       if (pp != NULL) {
       
  1520         pp->print(tp->get_thread_name());
       
  1521       }
       
  1522     }
       
  1523   }
       
  1524 
       
  1525   if (ProfilerPrintByteCodeStatistics) {
       
  1526     print_byte_code_statistics();
       
  1527   }
       
  1528 
       
  1529   if (non_method_ticks() > 0) {
       
  1530     tty->cr();
       
  1531     tty->print_cr("Global summary of %3.2f seconds:", timer.seconds());
       
  1532     print_ticks("Received ticks",      received_ticks,     received_ticks);
       
  1533     print_ticks("Received GC ticks",   received_gc_ticks,  received_ticks);
       
  1534     print_ticks("Compilation",         compiler_ticks,     received_ticks);
       
  1535     print_ticks("Deoptimization",      deopt_ticks,        received_ticks);
       
  1536     print_ticks("Other VM operations", vm_operation_ticks, received_ticks);
       
  1537 #ifndef PRODUCT
       
  1538     print_ticks("Blocked ticks",       blocked_ticks,      received_ticks);
       
  1539     print_ticks("Threads_lock blocks", threads_lock_ticks, received_ticks);
       
  1540     print_ticks("Delivered ticks",     delivered_ticks,    received_ticks);
       
  1541     print_ticks("All ticks",           all_ticks,          received_ticks);
       
  1542 #endif
       
  1543     print_ticks("Class loader",        class_loader_ticks, received_ticks);
       
  1544     print_ticks("Extra       ",        extra_ticks,        received_ticks);
       
  1545     print_ticks("Interpreter",         interpreter_ticks,  received_ticks);
       
  1546     print_ticks("Unknown code",        unknown_ticks,      received_ticks);
       
  1547   }
       
  1548 
       
  1549   PCRecorder::print();
       
  1550 
       
  1551   if(ProfileVM){
       
  1552     tty->cr();
       
  1553     vm_thread_profiler->print("VM Thread");
       
  1554   }
       
  1555 }
       
  1556 
       
  1557 void IntervalData::print_header(outputStream* st) {
       
  1558   st->print("i/c/n/g");
       
  1559 }
       
  1560 
       
  1561 void IntervalData::print_data(outputStream* st) {
       
  1562   st->print("%d/%d/%d/%d", interpreted(), compiled(), native(), compiling());
       
  1563 }
       
  1564 
       
  1565 void FlatProfiler::interval_record_thread(ThreadProfiler* tp) {
       
  1566   IntervalData id = tp->interval_data();
       
  1567   int total = id.total();
       
  1568   tp->interval_data_ref()->reset();
       
  1569 
       
  1570   // Insertion sort the data, if it's relevant.
       
  1571   for (int i = 0; i < interval_print_size; i += 1) {
       
  1572     if (total > interval_data[i].total()) {
       
  1573       for (int j = interval_print_size - 1; j > i; j -= 1) {
       
  1574         interval_data[j] = interval_data[j-1];
       
  1575       }
       
  1576       interval_data[i] = id;
       
  1577       break;
       
  1578     }
       
  1579   }
       
  1580 }
       
  1581 
       
  1582 void FlatProfiler::interval_print() {
       
  1583   if ((interval_data[0].total() > 0)) {
       
  1584     tty->stamp();
       
  1585     tty->print("\t");
       
  1586     IntervalData::print_header(tty);
       
  1587     for (int i = 0; i < interval_print_size; i += 1) {
       
  1588       if (interval_data[i].total() > 0) {
       
  1589         tty->print("\t");
       
  1590         interval_data[i].print_data(tty);
       
  1591       }
       
  1592     }
       
  1593     tty->cr();
       
  1594   }
       
  1595 }
       
  1596 
       
  1597 void FlatProfiler::interval_reset() {
       
  1598   for (int i = 0; i < interval_print_size; i += 1) {
       
  1599     interval_data[i].reset();
       
  1600   }
       
  1601 }
       
  1602 
       
  1603 void ThreadProfiler::oops_do(OopClosure* f) {
       
  1604   if (table == NULL) return;
       
  1605 
       
  1606   for(int index = 0; index < table_size; index++) {
       
  1607     for(ProfilerNode* node = table[index]; node; node = node->next())
       
  1608       node->oops_do(f);
       
  1609   }
       
  1610 }
       
  1611 
       
  1612 void FlatProfiler::oops_do(OopClosure* f) {
       
  1613   if (thread_profiler != NULL) {
       
  1614     thread_profiler->oops_do(f);
       
  1615   } else {
       
  1616     for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) {
       
  1617       ThreadProfiler* pp = tp->get_thread_profiler();
       
  1618       if (pp != NULL) {
       
  1619         pp->oops_do(f);
       
  1620       }
       
  1621     }
       
  1622   }
       
  1623 }