on javac flags
B. Blaser
bsrbnd at gmail.com
Wed Sep 26 19:26:15 UTC 2018
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