on javac flags
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Wed Sep 26 20:06:09 UTC 2018
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