Mercurial > hg > graal-compiler
annotate src/share/vm/utilities/xmlstream.cpp @ 1941:79d04223b8a5
Added caching for resolved types and resolved fields.
This is crucial, because the local load elimination will lead to wrong results, if field equality (of two RiField objects with the same object and the same RiType) is not given. The caching makes sure that the default equals implementation is sufficient.
author | Thomas Wuerthinger <wuerthinger@ssw.jku.at> |
---|---|
date | Tue, 28 Dec 2010 18:33:26 +0100 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
2 * Copyright (c) 2002, 2007, 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 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_xmlstream.cpp.incl" | |
27 | |
28 void xmlStream::initialize(outputStream* out) { | |
29 _out = out; | |
30 _last_flush = 0; | |
31 _markup_state = BODY; | |
32 _text_init._outer_xmlStream = this; | |
33 _text = &_text_init; | |
34 | |
35 #ifdef ASSERT | |
36 _element_depth = 0; | |
37 int init_len = 100; | |
38 char* init_buf = NEW_C_HEAP_ARRAY(char, init_len); | |
39 _element_close_stack_low = init_buf; | |
40 _element_close_stack_high = init_buf + init_len; | |
41 _element_close_stack_ptr = init_buf + init_len - 1; | |
42 _element_close_stack_ptr[0] = '\0'; | |
43 #endif | |
44 | |
45 // Make sure each log uses the same base for time stamps. | |
46 if (is_open()) { | |
47 _out->time_stamp().update_to(1); | |
48 } | |
49 } | |
50 | |
51 #ifdef ASSERT | |
52 xmlStream::~xmlStream() { | |
53 FREE_C_HEAP_ARRAY(char, _element_close_stack_low); | |
54 } | |
55 #endif | |
56 | |
57 // Pass the given chars directly to _out. | |
58 void xmlStream::write(const char* s, size_t len) { | |
59 if (!is_open()) return; | |
60 | |
61 out()->write(s, len); | |
222 | 62 update_position(s, len); |
0 | 63 } |
64 | |
65 | |
66 // Pass the given chars directly to _out, except that | |
67 // we watch for special "<&>" chars. | |
68 // This is suitable for either attribute text or for body text. | |
69 // We don't fool with "<![CDATA[" quotes, just single-character entities. | |
70 // This makes it easier for dumb tools to parse the output. | |
71 void xmlStream::write_text(const char* s, size_t len) { | |
72 if (!is_open()) return; | |
73 | |
74 size_t written = 0; | |
75 // All normally printed material goes inside XML quotes. | |
76 // This leaves the output free to include markup also. | |
77 // Scan the string looking for inadvertant "<&>" chars | |
78 for (size_t i = 0; i < len; i++) { | |
79 char ch = s[i]; | |
80 // Escape special chars. | |
81 const char* esc = NULL; | |
82 switch (ch) { | |
83 // These are important only in attrs, but we do them always: | |
84 case '\'': esc = "'"; break; | |
85 case '"': esc = """; break; | |
86 case '<': esc = "<"; break; | |
87 case '&': esc = "&"; break; | |
88 // This is a freebie. | |
89 case '>': esc = ">"; break; | |
90 } | |
91 if (esc != NULL) { | |
92 if (written < i) { | |
93 out()->write(&s[written], i - written); | |
94 written = i; | |
95 } | |
96 out()->print_raw(esc); | |
97 written++; | |
98 } | |
99 } | |
100 | |
101 // Print the clean remainder. Usually, it is all of s. | |
102 if (written < len) { | |
103 out()->write(&s[written], len - written); | |
104 } | |
105 } | |
106 | |
107 // ------------------------------------------------------------------ | |
108 // Outputs XML text, with special characters quoted. | |
109 void xmlStream::text(const char* format, ...) { | |
110 va_list ap; | |
111 va_start(ap, format); | |
112 va_text(format, ap); | |
113 va_end(ap); | |
114 } | |
115 | |
116 #define BUFLEN 2*K /* max size of output of individual print methods */ | |
117 | |
118 // ------------------------------------------------------------------ | |
119 void xmlStream::va_tag(bool push, const char* format, va_list ap) { | |
120 assert_if_no_error(!inside_attrs(), "cannot print tag inside attrs"); | |
121 char buffer[BUFLEN]; | |
122 size_t len; | |
123 const char* kind = do_vsnprintf(buffer, BUFLEN, format, ap, false, len); | |
124 see_tag(kind, push); | |
125 print_raw("<"); | |
126 write(kind, len); | |
127 _markup_state = (push ? HEAD : ELEM); | |
128 } | |
129 | |
130 #ifdef ASSERT | |
131 /// Debugging goo to make sure element tags nest properly. | |
132 | |
133 // ------------------------------------------------------------------ | |
134 void xmlStream::see_tag(const char* tag, bool push) { | |
135 assert_if_no_error(!inside_attrs(), "cannot start new element inside attrs"); | |
136 if (!push) return; | |
137 | |
138 // tag goes up until either null or space: | |
139 const char* tag_end = strchr(tag, ' '); | |
140 size_t tag_len = (tag_end == NULL) ? strlen(tag) : tag_end - tag; | |
141 assert(tag_len > 0, "tag must not be empty"); | |
142 // push the tag onto the stack, pulling down the pointer | |
143 char* old_ptr = _element_close_stack_ptr; | |
144 char* old_low = _element_close_stack_low; | |
145 char* push_ptr = old_ptr - (tag_len+1); | |
146 if (push_ptr < old_low) { | |
147 int old_len = _element_close_stack_high - old_ptr; | |
148 int new_len = old_len * 2; | |
149 if (new_len < 100) new_len = 100; | |
150 char* new_low = NEW_C_HEAP_ARRAY(char, new_len); | |
151 char* new_high = new_low + new_len; | |
152 char* new_ptr = new_high - old_len; | |
153 memcpy(new_ptr, old_ptr, old_len); | |
154 _element_close_stack_high = new_high; | |
155 _element_close_stack_low = new_low; | |
156 _element_close_stack_ptr = new_ptr; | |
157 FREE_C_HEAP_ARRAY(char, old_low); | |
158 push_ptr = new_ptr - (tag_len+1); | |
159 } | |
160 assert(push_ptr >= _element_close_stack_low, "in range"); | |
161 memcpy(push_ptr, tag, tag_len); | |
162 push_ptr[tag_len] = 0; | |
163 _element_close_stack_ptr = push_ptr; | |
164 _element_depth += 1; | |
165 } | |
166 | |
167 // ------------------------------------------------------------------ | |
168 void xmlStream::pop_tag(const char* tag) { | |
169 assert_if_no_error(!inside_attrs(), "cannot close element inside attrs"); | |
170 assert(_element_depth > 0, "must be in an element to close"); | |
171 assert(*tag != 0, "tag must not be empty"); | |
172 char* cur_tag = _element_close_stack_ptr; | |
173 bool bad_tag = false; | |
174 while (*cur_tag != 0 && strcmp(cur_tag, tag) != 0) { | |
175 this->print_cr("</%s> <!-- missing closing tag -->", cur_tag); | |
176 _element_close_stack_ptr = (cur_tag += strlen(cur_tag) + 1); | |
177 _element_depth -= 1; | |
178 bad_tag = true; | |
179 } | |
180 if (*cur_tag == 0) { | |
181 bad_tag = true; | |
182 } else { | |
183 // Pop the stack, by skipping over the tag and its null. | |
184 _element_close_stack_ptr = cur_tag + strlen(cur_tag) + 1; | |
185 _element_depth -= 1; | |
186 } | |
187 if (bad_tag && !VMThread::should_terminate() && !is_error_reported()) | |
188 assert(false, "bad tag in log"); | |
189 } | |
190 #endif | |
191 | |
192 | |
193 // ------------------------------------------------------------------ | |
194 // First word in formatted string is element kind, and any subsequent | |
195 // words must be XML attributes. Outputs "<kind .../>". | |
196 void xmlStream::elem(const char* format, ...) { | |
197 va_list ap; | |
198 va_start(ap, format); | |
199 va_elem(format, ap); | |
200 va_end(ap); | |
201 } | |
202 | |
203 // ------------------------------------------------------------------ | |
204 void xmlStream::va_elem(const char* format, va_list ap) { | |
205 va_begin_elem(format, ap); | |
206 end_elem(); | |
207 } | |
208 | |
209 | |
210 // ------------------------------------------------------------------ | |
211 // First word in formatted string is element kind, and any subsequent | |
212 // words must be XML attributes. Outputs "<kind ...", not including "/>". | |
213 void xmlStream::begin_elem(const char* format, ...) { | |
214 va_list ap; | |
215 va_start(ap, format); | |
216 va_tag(false, format, ap); | |
217 va_end(ap); | |
218 } | |
219 | |
220 // ------------------------------------------------------------------ | |
221 void xmlStream::va_begin_elem(const char* format, va_list ap) { | |
222 va_tag(false, format, ap); | |
223 } | |
224 | |
225 // ------------------------------------------------------------------ | |
226 // Outputs "/>". | |
227 void xmlStream::end_elem() { | |
228 assert(_markup_state == ELEM, "misplaced end_elem"); | |
229 print_raw("/>\n"); | |
230 _markup_state = BODY; | |
231 } | |
232 | |
233 // ------------------------------------------------------------------ | |
234 // Outputs formatted text, followed by "/>". | |
235 void xmlStream::end_elem(const char* format, ...) { | |
236 va_list ap; | |
237 va_start(ap, format); | |
238 out()->vprint(format, ap); | |
239 va_end(ap); | |
240 end_elem(); | |
241 } | |
242 | |
243 | |
244 // ------------------------------------------------------------------ | |
245 // First word in formatted string is element kind, and any subsequent | |
246 // words must be XML attributes. Outputs "<kind ...>". | |
247 void xmlStream::head(const char* format, ...) { | |
248 va_list ap; | |
249 va_start(ap, format); | |
250 va_head(format, ap); | |
251 va_end(ap); | |
252 } | |
253 | |
254 // ------------------------------------------------------------------ | |
255 void xmlStream::va_head(const char* format, va_list ap) { | |
256 va_begin_head(format, ap); | |
257 end_head(); | |
258 } | |
259 | |
260 // ------------------------------------------------------------------ | |
261 // First word in formatted string is element kind, and any subsequent | |
262 // words must be XML attributes. Outputs "<kind ...", not including ">". | |
263 void xmlStream::begin_head(const char* format, ...) { | |
264 va_list ap; | |
265 va_start(ap, format); | |
266 va_tag(true, format, ap); | |
267 va_end(ap); | |
268 } | |
269 | |
270 // ------------------------------------------------------------------ | |
271 void xmlStream::va_begin_head(const char* format, va_list ap) { | |
272 va_tag(true, format, ap); | |
273 } | |
274 | |
275 // ------------------------------------------------------------------ | |
276 // Outputs ">". | |
277 void xmlStream::end_head() { | |
278 assert(_markup_state == HEAD, "misplaced end_head"); | |
279 print_raw(">\n"); | |
280 _markup_state = BODY; | |
281 } | |
282 | |
283 | |
284 // ------------------------------------------------------------------ | |
285 // Outputs formatted text, followed by ">". | |
286 void xmlStream::end_head(const char* format, ...) { | |
287 va_list ap; | |
288 va_start(ap, format); | |
289 out()->vprint(format, ap); | |
290 va_end(ap); | |
291 end_head(); | |
292 } | |
293 | |
294 | |
295 // ------------------------------------------------------------------ | |
296 // Outputs "</kind>". | |
297 void xmlStream::tail(const char* kind) { | |
298 pop_tag(kind); | |
299 print_raw("</"); | |
300 print_raw(kind); | |
301 print_raw(">\n"); | |
302 } | |
303 | |
304 // ------------------------------------------------------------------ | |
305 // Outputs "<kind_done ... stamp='D.DD'/> </kind>". | |
306 void xmlStream::done(const char* format, ...) { | |
307 va_list ap; | |
308 va_start(ap, format); | |
309 va_done(format, ap); | |
310 va_end(ap); | |
311 } | |
312 | |
313 // ------------------------------------------------------------------ | |
314 // Outputs "<kind_done stamp='D.DD'/> </kind>". | |
315 // Because done_raw() doesn't need to format strings, it's simpler than | |
316 // done(), and can be called safely by fatal error handler. | |
317 void xmlStream::done_raw(const char* kind) { | |
318 print_raw("<"); | |
319 print_raw(kind); | |
320 print_raw("_done stamp='"); | |
321 out()->stamp(); | |
322 print_raw_cr("'/>"); | |
323 print_raw("</"); | |
324 print_raw(kind); | |
325 print_raw_cr(">"); | |
326 } | |
327 | |
328 // ------------------------------------------------------------------ | |
329 void xmlStream::va_done(const char* format, va_list ap) { | |
330 char buffer[200]; | |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
222
diff
changeset
|
331 guarantee(strlen(format) + 10 < sizeof(buffer), "bigger format buffer"); |
0 | 332 const char* kind = format; |
333 const char* kind_end = strchr(kind, ' '); | |
334 size_t kind_len = (kind_end != NULL) ? (kind_end - kind) : strlen(kind); | |
335 strncpy(buffer, kind, kind_len); | |
336 strcpy(buffer + kind_len, "_done"); | |
337 strcat(buffer, format + kind_len); | |
338 // Output the trailing event with the timestamp. | |
339 va_begin_elem(buffer, ap); | |
340 stamp(); | |
341 end_elem(); | |
342 // Output the tail-tag of the enclosing element. | |
343 buffer[kind_len] = 0; | |
344 tail(buffer); | |
345 } | |
346 | |
347 // Output a timestamp attribute. | |
348 void xmlStream::stamp() { | |
349 assert_if_no_error(inside_attrs(), "stamp must be an attribute"); | |
350 print_raw(" stamp='"); | |
351 out()->stamp(); | |
352 print_raw("'"); | |
353 } | |
354 | |
355 | |
356 // ------------------------------------------------------------------ | |
357 // Output a method attribute, in the form " method='pkg/cls name sig'". | |
358 // This is used only when there is no ciMethod available. | |
359 void xmlStream::method(methodHandle method) { | |
360 assert_if_no_error(inside_attrs(), "printing attributes"); | |
361 if (method.is_null()) return; | |
362 print_raw(" method='"); | |
363 method_text(method); | |
364 print("' bytes='%d'", method->code_size()); | |
365 print(" count='%d'", method->invocation_count()); | |
366 int bec = method->backedge_count(); | |
367 if (bec != 0) print(" backedge_count='%d'", bec); | |
368 print(" iicount='%d'", method->interpreter_invocation_count()); | |
369 int throwouts = method->interpreter_throwout_count(); | |
370 if (throwouts != 0) print(" throwouts='%d'", throwouts); | |
371 methodDataOop mdo = method->method_data(); | |
372 if (mdo != NULL) { | |
373 uint cnt; | |
374 cnt = mdo->decompile_count(); | |
375 if (cnt != 0) print(" decompiles='%d'", cnt); | |
376 for (uint reason = 0; reason < mdo->trap_reason_limit(); reason++) { | |
377 cnt = mdo->trap_count(reason); | |
378 if (cnt != 0) print(" %s_traps='%d'", Deoptimization::trap_reason_name(reason), cnt); | |
379 } | |
380 cnt = mdo->overflow_trap_count(); | |
381 if (cnt != 0) print(" overflow_traps='%d'", cnt); | |
382 cnt = mdo->overflow_recompile_count(); | |
383 if (cnt != 0) print(" overflow_recompiles='%d'", cnt); | |
384 } | |
385 } | |
386 | |
387 void xmlStream::method_text(methodHandle method) { | |
388 assert_if_no_error(inside_attrs(), "printing attributes"); | |
389 if (method.is_null()) return; | |
390 //method->print_short_name(text()); | |
391 method->method_holder()->klass_part()->name()->print_symbol_on(text()); | |
392 print_raw(" "); // " " is easier for tools to parse than "::" | |
393 method->name()->print_symbol_on(text()); | |
394 print_raw(" "); // separator | |
395 method->signature()->print_symbol_on(text()); | |
396 } | |
397 | |
398 | |
399 // ------------------------------------------------------------------ | |
400 // Output a klass attribute, in the form " klass='pkg/cls'". | |
401 // This is used only when there is no ciKlass available. | |
402 void xmlStream::klass(KlassHandle klass) { | |
403 assert_if_no_error(inside_attrs(), "printing attributes"); | |
404 if (klass.is_null()) return; | |
405 print_raw(" klass='"); | |
406 klass_text(klass); | |
407 print_raw("'"); | |
408 } | |
409 | |
410 void xmlStream::klass_text(KlassHandle klass) { | |
411 assert_if_no_error(inside_attrs(), "printing attributes"); | |
412 if (klass.is_null()) return; | |
413 //klass->print_short_name(log->out()); | |
414 klass->name()->print_symbol_on(out()); | |
415 } | |
416 | |
417 void xmlStream::name(symbolHandle name) { | |
418 assert_if_no_error(inside_attrs(), "printing attributes"); | |
419 if (name.is_null()) return; | |
420 print_raw(" name='"); | |
421 name_text(name); | |
422 print_raw("'"); | |
423 } | |
424 | |
425 void xmlStream::name_text(symbolHandle name) { | |
426 assert_if_no_error(inside_attrs(), "printing attributes"); | |
427 if (name.is_null()) return; | |
428 //name->print_short_name(text()); | |
429 name->print_symbol_on(text()); | |
430 } | |
431 | |
432 void xmlStream::object(const char* attr, Handle x) { | |
433 assert_if_no_error(inside_attrs(), "printing attributes"); | |
434 if (x.is_null()) return; | |
435 print_raw(" "); | |
436 print_raw(attr); | |
437 print_raw("='"); | |
438 object_text(x); | |
439 print_raw("'"); | |
440 } | |
441 | |
442 void xmlStream::object_text(Handle x) { | |
443 assert_if_no_error(inside_attrs(), "printing attributes"); | |
444 if (x.is_null()) return; | |
445 //x->print_value_on(text()); | |
446 if (x->is_method()) | |
447 method_text(methodOop(x())); | |
448 else if (x->is_klass()) | |
449 klass_text(klassOop(x())); | |
450 else if (x->is_symbol()) | |
451 name_text(symbolOop(x())); | |
452 else | |
453 x->print_value_on(text()); | |
454 } | |
455 | |
456 | |
457 void xmlStream::flush() { | |
458 out()->flush(); | |
459 _last_flush = count(); | |
460 } | |
461 | |
462 void xmlTextStream::flush() { | |
463 if (_outer_xmlStream == NULL) return; | |
464 _outer_xmlStream->flush(); | |
465 } | |
466 | |
467 void xmlTextStream::write(const char* str, size_t len) { | |
468 if (_outer_xmlStream == NULL) return; | |
469 _outer_xmlStream->write_text(str, len); | |
470 update_position(str, len); | |
471 } |