annotate src/share/vm/utilities/xmlstream.cpp @ 453:c96030fff130

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