# HG changeset patch # User fparain # Date 1373471355 0 # Node ID ac0163dd0a50f39d74914d49749d1a1f3a478437 # Parent 9f928b94b877d2fb49f7eab96f3f6773dfd9687b 7143807: ResourceMark nesting problem in stringStream Reviewed-by: kvn, dcubed diff -r 9f928b94b877 -r ac0163dd0a50 hotspot/src/share/vm/memory/resourceArea.hpp --- a/hotspot/src/share/vm/memory/resourceArea.hpp Tue Jul 09 22:48:52 2013 +0200 +++ b/hotspot/src/share/vm/memory/resourceArea.hpp Wed Jul 10 15:49:15 2013 +0000 @@ -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 @@ 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 @@ _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 @@ _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 @@ 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 -r 9f928b94b877 -r ac0163dd0a50 hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Tue Jul 09 22:48:52 2013 +0200 +++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 10 15:49:15 2013 +0000 @@ -218,6 +218,7 @@ // 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 -r 9f928b94b877 -r ac0163dd0a50 hotspot/src/share/vm/runtime/thread.hpp --- a/hotspot/src/share/vm/runtime/thread.hpp Tue Jul 09 22:48:52 2013 +0200 +++ b/hotspot/src/share/vm/runtime/thread.hpp Wed Jul 10 15:49:15 2013 +0000 @@ -86,6 +86,8 @@ class ThreadClosure; class IdealGraphPrinter; +DEBUG_ONLY(class ResourceMark;) + class WorkerThread; // Class hierarchy @@ -531,6 +533,8 @@ // 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 @@ // 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 -r 9f928b94b877 -r ac0163dd0a50 hotspot/src/share/vm/utilities/ostream.cpp --- a/hotspot/src/share/vm/utilities/ostream.cpp Tue Jul 09 22:48:52 2013 +0200 +++ b/hotspot/src/share/vm/utilities/ostream.cpp Wed Jul 10 15:49:15 2013 +0000 @@ -296,6 +296,7 @@ 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 @@ 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 -r 9f928b94b877 -r ac0163dd0a50 hotspot/src/share/vm/utilities/ostream.hpp --- a/hotspot/src/share/vm/utilities/ostream.hpp Tue Jul 09 22:48:52 2013 +0200 +++ b/hotspot/src/share/vm/utilities/ostream.hpp Wed Jul 10 15:49:15 2013 +0000 @@ -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 @@ 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);