annotate src/share/vm/runtime/fprofiler.cpp @ 1721:413ad0331a0c

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