diff src/share/vm/runtime/fprofiler.hpp @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children 93b6525e3b82
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/runtime/fprofiler.hpp	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,311 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+// a simple flat profiler for Java
+
+
+// Forward declaration of classes defined in this header file
+class ThreadProfiler;
+class ThreadProfilerMark;
+class FlatProfiler;
+class IntervalData;
+
+// Declarations of classes defined only in the implementation.
+class ProfilerNode;
+class FlatProfilerTask;
+
+enum TickPosition {
+  tp_code,
+  tp_native
+};
+
+// One of these guys is constructed as we enter interesting regions
+// and destructed as we exit the region.  While we are in the region
+// ticks are allotted to the region.
+class ThreadProfilerMark: public StackObj {
+public:
+  // For now, the only thread-specific region is the class loader.
+  enum Region { noRegion, classLoaderRegion, extraRegion, maxRegion };
+
+  ThreadProfilerMark(Region)  KERNEL_RETURN;
+  ~ThreadProfilerMark()       KERNEL_RETURN;
+
+private:
+  ThreadProfiler* _pp;
+  Region _r;
+};
+
+#ifndef FPROF_KERNEL
+
+class IntervalData VALUE_OBJ_CLASS_SPEC {
+  // Just to keep these things all together
+private:
+  int _interpreted;
+  int _compiled;
+  int _native;
+  int _compiling;
+public:
+  int interpreted() {
+    return _interpreted;
+  }
+  int compiled() {
+    return _compiled;
+  }
+  int native() {
+    return _native;
+  }
+  int compiling() {
+    return _compiling;
+  }
+  int total() {
+    return (interpreted() + compiled() + native() + compiling());
+  }
+  void inc_interpreted() {
+    _interpreted += 1;
+  }
+  void inc_compiled() {
+    _compiled += 1;
+  }
+  void inc_native() {
+    _native += 1;
+  }
+  void inc_compiling() {
+    _compiling += 1;
+  }
+  void reset() {
+    _interpreted = 0;
+    _compiled = 0;
+    _native = 0;
+    _compiling = 0;
+  }
+  static void print_header(outputStream* st);
+  void print_data(outputStream* st);
+};
+#endif // FPROF_KERNEL
+
+class ThreadProfiler: public CHeapObj {
+public:
+  ThreadProfiler()    KERNEL_RETURN;
+  ~ThreadProfiler()   KERNEL_RETURN;
+
+  // Resets the profiler
+  void reset()        KERNEL_RETURN;
+
+  // Activates the profiler for a certain thread
+  void engage()       KERNEL_RETURN;
+
+  // Deactivates the profiler
+  void disengage()    KERNEL_RETURN;
+
+  // Prints the collected profiling information
+  void print(const char* thread_name) KERNEL_RETURN;
+
+  // Garbage Collection Support
+  void oops_do(OopClosure* f)         KERNEL_RETURN;
+
+#ifndef FPROF_KERNEL
+private:
+  // for recording ticks.
+  friend class ProfilerNode;
+  char* area_bottom; // preallocated area for pnodes
+  char* area_top;
+  char* area_limit;
+  static int            table_size;
+  ProfilerNode** table;
+
+private:
+  void record_interpreted_tick(frame fr, TickPosition where, int* ticks);
+  void record_compiled_tick   (JavaThread* thread, frame fr, TickPosition where);
+  void interpreted_update(methodOop method, TickPosition where);
+  void compiled_update   (methodOop method, TickPosition where);
+  void stub_update       (methodOop method, const char* name, TickPosition where);
+  void adapter_update    (TickPosition where);
+
+  void runtime_stub_update(const CodeBlob* stub, const char* name, TickPosition where);
+  void unknown_compiled_update    (const CodeBlob* cb, TickPosition where);
+
+  void vm_update    (TickPosition where);
+  void vm_update    (const char* name, TickPosition where);
+
+  void record_tick_for_running_frame(JavaThread* thread, frame fr);
+  void record_tick_for_calling_frame(JavaThread* thread, frame fr);
+
+  void initialize();
+
+  static int  entry(int value);
+
+
+private:
+  friend class FlatProfiler;
+  void record_tick(JavaThread* thread);
+  bool engaged;
+  // so we can do percentages for this thread, and quick checks for activity
+  int thread_ticks;
+  int compiler_ticks;
+  int interpreter_ticks;
+
+public:
+  void inc_thread_ticks() { thread_ticks += 1; }
+
+private:
+  friend class ThreadProfilerMark;
+  // counters for thread-specific regions
+  bool region_flag[ThreadProfilerMark::maxRegion];
+  int class_loader_ticks;
+  int extra_ticks;
+
+private:
+  // other thread-specific regions
+  int blocked_ticks;
+  enum UnknownTickSites {
+      ut_null_method,
+      ut_vtable_stubs,
+      ut_running_frame,
+      ut_calling_frame,
+      ut_no_pc,
+      ut_no_last_Java_frame,
+      ut_unknown_thread_state,
+      ut_end
+  };
+  int unknown_ticks_array[ut_end];
+  int unknown_ticks() {
+    int result = 0;
+    for (int ut = 0; ut < ut_end; ut += 1) {
+      result += unknown_ticks_array[ut];
+    }
+    return result;
+  }
+
+  elapsedTimer timer;
+
+  // For interval timing
+private:
+  IntervalData _interval_data;
+  IntervalData interval_data() {
+    return _interval_data;
+  }
+  IntervalData* interval_data_ref() {
+    return &_interval_data;
+  }
+#endif // FPROF_KERNEL
+};
+
+class FlatProfiler: AllStatic {
+public:
+  static void reset() KERNEL_RETURN ;
+  static void engage(JavaThread* mainThread, bool fullProfile) KERNEL_RETURN ;
+  static void disengage() KERNEL_RETURN ;
+  static void print(int unused) KERNEL_RETURN ;
+  static bool is_active() KERNEL_RETURN_(return false;) ;
+
+  // This is NULL if each thread has its own thread profiler,
+  // else this is the single thread profiler used by all threads.
+  // In particular it makes a difference during garbage collection,
+  // where you only want to traverse each thread profiler once.
+  static ThreadProfiler* get_thread_profiler() KERNEL_RETURN_(return NULL;);
+
+  // Garbage Collection Support
+  static void oops_do(OopClosure* f) KERNEL_RETURN ;
+
+  // Support for disassembler to inspect the PCRecorder
+
+  // Returns the start address for a given pc
+  // NULL is returned if the PCRecorder is inactive
+  static address bucket_start_for(address pc) KERNEL_RETURN_(return NULL;);
+
+  enum { MillisecsPerTick = 10 };   // ms per profiling ticks
+
+  // Returns the number of ticks recorded for the bucket
+  // pc belongs to.
+  static int bucket_count_for(address pc) KERNEL_RETURN_(return 0;);
+
+#ifndef FPROF_KERNEL
+
+ private:
+  static bool full_profile() {
+    return full_profile_flag;
+  }
+
+  friend class ThreadProfiler;
+  // the following group of ticks cover everything that's not attributed to individual Java methods
+  static int  received_gc_ticks;      // ticks during which gc was active
+  static int vm_operation_ticks;      // total ticks in vm_operations other than GC
+  static int threads_lock_ticks;      // the number of times we couldn't get the Threads_lock without blocking
+  static int      blocked_ticks;      // ticks when the thread was blocked.
+  static int class_loader_ticks;      // total ticks in class loader
+  static int        extra_ticks;      // total ticks an extra temporary measuring
+  static int     compiler_ticks;      // total ticks in compilation
+  static int  interpreter_ticks;      // ticks in unknown interpreted method
+  static int        deopt_ticks;      // ticks in deoptimization
+  static int      unknown_ticks;      // ticks that cannot be categorized
+  static int     received_ticks;      // ticks that were received by task
+  static int    delivered_ticks;      // ticks that were delivered by task
+  static int non_method_ticks() {
+    return
+      ( received_gc_ticks
+      + vm_operation_ticks
+      + deopt_ticks
+      + threads_lock_ticks
+      + blocked_ticks
+      + compiler_ticks
+      + interpreter_ticks
+      + unknown_ticks );
+  }
+  static elapsedTimer timer;
+
+  // Counts of each of the byte codes
+  static int*           bytecode_ticks;
+  static int*           bytecode_ticks_stub;
+  static void print_byte_code_statistics();
+
+  // the ticks below are for continuous profiling (to adjust recompilation, etc.)
+  static int          all_ticks;      // total count of ticks received so far
+  static int      all_int_ticks;      // ticks in interpreter
+  static int     all_comp_ticks;      // ticks in compiled code (+ native)
+  static bool full_profile_flag;      // collecting full profile?
+
+  // to accumulate thread-specific data
+  // if we aren't profiling individual threads.
+  static ThreadProfiler* thread_profiler;
+  static ThreadProfiler* vm_thread_profiler;
+
+  static void allocate_table();
+
+  // The task that periodically interrupts things.
+  friend class FlatProfilerTask;
+  static FlatProfilerTask* task;
+  static void record_vm_operation();
+  static void record_vm_tick();
+  static void record_thread_ticks();
+
+  // For interval analysis
+ private:
+  static int interval_ticks_previous;  // delivered_ticks from the last interval
+  static void interval_record_thread(ThreadProfiler* tp); // extract ticks from ThreadProfiler.
+  static void interval_print();       // print interval data.
+  static void interval_reset();       // reset interval data.
+  enum {interval_print_size = 10};
+  static IntervalData* interval_data;
+#endif // FPROF_KERNEL
+};