# String literal resolution in AOT-compiled code To get string literal by its identifier application has to perform special runtime call. To improve performance in AOT mode such runtime calls could be replaced with load from a special PLT-slot in AOT file. In that case compiled code loads a value from a slot associated with a string and checks if that value is valid pointer. If it's not then the application have to perform `ResolveStringAot` runtime call that will return a pointer. That runtime call may also save returned string pointer into the slot and subsequent executions of the same code will bypass runtime calls. ## Compiler support During AOT compilation `LoadString` instruction could be either encoded as regular `ResolveString` runtime call or as a PLT-slot check with `ResolveStringAot` runtime call as a fallback. To use the latter encoding the following conditions have to be met: - compiled method should not be a static class initializer (initializers get invoked only once and the first resolution attempt requires runtime call, so usage of regular `ResolveString` call reduces the overhead); - `--compiler-aot-load-string-plt` option should be turned on (it is on by default). If the condition is met then the compiler reserves a unique PLT-slot (with type `STRING_SLOT`) for the string and emits load from that slot, followed by the check that the loaded value is a valid pointer and the slow path. The slow path performs `ResolveStringAot` runtime call that returns resolved string. ## Runtime support There are two options controlling when and how many string will be saved into PLT-slots: - `--aot-string-gc-roots-limit` controls how many time the same string should be resolved before its pointer will be saved into the associated PLT-slot; - `--resolve-string-aot-threshold` controls how many strings could be save to PLT-slots (option applied to the whole application, not to a single AOT-file). `RuntimeStringAot` runtime call resolves the string as a regular `RuntimeString` call, but also does the following things: - checks the value already stored in `STRING_SLOT` PLT-slot - after AOT-file loading all such slots contain `0` and then each resolution attempt will increment value inside the slot until it either get replaced with a string pointer, or it reaches `PANDA_32BITS_HEAP_START_ADDRESS - 1` (after that invocations will not increment slot value); - if PLT-slot's value is already a pointer then the resolved string gets returned; - if amount of already filled PLT-slots is above `--resolve-string-aot-threshold` then the resolved string gets returned; - if PLT-slot's value is below `--aot-string-gc-roots-limit` then slot's value is incremented and the resolved string is returned; - if PLT-slot's value is above `--aot-string-gc-roots-limit` then slot's value is replaced by string pointer, slot is registered as GC-root in `AotManager` and the resolved string is returned. ## GC support String pointers stored inside PLT-slots have to be treated as GC-roots to prevent its scavenge in case there are no references to it. `AotManager` is responsible for storing PLT-slots containing references. It also provides methods to iterate over these slots in order to scan and update them. As an optimization `AotManager` stores information about whether or not the PLT-slot is referencing to an object in young space. That information allow to significantly reduce amount of scanned PLT-slots during young GC, but it also requires update during update phase. As yet another optimization PLT-slots are updated only if `StringTable` was updated during GC, because both these structures are referencing to the same string ( PLT-slots referencing a subset of strings references by the `StringTable`).