Mercurial > hg > truffle
annotate src/share/vm/utilities/xmlstream.cpp @ 9126:bc26f978b0ce
HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly
don't use the (wrong) cached value, but ask the runtime on each request.
Fixes regression on xml.* benchmarks @ specjvm2008. The problem was:
After the constructor of Object was deoptimized due to an assumption violation,
it was recompiled again after some time. However, on recompilation, the value
of hasFinalizeSubclass for the class was not updated and it was compiled again
with a, now wrong, assumption, which then triggers deoptimization again.
This was repeated until it hit the recompilation limit (defined by
PerMethodRecompilationCutoff), and therefore only executed by the interpreter
from now on, causing the performance regression.
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Mon, 15 Apr 2013 19:54:58 +0200 |
parents | da91efe96a93 |
children | 78bbf4d43a14 |
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 "code/nmethod.hpp" | |
27 #include "memory/allocation.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/methodData.hpp" |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
30 #include "oops/method.hpp" |
1972 | 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; | |
6197 | 46 char* init_buf = NEW_C_HEAP_ARRAY(char, init_len, mtInternal); |
0 | 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() { | |
6197 | 61 FREE_C_HEAP_ARRAY(char, _element_close_stack_low, mtInternal); |
0 | 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; | |
6197 | 158 char* new_low = NEW_C_HEAP_ARRAY(char, new_len, mtInternal); |
0 | 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; | |
6197 | 165 FREE_C_HEAP_ARRAY(char, old_low, mtInternal); |
0 | 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 } | |
4897
1ac084126285
7130319: C2: running with -XX:+PrintOptoAssembly crashes the VM with assert(false) failed: bad tag in log
dlong
parents:
2426
diff
changeset
|
195 if (bad_tag && !VMThread::should_terminate() && !VM_Exit::vm_exited() && |
1ac084126285
7130319: C2: running with -XX:+PrintOptoAssembly crashes the VM with assert(false) failed: bad tag in log
dlong
parents:
2426
diff
changeset
|
196 !is_error_reported()) |
1ac084126285
7130319: C2: running with -XX:+PrintOptoAssembly crashes the VM with assert(false) failed: bad tag in log
dlong
parents:
2426
diff
changeset
|
197 { |
0 | 198 assert(false, "bad tag in log"); |
4897
1ac084126285
7130319: C2: running with -XX:+PrintOptoAssembly crashes the VM with assert(false) failed: bad tag in log
dlong
parents:
2426
diff
changeset
|
199 } |
0 | 200 } |
201 #endif | |
202 | |
203 | |
204 // ------------------------------------------------------------------ | |
205 // First word in formatted string is element kind, and any subsequent | |
206 // words must be XML attributes. Outputs "<kind .../>". | |
207 void xmlStream::elem(const char* format, ...) { | |
208 va_list ap; | |
209 va_start(ap, format); | |
210 va_elem(format, ap); | |
211 va_end(ap); | |
212 } | |
213 | |
214 // ------------------------------------------------------------------ | |
215 void xmlStream::va_elem(const char* format, va_list ap) { | |
216 va_begin_elem(format, ap); | |
217 end_elem(); | |
218 } | |
219 | |
220 | |
221 // ------------------------------------------------------------------ | |
222 // First word in formatted string is element kind, and any subsequent | |
223 // words must be XML attributes. Outputs "<kind ...", not including "/>". | |
224 void xmlStream::begin_elem(const char* format, ...) { | |
225 va_list ap; | |
226 va_start(ap, format); | |
227 va_tag(false, format, ap); | |
228 va_end(ap); | |
229 } | |
230 | |
231 // ------------------------------------------------------------------ | |
232 void xmlStream::va_begin_elem(const char* format, va_list ap) { | |
233 va_tag(false, format, ap); | |
234 } | |
235 | |
236 // ------------------------------------------------------------------ | |
237 // Outputs "/>". | |
238 void xmlStream::end_elem() { | |
239 assert(_markup_state == ELEM, "misplaced end_elem"); | |
240 print_raw("/>\n"); | |
241 _markup_state = BODY; | |
242 } | |
243 | |
244 // ------------------------------------------------------------------ | |
245 // Outputs formatted text, followed by "/>". | |
246 void xmlStream::end_elem(const char* format, ...) { | |
247 va_list ap; | |
248 va_start(ap, format); | |
249 out()->vprint(format, ap); | |
250 va_end(ap); | |
251 end_elem(); | |
252 } | |
253 | |
254 | |
255 // ------------------------------------------------------------------ | |
256 // First word in formatted string is element kind, and any subsequent | |
257 // words must be XML attributes. Outputs "<kind ...>". | |
258 void xmlStream::head(const char* format, ...) { | |
259 va_list ap; | |
260 va_start(ap, format); | |
261 va_head(format, ap); | |
262 va_end(ap); | |
263 } | |
264 | |
265 // ------------------------------------------------------------------ | |
266 void xmlStream::va_head(const char* format, va_list ap) { | |
267 va_begin_head(format, ap); | |
268 end_head(); | |
269 } | |
270 | |
271 // ------------------------------------------------------------------ | |
272 // First word in formatted string is element kind, and any subsequent | |
273 // words must be XML attributes. Outputs "<kind ...", not including ">". | |
274 void xmlStream::begin_head(const char* format, ...) { | |
275 va_list ap; | |
276 va_start(ap, format); | |
277 va_tag(true, format, ap); | |
278 va_end(ap); | |
279 } | |
280 | |
281 // ------------------------------------------------------------------ | |
282 void xmlStream::va_begin_head(const char* format, va_list ap) { | |
283 va_tag(true, format, ap); | |
284 } | |
285 | |
286 // ------------------------------------------------------------------ | |
287 // Outputs ">". | |
288 void xmlStream::end_head() { | |
289 assert(_markup_state == HEAD, "misplaced end_head"); | |
290 print_raw(">\n"); | |
291 _markup_state = BODY; | |
292 } | |
293 | |
294 | |
295 // ------------------------------------------------------------------ | |
296 // Outputs formatted text, followed by ">". | |
297 void xmlStream::end_head(const char* format, ...) { | |
298 va_list ap; | |
299 va_start(ap, format); | |
300 out()->vprint(format, ap); | |
301 va_end(ap); | |
302 end_head(); | |
303 } | |
304 | |
305 | |
306 // ------------------------------------------------------------------ | |
307 // Outputs "</kind>". | |
308 void xmlStream::tail(const char* kind) { | |
309 pop_tag(kind); | |
310 print_raw("</"); | |
311 print_raw(kind); | |
312 print_raw(">\n"); | |
313 } | |
314 | |
315 // ------------------------------------------------------------------ | |
316 // Outputs "<kind_done ... stamp='D.DD'/> </kind>". | |
317 void xmlStream::done(const char* format, ...) { | |
318 va_list ap; | |
319 va_start(ap, format); | |
320 va_done(format, ap); | |
321 va_end(ap); | |
322 } | |
323 | |
324 // ------------------------------------------------------------------ | |
325 // Outputs "<kind_done stamp='D.DD'/> </kind>". | |
326 // Because done_raw() doesn't need to format strings, it's simpler than | |
327 // done(), and can be called safely by fatal error handler. | |
328 void xmlStream::done_raw(const char* kind) { | |
329 print_raw("<"); | |
330 print_raw(kind); | |
331 print_raw("_done stamp='"); | |
332 out()->stamp(); | |
333 print_raw_cr("'/>"); | |
334 print_raw("</"); | |
335 print_raw(kind); | |
336 print_raw_cr(">"); | |
337 } | |
338 | |
339 // ------------------------------------------------------------------ | |
340 void xmlStream::va_done(const char* format, va_list ap) { | |
341 char buffer[200]; | |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
222
diff
changeset
|
342 guarantee(strlen(format) + 10 < sizeof(buffer), "bigger format buffer"); |
0 | 343 const char* kind = format; |
344 const char* kind_end = strchr(kind, ' '); | |
345 size_t kind_len = (kind_end != NULL) ? (kind_end - kind) : strlen(kind); | |
346 strncpy(buffer, kind, kind_len); | |
347 strcpy(buffer + kind_len, "_done"); | |
348 strcat(buffer, format + kind_len); | |
349 // Output the trailing event with the timestamp. | |
350 va_begin_elem(buffer, ap); | |
351 stamp(); | |
352 end_elem(); | |
353 // Output the tail-tag of the enclosing element. | |
354 buffer[kind_len] = 0; | |
355 tail(buffer); | |
356 } | |
357 | |
358 // Output a timestamp attribute. | |
359 void xmlStream::stamp() { | |
360 assert_if_no_error(inside_attrs(), "stamp must be an attribute"); | |
361 print_raw(" stamp='"); | |
362 out()->stamp(); | |
363 print_raw("'"); | |
364 } | |
365 | |
366 | |
367 // ------------------------------------------------------------------ | |
368 // Output a method attribute, in the form " method='pkg/cls name sig'". | |
369 // This is used only when there is no ciMethod available. | |
370 void xmlStream::method(methodHandle method) { | |
371 assert_if_no_error(inside_attrs(), "printing attributes"); | |
372 if (method.is_null()) return; | |
373 print_raw(" method='"); | |
374 method_text(method); | |
375 print("' bytes='%d'", method->code_size()); | |
376 print(" count='%d'", method->invocation_count()); | |
377 int bec = method->backedge_count(); | |
378 if (bec != 0) print(" backedge_count='%d'", bec); | |
379 print(" iicount='%d'", method->interpreter_invocation_count()); | |
380 int throwouts = method->interpreter_throwout_count(); | |
381 if (throwouts != 0) print(" throwouts='%d'", throwouts); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
382 MethodData* mdo = method->method_data(); |
0 | 383 if (mdo != NULL) { |
384 uint cnt; | |
385 cnt = mdo->decompile_count(); | |
386 if (cnt != 0) print(" decompiles='%d'", cnt); | |
387 for (uint reason = 0; reason < mdo->trap_reason_limit(); reason++) { | |
388 cnt = mdo->trap_count(reason); | |
389 if (cnt != 0) print(" %s_traps='%d'", Deoptimization::trap_reason_name(reason), cnt); | |
390 } | |
391 cnt = mdo->overflow_trap_count(); | |
392 if (cnt != 0) print(" overflow_traps='%d'", cnt); | |
393 cnt = mdo->overflow_recompile_count(); | |
394 if (cnt != 0) print(" overflow_recompiles='%d'", cnt); | |
395 } | |
396 } | |
397 | |
398 void xmlStream::method_text(methodHandle method) { | |
399 assert_if_no_error(inside_attrs(), "printing attributes"); | |
400 if (method.is_null()) return; | |
401 //method->print_short_name(text()); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
402 method->method_holder()->name()->print_symbol_on(text()); |
0 | 403 print_raw(" "); // " " is easier for tools to parse than "::" |
404 method->name()->print_symbol_on(text()); | |
405 print_raw(" "); // separator | |
406 method->signature()->print_symbol_on(text()); | |
407 } | |
408 | |
409 | |
410 // ------------------------------------------------------------------ | |
411 // Output a klass attribute, in the form " klass='pkg/cls'". | |
412 // This is used only when there is no ciKlass available. | |
413 void xmlStream::klass(KlassHandle klass) { | |
414 assert_if_no_error(inside_attrs(), "printing attributes"); | |
415 if (klass.is_null()) return; | |
416 print_raw(" klass='"); | |
417 klass_text(klass); | |
418 print_raw("'"); | |
419 } | |
420 | |
421 void xmlStream::klass_text(KlassHandle klass) { | |
422 assert_if_no_error(inside_attrs(), "printing attributes"); | |
423 if (klass.is_null()) return; | |
424 //klass->print_short_name(log->out()); | |
425 klass->name()->print_symbol_on(out()); | |
426 } | |
427 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
428 void xmlStream::name(const Symbol* name) { |
0 | 429 assert_if_no_error(inside_attrs(), "printing attributes"); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
430 if (name == NULL) return; |
0 | 431 print_raw(" name='"); |
432 name_text(name); | |
433 print_raw("'"); | |
434 } | |
435 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
436 void xmlStream::name_text(const Symbol* name) { |
0 | 437 assert_if_no_error(inside_attrs(), "printing attributes"); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
438 if (name == NULL) return; |
0 | 439 //name->print_short_name(text()); |
440 name->print_symbol_on(text()); | |
441 } | |
442 | |
443 void xmlStream::object(const char* attr, Handle x) { | |
444 assert_if_no_error(inside_attrs(), "printing attributes"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
445 if (x == NULL) return; |
0 | 446 print_raw(" "); |
447 print_raw(attr); | |
448 print_raw("='"); | |
449 object_text(x); | |
450 print_raw("'"); | |
451 } | |
452 | |
453 void xmlStream::object_text(Handle x) { | |
454 assert_if_no_error(inside_attrs(), "printing attributes"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
455 if (x == NULL) return; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
456 x->print_value_on(text()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
457 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
458 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
459 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
460 void xmlStream::object(const char* attr, Metadata* x) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
461 assert_if_no_error(inside_attrs(), "printing attributes"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
462 if (x == NULL) return; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
463 print_raw(" "); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
464 print_raw(attr); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
465 print_raw("='"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
466 object_text(x); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
467 print_raw("'"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
468 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
469 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
470 void xmlStream::object_text(Metadata* x) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
471 assert_if_no_error(inside_attrs(), "printing attributes"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
472 if (x == NULL) return; |
0 | 473 //x->print_value_on(text()); |
474 if (x->is_method()) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
475 method_text((Method*)x); |
0 | 476 else if (x->is_klass()) |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
477 klass_text((Klass*)x); |
0 | 478 else |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6197
diff
changeset
|
479 ShouldNotReachHere(); // Add impl if this is reached. |
0 | 480 } |
481 | |
482 | |
483 void xmlStream::flush() { | |
484 out()->flush(); | |
485 _last_flush = count(); | |
486 } | |
487 | |
488 void xmlTextStream::flush() { | |
489 if (_outer_xmlStream == NULL) return; | |
490 _outer_xmlStream->flush(); | |
491 } | |
492 | |
493 void xmlTextStream::write(const char* str, size_t len) { | |
494 if (_outer_xmlStream == NULL) return; | |
495 _outer_xmlStream->write_text(str, len); | |
496 update_position(str, len); | |
497 } |