Static fields are represented as two arrays in the native image heap: one for Object fields and
one for all primitive fields. The byte-offset into these arrays is stored in
SharedField.getLocation().
Implementation notes: The arrays are created after static analysis, but before compilation. We
need to know how many static fields are reachable in order to compute the appropriate size for
the arrays, which is only available after static analysis.
When bytecode is parsed before static analysis, the arrays are not available yet. Therefore, the
accessor functions StaticFieldsSupport.getStaticObjectFields()} and StaticFieldsSupport.getStaticPrimitiveFields() are
intrinsified to a StaticFieldBaseNode, which is then during compilation lowered to the
constant arrays. This also solves memory graph problems in the Graal compiler: Direct
loads/stores using the arrays, for example via Unsafe or VarHandle, alias with static field
loads/stores that have dedicated LocationIdentity. If the arrays are already exposed in
the high-level optimization phases of Graal, the compiler would miss the alias since the location
identities for arrays are considered non-aliasing with location identities for fields. Replacing
the StaticFieldBaseNode with a ConstantNode only in the low tier of the compiler
solves this problem.