RFR (XS): 8167995: -Xlog:defaultmethods=debug: lengthy method descriptor triggers "StringStream is re-allocated with a different ResourceMark"
Rachel Protacio
rachel.protacio at oracle.com
Wed Oct 26 19:59:57 UTC 2016
Great! Thank you, David and Harold for the reviews. I'll commit.
Rachel
On 10/26/2016 3:33 PM, David Holmes wrote:
> Harold/Rachel,
>
> Thanks for clarifying things - I had misconstrued the actual problem.
>
> In summary we should not use a ResourceObj in the scope of a nested
> ResourceMark wrt. the allocation of the ResourceObj.
>
> The fix is good and no further changes are needed.
>
> Thanks,
> David
>
> On 26/10/2016 5:58 AM, harold seigel wrote:
>> Hi Rachel,
>>
>> I think that the ResourceMarks that you removed were the correct ones.
>> My understanding is that based on this assert it looks like all calls to
>> stringStream::write() on a particular Stream need to be done using the
>> same ResourceMark with which the Stream was created. Otherwise, this
>> assert in stringStream::write() will trigger:
>>
>> assert(rm == NULL || Thread::current()->current_resource_mark() ==
>> rm,
>> "StringStream is re-allocated with a different
>> ResourceMark..." ...)
>>
>> These two ResourceMarks needed to be removed because their outputStream
>> was constructed with a caller's ResourceMark. If they specified their
>> own ResourceMark then their calls to print(), which eventually calls
>> stringStream::write(), would cause the assert to trigger.
>>
>> static void print_slot(outputStream* str, Symbol* name, Symbol*
>> signature) {
>> ResourceMark rm;
>> str->print("%s%s", name->as_C_string(), signature->as_C_string());
>> }
>>
>> static void print_method(outputStream* str, Method* mo, bool
>> with_class=true) {
>> ResourceMark rm;
>> if (with_class) {
>> str->print("%s.", mo->klass_name()->as_C_string());
>> }
>> print_slot(str, mo->name(), mo->signature());
>> }
>>
>>
>>
>> I think that having a ResourceMark in code like this is okay because
>> debug_stream() probably constructs a new Stream object.
>>
>> if (log_is_enabled(Debug, defaultmethods)) {
>> log_debug(defaultmethods)("Slots that need filling:");
>> ResourceMark rm;
>> outputStream* logstream = Log(defaultmethods)::debug_stream();
>> streamIndentor si(logstream);
>> for (int i = 0; i < slots->length(); ++i) {
>> logstream->indent();
>> slots->at(i)->print_on(logstream);
>> logstream->cr();
>> }
>> }
>>
>> Harold
>>
>>
>> On 10/25/2016 11:14 AM, Rachel Protacio wrote:
>>> Hi,
>>>
>>> Thanks for taking a look. I think in this particular case the issue
>>> was that the nested ResourceMark's were around code that affected an
>>> existing outputStream. So in fact the nesting per se isn't what was
>>> wrong, the issue was adding a ResourceMark in the middle of a resource
>>> that still needed the content after it went out of scope of the RM. So
>>> line 796 is good because its functionality is self-contained, and the
>>> ones I deleted were bad because they interfered with the functionality
>>> of the caller code. (Can someone corroborate this assessment?)
>>>
>>> However, as those functions still need RMs in general somewhere up the
>>> line, I can add a comment of the form
>>>
>>> // The caller of print_slot() (or one of its callers)
>>> // must use a ResourceMark in order to correctly free the result.
>>>
>>> for print_slot(), print_method(), and print_on() at line 590. Does
>>> that sound good?
>>> Rachel
>>>
>>> On 10/25/2016 1:41 AM, David Holmes wrote:
>>>> Hi Rachel,
>>>>
>>>> On 25/10/2016 6:17 AM, Rachel Protacio wrote:
>>>>> Hi,
>>>>>
>>>>> Please review this small fix, which removes two nested ResourceMark's
>>>>> that were causing problems with defaultmethods logging.
>>>>>
>>>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8167995
>>>>> Open webrev: http://cr.openjdk.java.net/~rprotacio/8167995.00/
>>>>>
>>>>> Tested with JPRT.
>>>>
>>>> It is tricky to determine who has responsibility for positioning the
>>>> ResourceMarks. Looking at this call chain it initially appeared to me
>>>> that we now had a missing RM for the code at line #80:
>>>>
>>>> 813 slot->print_on(logstream);
>>>> =>
>>>> 590 void print_on(outputStream* str) const {
>>>> 591 print_slot(str, name(), signature());
>>>> 592 }
>>>> =>
>>>> 79 static void print_slot(outputStream* str, Symbol* name, Symbol*
>>>> signature) {
>>>> 80 str->print("%s%s", name->as_C_string(),
>>>> signature->as_C_string());
>>>> 81 }
>>>>
>>>> but we actually have a RM higher up at:
>>>>
>>>> 787 ResourceMark rm(THREAD);
>>>>
>>>> so that is good, but then we also have a nested ResourceMark further
>>>> down:
>>>>
>>>> 795 if (log_is_enabled(Debug, defaultmethods)) {
>>>> 796 ResourceMark rm;
>>>>
>>>> I must admit I'm unclear if ResourceMarks should never be nested, or
>>>> should be nested "carefully" - and if the latter exactly what that
>>>> means and how to recognize it.
>>>>
>>>> Thanks,
>>>> David
>>>> -----
>>>>
>>>>> Thanks!
>>>>> Rachel
>>>
>>
More information about the hotspot-runtime-dev
mailing list