From 5bbd7df372b171f931dd2d7b30aae3b298766281 Mon Sep 17 00:00:00 2001 From: fparain Date: Wed, 10 Jul 2013 15:49:15 +0000 Subject: [PATCH] 7143807: ResourceMark nesting problem in stringStream Reviewed-by: kvn, dcubed --- src/share/vm/memory/resourceArea.hpp | 27 ++++++++++++++++++++++++++- src/share/vm/runtime/thread.cpp | 1 + src/share/vm/runtime/thread.hpp | 6 ++++++ src/share/vm/utilities/ostream.cpp | 3 +++ src/share/vm/utilities/ostream.hpp | 3 +++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/share/vm/memory/resourceArea.hpp b/src/share/vm/memory/resourceArea.hpp index 0699334a5..1357081fd 100644 --- a/src/share/vm/memory/resourceArea.hpp +++ b/src/share/vm/memory/resourceArea.hpp @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -83,6 +83,10 @@ protected: Chunk *_chunk; // saved arena chunk char *_hwm, *_max; size_t _size_in_bytes; +#ifdef ASSERT + Thread* _thread; + ResourceMark* _previous_resource_mark; +#endif //ASSERT void initialize(Thread *thread) { _area = thread->resource_area(); @@ -92,6 +96,11 @@ protected: _size_in_bytes = _area->size_in_bytes(); debug_only(_area->_nesting++;) 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: @@ -111,6 +120,17 @@ protected: _size_in_bytes = r->_size_in_bytes; debug_only(_area->_nesting++;) 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() { @@ -137,6 +157,11 @@ protected: assert( _area->_nesting > 0, "must stack allocate RMs" ); debug_only(_area->_nesting--;) reset_to_mark(); +#ifdef ASSERT + if (_thread != NULL) { + _thread->set_current_resource_mark(_previous_resource_mark); + } +#endif // ASSERT } diff --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp index ef862012f..a491c4d26 100644 --- a/src/share/vm/runtime/thread.cpp +++ b/src/share/vm/runtime/thread.cpp @@ -218,6 +218,7 @@ Thread::Thread() { // allocated data structures set_osthread(NULL); set_resource_area(new (mtThread)ResourceArea()); + DEBUG_ONLY(_current_resource_mark = NULL;) set_handle_area(new (mtThread) HandleArea(NULL)); set_metadata_handles(new (ResourceObj::C_HEAP, mtClass) GrowableArray(30, true)); set_active_handles(NULL); diff --git a/src/share/vm/runtime/thread.hpp b/src/share/vm/runtime/thread.hpp index 8b8e6dd4e..13950ec16 100644 --- a/src/share/vm/runtime/thread.hpp +++ b/src/share/vm/runtime/thread.hpp @@ -86,6 +86,8 @@ class GCTaskQueue; class ThreadClosure; class IdealGraphPrinter; +DEBUG_ONLY(class ResourceMark;) + class WorkerThread; // Class hierarchy @@ -531,6 +533,8 @@ public: // Thread local resource area for temporary allocation within the VM ResourceArea* _resource_area; + DEBUG_ONLY(ResourceMark* _current_resource_mark;) + // Thread local handle area for allocation of handles within the VM HandleArea* _handle_area; GrowableArray* _metadata_handles; @@ -585,6 +589,8 @@ public: // Deadlock detection 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 void check_for_valid_safepoint_state(bool potential_vm_operation) PRODUCT_RETURN; diff --git a/src/share/vm/utilities/ostream.cpp b/src/share/vm/utilities/ostream.cpp index 1d066ddde..2f04fa0e4 100644 --- a/src/share/vm/utilities/ostream.cpp +++ b/src/share/vm/utilities/ostream.cpp @@ -296,6 +296,7 @@ stringStream::stringStream(size_t initial_size) : outputStream() { buffer = NEW_RESOURCE_ARRAY(char, buffer_length); buffer_pos = 0; buffer_fixed = false; + DEBUG_ONLY(rm = Thread::current()->current_resource_mark();) } // 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; } 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); strncpy(buffer, oldbuf, buffer_pos); buffer_length = end; diff --git a/src/share/vm/utilities/ostream.hpp b/src/share/vm/utilities/ostream.hpp index 6b154184b..4d1384766 100644 --- a/src/share/vm/utilities/ostream.hpp +++ b/src/share/vm/utilities/ostream.hpp @@ -28,6 +28,8 @@ #include "memory/allocation.hpp" #include "runtime/timer.hpp" +DEBUG_ONLY(class ResourceMark;) + // Output streams for printing // // Printing guidelines: @@ -177,6 +179,7 @@ class stringStream : public outputStream { size_t buffer_pos; size_t buffer_length; bool buffer_fixed; + DEBUG_ONLY(ResourceMark* rm;) public: stringStream(size_t initial_bufsize = 256); stringStream(char* fixed_buffer, size_t fixed_buffer_size); -- GitLab