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