hotspot/src/share/vm/runtime/fprofiler.hpp
changeset 47213 57173ad5c534
parent 47212 000f4e4ddd39
parent 47211 75e8600f1136
child 47214 22850b3a5524
equal deleted inserted replaced
47212:000f4e4ddd39 47213:57173ad5c534
     1 /*
       
     2  * Copyright (c) 1997, 2013, 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 #ifndef SHARE_VM_RUNTIME_FPROFILER_HPP
       
    26 #define SHARE_VM_RUNTIME_FPROFILER_HPP
       
    27 
       
    28 #include "utilities/macros.hpp"
       
    29 #include "runtime/timer.hpp"
       
    30 
       
    31 // a simple flat profiler for Java
       
    32 
       
    33 
       
    34 // Forward declaration of classes defined in this header file
       
    35 class ThreadProfiler;
       
    36 class ThreadProfilerMark;
       
    37 class FlatProfiler;
       
    38 class IntervalData;
       
    39 
       
    40 // Declarations of classes defined only in the implementation.
       
    41 class ProfilerNode;
       
    42 class FlatProfilerTask;
       
    43 
       
    44 enum TickPosition {
       
    45   tp_code,
       
    46   tp_native
       
    47 };
       
    48 
       
    49 // One of these guys is constructed as we enter interesting regions
       
    50 // and destructed as we exit the region.  While we are in the region
       
    51 // ticks are allotted to the region.
       
    52 class ThreadProfilerMark: public StackObj {
       
    53 public:
       
    54   // For now, the only thread-specific region is the class loader.
       
    55   enum Region { noRegion, classLoaderRegion, extraRegion, maxRegion };
       
    56 
       
    57   ThreadProfilerMark(Region)  NOT_FPROF_RETURN;
       
    58   ~ThreadProfilerMark()       NOT_FPROF_RETURN;
       
    59 
       
    60 private:
       
    61   ThreadProfiler* _pp;
       
    62   Region _r;
       
    63 };
       
    64 
       
    65 #if INCLUDE_FPROF
       
    66 
       
    67 class IntervalData VALUE_OBJ_CLASS_SPEC {
       
    68   // Just to keep these things all together
       
    69 private:
       
    70   int _interpreted;
       
    71   int _compiled;
       
    72   int _native;
       
    73   int _compiling;
       
    74 public:
       
    75   int interpreted() {
       
    76     return _interpreted;
       
    77   }
       
    78   int compiled() {
       
    79     return _compiled;
       
    80   }
       
    81   int native() {
       
    82     return _native;
       
    83   }
       
    84   int compiling() {
       
    85     return _compiling;
       
    86   }
       
    87   int total() {
       
    88     return (interpreted() + compiled() + native() + compiling());
       
    89   }
       
    90   void inc_interpreted() {
       
    91     _interpreted += 1;
       
    92   }
       
    93   void inc_compiled() {
       
    94     _compiled += 1;
       
    95   }
       
    96   void inc_native() {
       
    97     _native += 1;
       
    98   }
       
    99   void inc_compiling() {
       
   100     _compiling += 1;
       
   101   }
       
   102   void reset() {
       
   103     _interpreted = 0;
       
   104     _compiled = 0;
       
   105     _native = 0;
       
   106     _compiling = 0;
       
   107   }
       
   108   static void print_header(outputStream* st);
       
   109   void print_data(outputStream* st);
       
   110 };
       
   111 #endif // INCLUDE_FPROF
       
   112 
       
   113 class ThreadProfiler: public CHeapObj<mtInternal> {
       
   114 public:
       
   115   ThreadProfiler()    NOT_FPROF_RETURN;
       
   116   ~ThreadProfiler()   NOT_FPROF_RETURN;
       
   117 
       
   118   // Resets the profiler
       
   119   void reset()        NOT_FPROF_RETURN;
       
   120 
       
   121   // Activates the profiler for a certain thread
       
   122   void engage()       NOT_FPROF_RETURN;
       
   123 
       
   124   // Deactivates the profiler
       
   125   void disengage()    NOT_FPROF_RETURN;
       
   126 
       
   127   // Prints the collected profiling information
       
   128   void print(const char* thread_name) NOT_FPROF_RETURN;
       
   129 
       
   130   // Garbage Collection Support
       
   131   void oops_do(OopClosure* f)         NOT_FPROF_RETURN;
       
   132 
       
   133 #if INCLUDE_FPROF
       
   134 private:
       
   135   // for recording ticks.
       
   136   friend class ProfilerNode;
       
   137   char* area_bottom; // preallocated area for pnodes
       
   138   char* area_top;
       
   139   char* area_limit;
       
   140   static int            table_size;
       
   141   ProfilerNode** table;
       
   142 
       
   143 private:
       
   144   void record_interpreted_tick(JavaThread* thread, frame fr, TickPosition where, int* ticks);
       
   145   void record_compiled_tick   (JavaThread* thread, frame fr, TickPosition where);
       
   146   void interpreted_update(Method* method, TickPosition where);
       
   147   void compiled_update   (Method* method, TickPosition where);
       
   148   void stub_update       (Method* method, const char* name, TickPosition where);
       
   149   void adapter_update    (TickPosition where);
       
   150 
       
   151   void runtime_stub_update(const CodeBlob* stub, const char* name, TickPosition where);
       
   152   void unknown_compiled_update    (const CodeBlob* cb, TickPosition where);
       
   153 
       
   154   void vm_update    (TickPosition where);
       
   155   void vm_update    (const char* name, TickPosition where);
       
   156 
       
   157   void record_tick_for_running_frame(JavaThread* thread, frame fr);
       
   158   void record_tick_for_calling_frame(JavaThread* thread, frame fr);
       
   159 
       
   160   void initialize();
       
   161 
       
   162   static int  entry(int value);
       
   163 
       
   164 
       
   165 private:
       
   166   friend class FlatProfiler;
       
   167   void record_tick(JavaThread* thread);
       
   168   bool engaged;
       
   169   // so we can do percentages for this thread, and quick checks for activity
       
   170   int thread_ticks;
       
   171   int compiler_ticks;
       
   172   int interpreter_ticks;
       
   173 
       
   174 public:
       
   175   void inc_thread_ticks() { thread_ticks += 1; }
       
   176 
       
   177 private:
       
   178   friend class ThreadProfilerMark;
       
   179   // counters for thread-specific regions
       
   180   bool region_flag[ThreadProfilerMark::maxRegion];
       
   181   int class_loader_ticks;
       
   182   int extra_ticks;
       
   183 
       
   184 private:
       
   185   // other thread-specific regions
       
   186   int blocked_ticks;
       
   187   enum UnknownTickSites {
       
   188       ut_null_method,
       
   189       ut_vtable_stubs,
       
   190       ut_running_frame,
       
   191       ut_calling_frame,
       
   192       ut_no_pc,
       
   193       ut_no_last_Java_frame,
       
   194       ut_unknown_thread_state,
       
   195       ut_end
       
   196   };
       
   197   int unknown_ticks_array[ut_end];
       
   198   int unknown_ticks() {
       
   199     int result = 0;
       
   200     for (int ut = 0; ut < ut_end; ut += 1) {
       
   201       result += unknown_ticks_array[ut];
       
   202     }
       
   203     return result;
       
   204   }
       
   205 
       
   206   elapsedTimer timer;
       
   207 
       
   208   // For interval timing
       
   209 private:
       
   210   IntervalData _interval_data;
       
   211   IntervalData interval_data() {
       
   212     return _interval_data;
       
   213   }
       
   214   IntervalData* interval_data_ref() {
       
   215     return &_interval_data;
       
   216   }
       
   217 #endif // INCLUDE_FPROF
       
   218 };
       
   219 
       
   220 class FlatProfiler: AllStatic {
       
   221 public:
       
   222   static void reset() NOT_FPROF_RETURN ;
       
   223   static void engage(JavaThread* mainThread, bool fullProfile) NOT_FPROF_RETURN ;
       
   224   static void disengage() NOT_FPROF_RETURN ;
       
   225   static void print(int unused) NOT_FPROF_RETURN ;
       
   226   static bool is_active() NOT_FPROF_RETURN_(false) ;
       
   227 
       
   228   // This is NULL if each thread has its own thread profiler,
       
   229   // else this is the single thread profiler used by all threads.
       
   230   // In particular it makes a difference during garbage collection,
       
   231   // where you only want to traverse each thread profiler once.
       
   232   static ThreadProfiler* get_thread_profiler() NOT_FPROF_RETURN_(NULL);
       
   233 
       
   234   // Garbage Collection Support
       
   235   static void oops_do(OopClosure* f) NOT_FPROF_RETURN ;
       
   236 
       
   237   // Support for disassembler to inspect the PCRecorder
       
   238 
       
   239   // Returns the start address for a given pc
       
   240   // NULL is returned if the PCRecorder is inactive
       
   241   static address bucket_start_for(address pc) NOT_FPROF_RETURN_(NULL);
       
   242 
       
   243   enum { MillisecsPerTick = 10 };   // ms per profiling ticks
       
   244 
       
   245   // Returns the number of ticks recorded for the bucket
       
   246   // pc belongs to.
       
   247   static int bucket_count_for(address pc) NOT_FPROF_RETURN_(0);
       
   248 
       
   249 #if INCLUDE_FPROF
       
   250 
       
   251  private:
       
   252   static bool full_profile() {
       
   253     return full_profile_flag;
       
   254   }
       
   255 
       
   256   friend class ThreadProfiler;
       
   257   // the following group of ticks cover everything that's not attributed to individual Java methods
       
   258   static int  received_gc_ticks;      // ticks during which gc was active
       
   259   static int vm_operation_ticks;      // total ticks in vm_operations other than GC
       
   260   static int threads_lock_ticks;      // the number of times we couldn't get the Threads_lock without blocking
       
   261   static int      blocked_ticks;      // ticks when the thread was blocked.
       
   262   static int class_loader_ticks;      // total ticks in class loader
       
   263   static int        extra_ticks;      // total ticks an extra temporary measuring
       
   264   static int     compiler_ticks;      // total ticks in compilation
       
   265   static int  interpreter_ticks;      // ticks in unknown interpreted method
       
   266   static int        deopt_ticks;      // ticks in deoptimization
       
   267   static int      unknown_ticks;      // ticks that cannot be categorized
       
   268   static int     received_ticks;      // ticks that were received by task
       
   269   static int    delivered_ticks;      // ticks that were delivered by task
       
   270   static int non_method_ticks() {
       
   271     return
       
   272       ( received_gc_ticks
       
   273       + vm_operation_ticks
       
   274       + deopt_ticks
       
   275       + threads_lock_ticks
       
   276       + blocked_ticks
       
   277       + compiler_ticks
       
   278       + interpreter_ticks
       
   279       + unknown_ticks );
       
   280   }
       
   281   static elapsedTimer timer;
       
   282 
       
   283   // Counts of each of the byte codes
       
   284   static int*           bytecode_ticks;
       
   285   static int*           bytecode_ticks_stub;
       
   286   static void print_byte_code_statistics();
       
   287 
       
   288   // the ticks below are for continuous profiling (to adjust recompilation, etc.)
       
   289   static int          all_ticks;      // total count of ticks received so far
       
   290   static int      all_int_ticks;      // ticks in interpreter
       
   291   static int     all_comp_ticks;      // ticks in compiled code (+ native)
       
   292   static bool full_profile_flag;      // collecting full profile?
       
   293 
       
   294   // to accumulate thread-specific data
       
   295   // if we aren't profiling individual threads.
       
   296   static ThreadProfiler* thread_profiler;
       
   297   static ThreadProfiler* vm_thread_profiler;
       
   298 
       
   299   static void allocate_table();
       
   300 
       
   301   // The task that periodically interrupts things.
       
   302   friend class FlatProfilerTask;
       
   303   static FlatProfilerTask* task;
       
   304   static void record_vm_operation();
       
   305   static void record_vm_tick();
       
   306   static void record_thread_ticks();
       
   307 
       
   308   // For interval analysis
       
   309  private:
       
   310   static int interval_ticks_previous;  // delivered_ticks from the last interval
       
   311   static void interval_record_thread(ThreadProfiler* tp); // extract ticks from ThreadProfiler.
       
   312   static void interval_print();       // print interval data.
       
   313   static void interval_reset();       // reset interval data.
       
   314   enum {interval_print_size = 10};
       
   315   static IntervalData* interval_data;
       
   316 #endif // INCLUDE_FPROF
       
   317 };
       
   318 
       
   319 #endif // SHARE_VM_RUNTIME_FPROFILER_HPP