mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
7143807: ResourceMark nesting problem in stringStream
Reviewed-by: kvn, dcubed
This commit is contained in:
parent
de0c86b0b4
commit
c716fa083c
5 changed files with 39 additions and 1 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -83,6 +83,10 @@ protected:
|
||||||
Chunk *_chunk; // saved arena chunk
|
Chunk *_chunk; // saved arena chunk
|
||||||
char *_hwm, *_max;
|
char *_hwm, *_max;
|
||||||
size_t _size_in_bytes;
|
size_t _size_in_bytes;
|
||||||
|
#ifdef ASSERT
|
||||||
|
Thread* _thread;
|
||||||
|
ResourceMark* _previous_resource_mark;
|
||||||
|
#endif //ASSERT
|
||||||
|
|
||||||
void initialize(Thread *thread) {
|
void initialize(Thread *thread) {
|
||||||
_area = thread->resource_area();
|
_area = thread->resource_area();
|
||||||
|
@ -92,6 +96,11 @@ protected:
|
||||||
_size_in_bytes = _area->size_in_bytes();
|
_size_in_bytes = _area->size_in_bytes();
|
||||||
debug_only(_area->_nesting++;)
|
debug_only(_area->_nesting++;)
|
||||||
assert( _area->_nesting > 0, "must stack allocate RMs" );
|
assert( _area->_nesting > 0, "must stack allocate RMs" );
|
||||||
|
#ifdef ASSERT
|
||||||
|
_thread = thread;
|
||||||
|
_previous_resource_mark = thread->current_resource_mark();
|
||||||
|
thread->set_current_resource_mark(this);
|
||||||
|
#endif // ASSERT
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -111,6 +120,17 @@ protected:
|
||||||
_size_in_bytes = r->_size_in_bytes;
|
_size_in_bytes = r->_size_in_bytes;
|
||||||
debug_only(_area->_nesting++;)
|
debug_only(_area->_nesting++;)
|
||||||
assert( _area->_nesting > 0, "must stack allocate RMs" );
|
assert( _area->_nesting > 0, "must stack allocate RMs" );
|
||||||
|
#ifdef ASSERT
|
||||||
|
Thread* thread = ThreadLocalStorage::thread();
|
||||||
|
if (thread != NULL) {
|
||||||
|
_thread = thread;
|
||||||
|
_previous_resource_mark = thread->current_resource_mark();
|
||||||
|
thread->set_current_resource_mark(this);
|
||||||
|
} else {
|
||||||
|
_thread = NULL;
|
||||||
|
_previous_resource_mark = NULL;
|
||||||
|
}
|
||||||
|
#endif // ASSERT
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_to_mark() {
|
void reset_to_mark() {
|
||||||
|
@ -137,6 +157,11 @@ protected:
|
||||||
assert( _area->_nesting > 0, "must stack allocate RMs" );
|
assert( _area->_nesting > 0, "must stack allocate RMs" );
|
||||||
debug_only(_area->_nesting--;)
|
debug_only(_area->_nesting--;)
|
||||||
reset_to_mark();
|
reset_to_mark();
|
||||||
|
#ifdef ASSERT
|
||||||
|
if (_thread != NULL) {
|
||||||
|
_thread->set_current_resource_mark(_previous_resource_mark);
|
||||||
|
}
|
||||||
|
#endif // ASSERT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -218,6 +218,7 @@ Thread::Thread() {
|
||||||
// allocated data structures
|
// allocated data structures
|
||||||
set_osthread(NULL);
|
set_osthread(NULL);
|
||||||
set_resource_area(new (mtThread)ResourceArea());
|
set_resource_area(new (mtThread)ResourceArea());
|
||||||
|
DEBUG_ONLY(_current_resource_mark = NULL;)
|
||||||
set_handle_area(new (mtThread) HandleArea(NULL));
|
set_handle_area(new (mtThread) HandleArea(NULL));
|
||||||
set_metadata_handles(new (ResourceObj::C_HEAP, mtClass) GrowableArray<Metadata*>(30, true));
|
set_metadata_handles(new (ResourceObj::C_HEAP, mtClass) GrowableArray<Metadata*>(30, true));
|
||||||
set_active_handles(NULL);
|
set_active_handles(NULL);
|
||||||
|
|
|
@ -86,6 +86,8 @@ class GCTaskQueue;
|
||||||
class ThreadClosure;
|
class ThreadClosure;
|
||||||
class IdealGraphPrinter;
|
class IdealGraphPrinter;
|
||||||
|
|
||||||
|
DEBUG_ONLY(class ResourceMark;)
|
||||||
|
|
||||||
class WorkerThread;
|
class WorkerThread;
|
||||||
|
|
||||||
// Class hierarchy
|
// Class hierarchy
|
||||||
|
@ -531,6 +533,8 @@ public:
|
||||||
// Thread local resource area for temporary allocation within the VM
|
// Thread local resource area for temporary allocation within the VM
|
||||||
ResourceArea* _resource_area;
|
ResourceArea* _resource_area;
|
||||||
|
|
||||||
|
DEBUG_ONLY(ResourceMark* _current_resource_mark;)
|
||||||
|
|
||||||
// Thread local handle area for allocation of handles within the VM
|
// Thread local handle area for allocation of handles within the VM
|
||||||
HandleArea* _handle_area;
|
HandleArea* _handle_area;
|
||||||
GrowableArray<Metadata*>* _metadata_handles;
|
GrowableArray<Metadata*>* _metadata_handles;
|
||||||
|
@ -585,6 +589,8 @@ public:
|
||||||
|
|
||||||
// Deadlock detection
|
// Deadlock detection
|
||||||
bool allow_allocation() { return _allow_allocation_count == 0; }
|
bool allow_allocation() { return _allow_allocation_count == 0; }
|
||||||
|
ResourceMark* current_resource_mark() { return _current_resource_mark; }
|
||||||
|
void set_current_resource_mark(ResourceMark* rm) { _current_resource_mark = rm; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void check_for_valid_safepoint_state(bool potential_vm_operation) PRODUCT_RETURN;
|
void check_for_valid_safepoint_state(bool potential_vm_operation) PRODUCT_RETURN;
|
||||||
|
|
|
@ -296,6 +296,7 @@ stringStream::stringStream(size_t initial_size) : outputStream() {
|
||||||
buffer = NEW_RESOURCE_ARRAY(char, buffer_length);
|
buffer = NEW_RESOURCE_ARRAY(char, buffer_length);
|
||||||
buffer_pos = 0;
|
buffer_pos = 0;
|
||||||
buffer_fixed = false;
|
buffer_fixed = false;
|
||||||
|
DEBUG_ONLY(rm = Thread::current()->current_resource_mark();)
|
||||||
}
|
}
|
||||||
|
|
||||||
// useful for output to fixed chunks of memory, such as performance counters
|
// useful for output to fixed chunks of memory, such as performance counters
|
||||||
|
@ -321,6 +322,8 @@ void stringStream::write(const char* s, size_t len) {
|
||||||
end = buffer_length * 2;
|
end = buffer_length * 2;
|
||||||
}
|
}
|
||||||
char* oldbuf = buffer;
|
char* oldbuf = buffer;
|
||||||
|
assert(rm == NULL || Thread::current()->current_resource_mark() == rm,
|
||||||
|
"stringStream is re-allocated with a different ResourceMark");
|
||||||
buffer = NEW_RESOURCE_ARRAY(char, end);
|
buffer = NEW_RESOURCE_ARRAY(char, end);
|
||||||
strncpy(buffer, oldbuf, buffer_pos);
|
strncpy(buffer, oldbuf, buffer_pos);
|
||||||
buffer_length = end;
|
buffer_length = end;
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include "memory/allocation.hpp"
|
#include "memory/allocation.hpp"
|
||||||
#include "runtime/timer.hpp"
|
#include "runtime/timer.hpp"
|
||||||
|
|
||||||
|
DEBUG_ONLY(class ResourceMark;)
|
||||||
|
|
||||||
// Output streams for printing
|
// Output streams for printing
|
||||||
//
|
//
|
||||||
// Printing guidelines:
|
// Printing guidelines:
|
||||||
|
@ -177,6 +179,7 @@ class stringStream : public outputStream {
|
||||||
size_t buffer_pos;
|
size_t buffer_pos;
|
||||||
size_t buffer_length;
|
size_t buffer_length;
|
||||||
bool buffer_fixed;
|
bool buffer_fixed;
|
||||||
|
DEBUG_ONLY(ResourceMark* rm;)
|
||||||
public:
|
public:
|
||||||
stringStream(size_t initial_bufsize = 256);
|
stringStream(size_t initial_bufsize = 256);
|
||||||
stringStream(char* fixed_buffer, size_t fixed_buffer_size);
|
stringStream(char* fixed_buffer, size_t fixed_buffer_size);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue