RFR (L) JDK-8231844: Enhance type signature characters in classfile_constants.h and improve the JVM to use type signature characters more consistently

Lois Foltan lois.foltan at oracle.com
Fri Oct 11 19:36:52 UTC 2019


On 10/10/2019 9:15 PM, David Holmes wrote:
> Hi Lois,
>
> On 11/10/2019 3:30 am, Lois Foltan wrote:
>> On 10/9/2019 8:14 PM, David Holmes wrote:
>>> Hi Lois,
>>>
>>> On 10/10/2019 7:18 am, Lois Foltan wrote:
>>>> Please review this enhancement to consistently use the 
>>>> JVM_SIGNATURE_* constants for type signature processing.  This 
>>>> change is a precursor to JDK-8230199: consolidate signature parsing 
>>>> in Hotspot sources.
>>>>
>>>> open webrev 
>>>> at:http://cr.openjdk.java.net/~lfoltan/bug_jdk8231844.0/webrev/ 
>>>> <http://cr.openjdk.java.net/~lfoltan/bug_jdk8231844.0/webrev/>
>>>> bug link: https://bugs.openjdk.java.net/browse/JDK-8231844
>>>> contributed-by: Lois Foltan, John Rose
>>>
>>> In general the change is good - special characters should be 
>>> referred to by symbolic names to give more semantic context where 
>>> practical.
>>
>> Thanks David for the review!  See my comments below.  New webrev at:
>>
>> http://cr.openjdk.java.net/~lfoltan/bug_jdk8231844.1/webrev/
>
> Updated look good - thanks.
>
> Follow up comments way below ...
>
>>>
>>> However I do have a few comments.
>>>
>>> It seems redundant and somewhat counter to the fix to change a 
>>> character in the code to a symbolic constant but then have a comment 
>>> still use the original character. Sometimes this seems acceptable as 
>>> it helps clarity e.g.
>>>
>>>     // Ignore wrapping L and ;
>>> !   if (name[0] == JVM_SIGNATURE_CLASS) {
>>>
>>> but in particular I found the comments here unnecessary:
>>>
>>> src/hotspot/share/utilities/globalDefinitions.cpp
>>>
>>>  // Map BasicType to signature character
>>> ! char type2char_tab[T_CONFLICT+1] = {
>>> !   0, 0, 0, 0,
>>> !   JVM_SIGNATURE_BOOLEAN, JVM_SIGNATURE_CHAR,    // 4:  'Z', 'C'
>>> !   JVM_SIGNATURE_FLOAT,   JVM_SIGNATURE_DOUBLE,  //     'F', 'D'
>>> !   JVM_SIGNATURE_BYTE,    JVM_SIGNATURE_SHORT,   // 8:  'B', 'S'
>>> !   JVM_SIGNATURE_INT,     JVM_SIGNATURE_LONG,    //     'I', 'J'
>>> !   JVM_SIGNATURE_CLASS,   JVM_SIGNATURE_ARRAY,   // 12: 'L', '['
>>> !   JVM_SIGNATURE_VOID,    0,                     //     'V'
>>> !   0, 0, 0, 0
>>> ! };
>>>
>>> other cases could go either way.
>>
>> Fixed this in utilities/globalDefinitions.cpp and another instance in 
>> src/hotspot/share/runtime/fieldType.cpp where the comments seemed 
>> redundant.
>>
>>>
>>> ---
>>>
>>> src/java.base/share/native/include/classfile_constants.h.template
>>>
>>> +     JVM_SIGNATURE_ENDPACKAGE    = '/',
>>> +     JVM_SIGNATURE_ENDPACKAGE_DOT = '.',
>>>
>>> These constants bothered me both because of their very long names 
>>> and because the names aren't completely accurate. They both indicate 
>>> separators between identifiers: one for internal form, and one for 
>>> external form. The / doesn't "end a package" and . can be part of a 
>>> nested type name, unrelated to packages. As these characters do not 
>>> have a unique semantic usage that is easily expressed, perhaps 
>>> referring to them as just:
>>>
>>> JVM_SIGNATURE_SLASH
>>> JVM_SIGNATURE_DOT
>>>
>>> would suffice?
>>
>> I agree, changed.
>>
>>>
>>> ---
>>>
>>> src/hotspot/share/c1/c1_InstructionPrinter.cpp
>>>
>>> Should type2name really handle all cases and assert if an invalid 
>>> type, and return "???" (or perhaps "<unknown>") in product mode?
>>
>> A new RFE should be created for addressing how type2name should 
>> handle an invalid type since it is used quite frequently throughout 
>> the JVM. It is not in the scope of this RFE to change the behavior of 
>> type2name. It was the goal to reduce the use of hard coded characters 
>> and/or strings when dealing with types and type signatures which is 
>> what the use of type2name does in InstructionPrinter::basic_type_name().
>
> Agree this is out of scope.
>
>>>
>>> ---
>>>
>>> src/hotspot/share/utilities/globalDefinitions.hpp
>>>
>>> I do not like this new method:
>>>
>>> +inline BasicType primitive_or_object(BasicType t) {
>>> +  assert(is_java_type(t), "%d", (int)t);
>>> +  return (is_reference_type(t) ? T_OBJECT : t);
>>> +}
>>>
>>> I found it's use in the code was far less clear than the original 
>>> code. I like to explicitly see where arrays and objects are being 
>>> treated the same (or differently).
>>
>> This is in line with the change that I recently completed for 
>> JDK-8230505: Replace JVM type comparisons to T_OBJECT and T_ARRAY 
>> with call to is_reference_type.  Please refer to John's response to 
>> Coleen's review comment that I believe addresses your concern as 
>> well. 
>> https://mail.openjdk.java.net/pipermail/hotspot-dev/2019-September/039486.html 
>
>
> I can't say that I agree. A simple query like is_reference_type() is 
> perfectly fine. But reducing all reference types to just T_OBJECT is 
> something that, to me, needs to be consciously chosen when a new 
> reference type is added. This approach could hide bugs as it will be 
> easy to miss locations that might new to handle the new reference type 
> differently. Just my 2c.

Thanks David for your 2c.  Based on your and Fred's feedback I have 
posted a new webrev without the change to primitive_or_object() since 
more discussion is needed.  See new webrev link in my reply to Fred.

Lois

>
> Thanks,
> David
>
>>
>> Thanks,
>> Lois
>>
>>>
>>> Thanks,
>>> David
>>> -----
>>>
>>>> Testing: hs-tier1-3, jdk-tier1-2 (all platforms).  hs-tier4-6 
>>>> (linux only)
>>>>
>>>> Thanks,
>>>> Lois
>>



More information about the hotspot-dev mailing list