On 8 Oct 2024, at 14:47, Ioi Lam wrote: > On Wed, 25 Sep 2024 17:14:54 GMT, Chen Liang <li...@openjdk.org> wrote: > >>> 402: MethodType primordialMT = new MethodType(rtype, ptypes); >>> 403: if (AOTHolder.archivedMethodTypes != null) { >>> 404: MethodType mt = >>> AOTHolder.archivedMethodTypes.get(primordialMT); >> >> Can we populate these AOT MTs into the internTable so we only look up once? > > There's a trade off here -- > start-up will be slowed down if the archivedMethodTypes table is big. Also, > `internTable` uses more memory as it wraps every entry inside a weak > reference.
I think there is a design pattern should be thinking about, which I have been calling the “Three Table Solution”. (And there might be just Two Tables.) The runtime table is the existing intern table with its weak references. It is designed for fast queries, fast updates, and good relations with the GC. It does not have the best possible footprint. The AOT table is archivedMethodTypes. It is designed for compactness, fast static boot-up, and reasonably fast queries. It is read-only. (It is permitted to have slower queries, such as in a log N tree instead of O(1) hash table, but if that is the case then entries should be migrated into the main runtime table as they are extracted.) A third table, maybe, is the startup table; it collects entries at startup before the big main runtime table can be created. It might also serve instead of the runtime table during the assembly phase. Its main property is simplicity, meaning lack of complex init-dependencies on the rest of the JDK. It does not need weak refs, or any other kind of scalability, because it will be quickly retired when the system boots up. In fact, the AOT table is likely to fulfill all early queries, so the startup table is probably empty, as long as an AOT cache is available. The startup table might be useful for exploded builds, as well as for the assembly phase. Note that while the startup table exists, the main runtime table is not yet created; its static reference is null. (It should be a @Stable field!) That third table is not very useful if we can figure out how to use the main runtime table (with its weak refs) at all init phases. So maybe this design pattern is the Two Table Solution, if we can tame weak refs for Leyden. But I do think we have a long-term need for two tables, with an AOT one optimized for fast boot-up and compactness (and slow to create, and not mutated during startup). The order of operations could be: A. check AOT table; if present, return B. check main table or startup table; if present, return C. make new object, install in appropriate table, return But in some cases it is better to always check the main table first, if it exists. (A @Stable reference will make the query method inline, after the JIT gets ahold of the object.) Like this: A. check main table; if present, return B. check AOT table or startup table B1. if present, and if main table exists, move to main table B2. if present, then return C. make new object, install in appropriate table, return > PR Review Comment: > https://git.openjdk.org/jdk/pull/21143#discussion_r1782292378