annotate src/share/vm/runtime/fprofiler.cpp @ 3979:4dfb2df418f2

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