Request for review: 7034585 Adjust fillinStackTrace filtering to assist 6998871

Tom Rodriguez tom.rodriguez at oracle.com
Fri Apr 8 16:12:26 PDT 2011


On Apr 8, 2011, at 3:57 PM, David Holmes wrote:

> Hi Tom,
> 
> Tom Rodriguez said the following on 04/09/11 06:53:
>> Performance of fillInStackTrace is somewhat important so I think you should avoid using as_C_string since that creates a copy of both fillInStackTrace and the method being checked.  Maybe something like this:
>> const char* fillInStackTrace = "fillInStackTrace";
>> int len = 16;
>> assert(strlen(fillInStackTrace) == len, "must agree");
>> if (method->name()->starts_with(fillInStackTrace, 16) &&
>>    throwable->is_a(method->method_holder())) {
> 
> I hear you, but we shouldn't be hard-coding names like that - which is why we use the vmSymbols entry in the first place.

The reason we use the vmSymbols is so that we can do pointer compares.  An assert like this:

assert(strcmp(vmSymbols::fillInstackTrace()->as_C_string(), fillInStackTrace) == 0, "must be the same");

would mitigate your concern, though I think it's unlikely we will be changing the name fillInStackTrace any time soon.

> It's a pity symbols don't have a set of operators for comparing against other symbols etc. I'll poke a little deeper to see what impact as_C_string will have and whether there is a way to mitigate it - perhaps use the variant where I supply the buffer eg:
> 
>  char[] buf = ...
>  if (method->name()->starts_with(vmSymbols::fillInstackTrace()->as_C_string(buf), 16) { ...

It still seems like pointless work.  The name of the symbol is the value of the symbol so dynamically converting it to char* is just a waste.

tom

> 
> Thanks,
> David
> 
>> tom
>> On Apr 8, 2011, at 4:33 AM, David Holmes wrote:
>>> webrev:
>>> 
>>> http://cr.openjdk.java.net/~dholmes/7034585/webrev/
>>> 
>>> When an exception is created, fillInStacktrace is called to populate the backtrace information. This is done in java_lang_Throwable::fill_in_stack_trace in the VM. Because the interesting part of the stacktrace is from the location where the exception was created, and upwards, filtering is applied in fill_in_stack_trace to remove the entry for fillInStackTrace() itself, and the exception constructors.
>>> 
>>> The current filtering code only expects to find a single frame for the fillInStackTrace method, so if an exception class overrides fillInStackTrace (and invokes super.fillInStackTrace) this actually disables the filtering of the constructors. Eg we see:
>>> 
>>> Exception in thread "main" MyException
>>>       at MyException.fillInStackTrace(MyException.java:3)
>>>       at java.lang.Throwable.<init>(Throwable.java:260)
>>>       at java.lang.Exception.<init>(Exception.java:54)
>>>       at java.lang.RuntimeException.<init>(RuntimeException.java:51)
>>>       at MyException.<init>(MyException.java:1)
>>>       at MyException.main(MyException.java:7)
>>> 
>>> instead of:
>>> 
>>> Exception in thread "main" MyException
>>>       at MyException.main(MyException.java:7)
>>> 
>>> The changes to Throwable.java for 6998871 effectively introduce an additional fillInStackTrace() frame and so this too disables the desired filtering of the backtrace.
>>> 
>>> The proposal is quite simple: to modify fill_in_stack_trace so that it expects one or more fillInStackTrace frames, followed by zero or more constructor frames. This addresses the needs of 6998871 as well as fixing any user-defined overriding of fillInStackTrace.
>>> 
>>> Thanks,
>>> David



More information about the hotspot-runtime-dev mailing list