307 } |
307 } |
308 } |
308 } |
309 |
309 |
310 stringStream::stringStream(size_t initial_size) : outputStream() { |
310 stringStream::stringStream(size_t initial_size) : outputStream() { |
311 buffer_length = initial_size; |
311 buffer_length = initial_size; |
312 buffer = NEW_RESOURCE_ARRAY(char, buffer_length); |
312 buffer = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal); |
313 buffer_pos = 0; |
313 buffer_pos = 0; |
314 buffer_fixed = false; |
314 buffer_fixed = false; |
315 DEBUG_ONLY(rm = Thread::current()->current_resource_mark();) |
|
316 } |
315 } |
317 |
316 |
318 // useful for output to fixed chunks of memory, such as performance counters |
317 // useful for output to fixed chunks of memory, such as performance counters |
319 stringStream::stringStream(char* fixed_buffer, size_t fixed_buffer_size) : outputStream() { |
318 stringStream::stringStream(char* fixed_buffer, size_t fixed_buffer_size) : outputStream() { |
320 buffer_length = fixed_buffer_size; |
319 buffer_length = fixed_buffer_size; |
335 // For small overruns, double the buffer. For larger ones, |
334 // For small overruns, double the buffer. For larger ones, |
336 // increase to the requested size. |
335 // increase to the requested size. |
337 if (end < buffer_length * 2) { |
336 if (end < buffer_length * 2) { |
338 end = buffer_length * 2; |
337 end = buffer_length * 2; |
339 } |
338 } |
340 char* oldbuf = buffer; |
339 buffer = REALLOC_C_HEAP_ARRAY(char, buffer, end, mtInternal); |
341 assert(rm == NULL || Thread::current()->current_resource_mark() == rm, |
|
342 "StringStream is re-allocated with a different ResourceMark. Current: " |
|
343 PTR_FORMAT " original: " PTR_FORMAT, |
|
344 p2i(Thread::current()->current_resource_mark()), p2i(rm)); |
|
345 buffer = NEW_RESOURCE_ARRAY(char, end); |
|
346 if (buffer_pos > 0) { |
|
347 memcpy(buffer, oldbuf, buffer_pos); |
|
348 } |
|
349 buffer_length = end; |
340 buffer_length = end; |
350 } |
341 } |
351 } |
342 } |
352 // invariant: buffer is always null-terminated |
343 // invariant: buffer is always null-terminated |
353 guarantee(buffer_pos + write_len + 1 <= buffer_length, "stringStream oob"); |
344 guarantee(buffer_pos + write_len + 1 <= buffer_length, "stringStream oob"); |
368 strncpy(copy, buffer, buffer_pos); |
359 strncpy(copy, buffer, buffer_pos); |
369 copy[buffer_pos] = 0; // terminating null |
360 copy[buffer_pos] = 0; // terminating null |
370 return copy; |
361 return copy; |
371 } |
362 } |
372 |
363 |
373 stringStream::~stringStream() {} |
364 stringStream::~stringStream() { |
|
365 if (buffer_fixed == false && buffer != NULL) { |
|
366 FREE_C_HEAP_ARRAY(char, buffer); |
|
367 } |
|
368 } |
374 |
369 |
375 xmlStream* xtty; |
370 xmlStream* xtty; |
376 outputStream* tty; |
371 outputStream* tty; |
377 CDS_ONLY(fileStream* classlist_file;) // Only dump the classes that can be stored into the CDS archive |
372 CDS_ONLY(fileStream* classlist_file;) // Only dump the classes that can be stored into the CDS archive |
378 extern Mutex* tty_lock; |
373 extern Mutex* tty_lock; |