on javac flags
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Mon Oct 1 11:49:49 UTC 2018
This comment makes a lot of sense Jon. I believe the first thing to do
here is to explore some of the use cases of the existing flags, and
devise an API that would cover them effectively; then come up with a way
to implement this API, whether it's backed by booleans, enum sets or
longs, that's something to be decided at a later stage.
Thanks
Maurizio
On 26/09/18 21:15, Jonathan Gibbons wrote:
> Maurizio,
>
> I think it would also be good to separate the storage from the API, to
> provide
> concise usage within the javac codebase.
>
> For example,
> sym.hasFlag(Flag.STATIC)
> sym.setFlag(Flag.PUBLIC)
> etc
>
> as compared to
> (sym.flags() & STATIC) != 0
> sym.flags |= STATIC;
>
> If you get the API right, maybe as a first step, it would then be
> easier to tweak
> the implementation later on as needed.
>
> -- Jon
>
>
> On 09/26/2018 01:06 PM, Maurizio Cimadamore wrote:
>> Hi Bernard,
>> your solution is clever, but now a symbol has an array of N elements
>> - which makes it completely unfeasible from a memory footprint
>> perspective. Although maybe the core of what you are suggesting is -
>> just use a custom data structure, e.g. something like an immutable
>> bitset, so that we can share common combinations, etc.
>>
>> Maurizio
>>
>> On 26/09/18 20:26, B. Blaser wrote:
>>> Hi Maurizio,
>>>
>>> On Wed, 26 Sep 2018 at 16:17, Maurizio Cimadamore
>>> <maurizio.cimadamore at oracle.com> wrote:
>>>> Hi,
>>>> In javac we have a Flags class which is used to define a list of
>>>> all the
>>>> flags that are used, both internally (i.e. javac private flags) and
>>>> externally (i.e ACC_ flags). The assumption is that external flags are
>>>> 16-bit wide, while internal flags are all values above 2^16 (_which
>>>> can
>>>> fit in a long_).
>>>>
>>>> There are several issues with the current handling of flags:
>>>> [...]
>>>> * checking presence/absence of flags is very tedious; we have many
>>>> many
>>>> occurrences (600+) of C-like code like:
>>>>
>>>> if ((sym.flags() & STATIC) == 0 && ...
>>>>
>>>> or
>>>>
>>>> (sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) { ... }
>>>>
>>>> [...]
>>>> Where does this leave us? I think with these optimizations the memory
>>>> footprint should be relatively contained - we are essentially
>>>> trading a
>>>> 64-bit value (long flag) with a 64 bit pointer which might or might
>>>> not
>>>> point to a fresh new object (if not, no extra cost). Of course this
>>>> all
>>>> needed to be validated with some real world profiling/JMH
>>>> benchmark, but
>>>> seems like a direction worth exploring.
>>>>
>>>> Thoughts?
>>> I'm afraid that
>>>
>>> if (!sym.flags().contains(Flag.STATIC) && ...
>>>
>>> would be also tedious, somewhat slow and probably expensive in term of
>>> memory usage...
>>>
>>> I guess I'd be more for something like:
>>>
>>> $ cat OnFlags.java
>>> class OnFlags {
>>> static enum Flag {
>>> PUBLIC(0, 0x1), PRIVATE(1, 0x2), INTERNAL(2, 0x0);
>>>
>>> int index;
>>> int mask; // maybe 'short' would be enough
>>>
>>> Flag(int index, int mask) {
>>> this.index = index;
>>> this.mask = mask;
>>> }
>>> }
>>>
>>> static class Symbol {
>>> boolean[] flags = new boolean[Flag.values().length];
>>> }
>>>
>>> public static void main(String... args) {
>>> var sym = new Symbol();
>>> sym.flags[Flag.PUBLIC.index] = true;
>>> sym.flags[Flag.INTERNAL.index] = true;
>>>
>>> int jvmFlags = 0;
>>> for (Flag f: Flag.values())
>>> if (sym.flags[f.index])
>>> jvmFlags |= f.mask;
>>>
>>> for (Flag f: Flag.values())
>>> System.out.println(f + ": " + sym.flags[f.index]);
>>>
>>> System.out.println("jvm flags " + jvmFlags);
>>> }
>>> }
>>>
>>> No difference between corresponding internal and external flags, so no
>>> mapping would be necessary.
>>>
>>> Testing a flag would be as fast as simple without much extra memory
>>> cost:
>>>
>>> if (!sym.flags[Flag.STATIC.index] && ...
>>>
>>> Computing the jvm external flag would be also straightforward:
>>>
>>> int jvmFlags = 0;
>>> for (Flag f: Flag.values())
>>> if (sym.flags[f.index])
>>> jvmFlags |= f.mask;
>>>
>>> Opinions?
>>>
>>> Bernard
>>>
>>>> Maurizio
>>
>
More information about the compiler-dev
mailing list