Mercurial > hg > truffle
annotate src/share/vm/compiler/compileLog.cpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | 9191895df19d |
children | c3e799c37717 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
2 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
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:
1489
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "ci/ciMethod.hpp" | |
27 #include "compiler/compileLog.hpp" | |
28 #include "memory/allocation.inline.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
29 #include "oops/method.hpp" |
1972 | 30 #include "runtime/mutexLocker.hpp" |
31 #include "runtime/os.hpp" | |
0 | 32 |
33 CompileLog* CompileLog::_first = NULL; | |
34 | |
35 // ------------------------------------------------------------------ | |
36 // CompileLog::CompileLog | |
37 CompileLog::CompileLog(const char* file, FILE* fp, intx thread_id) | |
38 : _context(_context_buffer, sizeof(_context_buffer)) | |
39 { | |
6197 | 40 initialize(new(ResourceObj::C_HEAP, mtCompiler) fileStream(fp)); |
0 | 41 _file = file; |
42 _file_end = 0; | |
43 _thread_id = thread_id; | |
44 | |
45 _identities_limit = 0; | |
46 _identities_capacity = 400; | |
6197 | 47 _identities = NEW_C_HEAP_ARRAY(char, _identities_capacity, mtCompiler); |
0 | 48 |
49 // link into the global list | |
50 { MutexLocker locker(CompileTaskAlloc_lock); | |
51 _next = _first; | |
52 _first = this; | |
53 } | |
54 } | |
55 | |
56 CompileLog::~CompileLog() { | |
57 delete _out; | |
58 _out = NULL; | |
6197 | 59 FREE_C_HEAP_ARRAY(char, _identities, mtCompiler); |
0 | 60 } |
61 | |
62 | |
63 // Advance kind up to a null or space, return this tail. | |
64 // Make sure kind is null-terminated, not space-terminated. | |
65 // Use the buffer if necessary. | |
66 static const char* split_attrs(const char* &kind, char* buffer) { | |
67 const char* attrs = strchr(kind, ' '); | |
68 // Tease apart the first word from the rest: | |
69 if (attrs == NULL) { | |
70 return ""; // no attrs, no split | |
71 } else if (kind == buffer) { | |
72 ((char*) attrs)[-1] = 0; | |
73 return attrs; | |
74 } else { | |
75 // park it in the buffer, so we can put a null on the end | |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
0
diff
changeset
|
76 assert(!(kind >= buffer && kind < buffer+100), "not obviously in buffer"); |
0 | 77 int klen = attrs - kind; |
78 strncpy(buffer, kind, klen); | |
79 buffer[klen] = 0; | |
80 kind = buffer; // return by reference | |
81 return attrs; | |
82 } | |
83 } | |
84 | |
85 // see_tag, pop_tag: Override the default do-nothing methods on xmlStream. | |
86 // These methods provide a hook for managing the the extra context markup. | |
87 void CompileLog::see_tag(const char* tag, bool push) { | |
88 if (_context.size() > 0 && _out != NULL) { | |
89 _out->write(_context.base(), _context.size()); | |
90 _context.reset(); | |
91 } | |
92 xmlStream::see_tag(tag, push); | |
93 } | |
94 void CompileLog::pop_tag(const char* tag) { | |
95 _context.reset(); // toss any context info. | |
96 xmlStream::pop_tag(tag); | |
97 } | |
98 | |
99 | |
100 // ------------------------------------------------------------------ | |
101 // CompileLog::identify | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
102 int CompileLog::identify(ciBaseObject* obj) { |
0 | 103 if (obj == NULL) return 0; |
104 int id = obj->ident(); | |
105 if (id < 0) return id; | |
106 // If it has already been identified, just return the id. | |
107 if (id < _identities_limit && _identities[id] != 0) return id; | |
108 // Lengthen the array, if necessary. | |
109 if (id >= _identities_capacity) { | |
110 int new_cap = _identities_capacity * 2; | |
111 if (new_cap <= id) new_cap = id + 100; | |
6197 | 112 _identities = REALLOC_C_HEAP_ARRAY(char, _identities, new_cap, mtCompiler); |
0 | 113 _identities_capacity = new_cap; |
114 } | |
115 while (id >= _identities_limit) { | |
116 _identities[_identities_limit++] = 0; | |
117 } | |
118 assert(id < _identities_limit, "oob"); | |
119 // Mark this id as processed. | |
120 // (Be sure to do this before any recursive calls to identify.) | |
121 _identities[id] = 1; // mark | |
122 | |
123 // Now, print the object's identity once, in detail. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
124 if (obj->is_metadata()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
125 ciMetadata* mobj = obj->as_metadata(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
126 if (mobj->is_klass()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
127 ciKlass* klass = mobj->as_klass(); |
6800
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
128 begin_elem("klass id='%d'", id); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
129 name(klass->name()); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
130 if (!klass->is_loaded()) { |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
131 print(" unloaded='1'"); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
132 } else { |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
133 print(" flags='%d'", klass->modifier_flags()); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
134 } |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
135 end_elem(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
136 } else if (mobj->is_method()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
137 ciMethod* method = mobj->as_method(); |
6800
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
138 ciSignature* sig = method->signature(); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
139 // Pre-identify items that we will need! |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
140 identify(sig->return_type()); |
0 | 141 for (int i = 0; i < sig->count(); i++) { |
6800
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
142 identify(sig->type_at(i)); |
0 | 143 } |
6800
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
144 begin_elem("method id='%d' holder='%d'", |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
145 id, identify(method->holder())); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
146 name(method->name()); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
147 print(" return='%d'", identify(sig->return_type())); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
148 if (sig->count() > 0) { |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
149 print(" arguments='"); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
150 for (int i = 0; i < sig->count(); i++) { |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
151 print((i == 0) ? "%d" : " %d", identify(sig->type_at(i))); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
152 } |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
153 print("'"); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
154 } |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
155 if (!method->is_loaded()) { |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
156 print(" unloaded='1'"); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
157 } else { |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
158 print(" flags='%d'", (jchar) method->flags().as_int()); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
159 // output a few metrics |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
160 print(" bytes='%d'", method->code_size()); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
161 method->log_nmethod_identity(this); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
162 //print(" count='%d'", method->invocation_count()); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
163 //int bec = method->backedge_count(); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
164 //if (bec != 0) print(" backedge_count='%d'", bec); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
165 print(" iicount='%d'", method->interpreter_invocation_count()); |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
166 } |
9191895df19d
7200001: failed C1 OSR compile doesn't get recompiled with C2
twisti
parents:
6725
diff
changeset
|
167 end_elem(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
168 } else if (mobj->is_type()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
169 BasicType type = mobj->as_type()->basic_type(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
170 elem("type id='%d' name='%s'", id, type2name(type)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
171 } else { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
172 // Should not happen. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
173 elem("unknown id='%d'", id); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
174 ShouldNotReachHere(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
175 } |
0 | 176 } else if (obj->is_symbol()) { |
177 begin_elem("symbol id='%d'", id); | |
178 name(obj->as_symbol()); | |
179 end_elem(); | |
180 } else { | |
181 // Should not happen. | |
182 elem("unknown id='%d'", id); | |
183 } | |
184 return id; | |
185 } | |
186 | |
187 void CompileLog::name(ciSymbol* name) { | |
188 if (name == NULL) return; | |
189 print(" name='"); | |
190 name->print_symbol_on(text()); // handles quoting conventions | |
191 print("'"); | |
192 } | |
193 | |
194 | |
195 // ------------------------------------------------------------------ | |
196 // CompileLog::clear_identities | |
197 // Forget which identities have been printed. | |
198 void CompileLog::clear_identities() { | |
199 _identities_limit = 0; | |
200 } | |
201 | |
202 // ------------------------------------------------------------------ | |
203 // CompileLog::finish_log_on_error | |
204 // | |
205 // Note: This function is called after fatal error, avoid unnecessary memory | |
206 // or stack allocation, use only async-safe functions. It's possible JVM is | |
207 // only partially initialized. | |
208 void CompileLog::finish_log_on_error(outputStream* file, char* buf, int buflen) { | |
209 static bool called_exit = false; | |
210 if (called_exit) return; | |
211 called_exit = true; | |
212 | |
213 for (CompileLog* log = _first; log != NULL; log = log->_next) { | |
214 log->flush(); | |
215 const char* partial_file = log->file(); | |
216 int partial_fd = open(partial_file, O_RDONLY); | |
217 if (partial_fd != -1) { | |
218 // print/print_cr may need to allocate large stack buffer to format | |
219 // strings, here we use snprintf() and print_raw() instead. | |
220 file->print_raw("<compilation_log thread='"); | |
221 jio_snprintf(buf, buflen, UINTX_FORMAT, log->thread_id()); | |
222 file->print_raw(buf); | |
223 file->print_raw_cr("'>"); | |
224 | |
225 size_t nr; // number read into buf from partial log | |
226 // Copy data up to the end of the last <event> element: | |
227 julong to_read = log->_file_end; | |
228 while (to_read > 0) { | |
229 if (to_read < (julong)buflen) | |
230 nr = (size_t)to_read; | |
231 else nr = buflen; | |
232 nr = read(partial_fd, buf, (int)nr); | |
233 if (nr <= 0) break; | |
234 to_read -= (julong)nr; | |
235 file->write(buf, nr); | |
236 } | |
237 | |
238 // Copy any remaining data inside a quote: | |
239 bool saw_slop = false; | |
240 int end_cdata = 0; // state machine [0..2] watching for too many "]]" | |
241 while ((nr = read(partial_fd, buf, buflen)) > 0) { | |
242 if (!saw_slop) { | |
243 file->print_raw_cr("<fragment>"); | |
244 file->print_raw_cr("<![CDATA["); | |
245 saw_slop = true; | |
246 } | |
247 // The rest of this loop amounts to a simple copy operation: | |
248 // { file->write(buf, nr); } | |
249 // However, it must sometimes output the buffer in parts, | |
250 // in case there is a CDATA quote embedded in the fragment. | |
251 const char* bufp; // pointer into buf | |
252 size_t nw; // number written in each pass of the following loop: | |
253 for (bufp = buf; nr > 0; nr -= nw, bufp += nw) { | |
254 // Write up to any problematic CDATA delimiter (usually all of nr). | |
255 for (nw = 0; nw < nr; nw++) { | |
256 // First, scan ahead into the buf, checking the state machine. | |
257 switch (bufp[nw]) { | |
258 case ']': | |
259 if (end_cdata < 2) end_cdata += 1; // saturating counter | |
260 continue; // keep scanning | |
261 case '>': | |
262 if (end_cdata == 2) break; // found CDATA delimiter! | |
263 // else fall through: | |
264 default: | |
265 end_cdata = 0; | |
266 continue; // keep scanning | |
267 } | |
268 // If we get here, nw is pointing at a bad '>'. | |
269 // It is very rare for this to happen. | |
270 // However, this code has been tested by introducing | |
271 // CDATA sequences into the compilation log. | |
272 break; | |
273 } | |
274 // Now nw is the number of characters to write, usually == nr. | |
275 file->write(bufp, nw); | |
276 if (nw < nr) { | |
277 // We are about to go around the loop again. | |
278 // But first, disrupt the ]]> by closing and reopening the quote. | |
279 file->print_raw("]]><![CDATA["); | |
280 end_cdata = 0; // reset state machine | |
281 } | |
282 } | |
283 } | |
284 if (saw_slop) { | |
285 file->print_raw_cr("]]>"); | |
286 file->print_raw_cr("</fragment>"); | |
287 } | |
288 file->print_raw_cr("</compilation_log>"); | |
289 close(partial_fd); | |
290 unlink(partial_file); | |
291 } | |
292 } | |
293 } | |
294 | |
295 // ------------------------------------------------------------------ | |
296 // CompileLog::finish_log | |
297 // | |
298 // Called during normal shutdown. For now, any clean-up needed in normal | |
299 // shutdown is also needed in VM abort, so is covered by finish_log_on_error(). | |
300 // Just allocate a buffer and call finish_log_on_error(). | |
301 void CompileLog::finish_log(outputStream* file) { | |
302 char buf[4 * K]; | |
303 finish_log_on_error(file, buf, sizeof(buf)); | |
304 } |