On Wed, 7 Jun 2023 00:10:59 GMT, Paul Sandoz <psan...@openjdk.org> wrote:
>>> I believe instead of changing the guards we can change the implementation >>> of the static methods on the concrete static VHs to call `asDirect()` (lets >>> also add `@ForceInline` on `asDirect`), since `linkToStatic` will pass the >>> args to the static method described by the member name (since the lazy and >>> direct VH handles share the same var form). >>> >>> That has the nice effect of pushing the complexity closer to where it is >>> needed. Its subtle but i think can be explained. Thereby we can reduce the >>> memory footprint for subsequent access modes. Perhaps we can even "zero" >>> out the MH cache on initialization? >> >> Is this aimed at decreasing long-term invocation cost or the initial >> invocation cost? FYI long-term invocation is already efficient enough; if >> this is for initial invocation, which can potentially bypass costly MH >> construction, I recommend creating an alternative method to `asDirect` for >> the purpose to be called and casted by X-VarHandle implementations. > >> Is this aimed at decreasing long-term invocation cost or the initial >> invocation cost? FYI long-term invocation is already efficient enough; if >> this is for initial invocation, which can potentially bypass costly MH >> construction, I recommend creating an alternative method to `asDirect` for >> the purpose to be called and casted by X-VarHandle implementations. > > It aims to reduce the cost of getting to peak performance (the work that C2 > has to perform) and reduce the overall memory footprint of such VHs (as long > as the user does not explicitly request MHs from them). Assuming of course > that the peak performance is good! > > For this pattern i not sure we need to create another method returning the > target that effectively does the same as `asDirect`, and instead it may come > down to better naming and documentation of the concepts. > > There is already a tight coupling between the `LazyInitializingVarHandle` and > its target via the sharing of the var forms. Renaming `asDirect` to `target` > might do it, and we refine a what a direct handle is to mean the guards just > pass along the handle that is given to it, otherwise we use a (lazily > created) method handle to its target. Thereby a VH implementation free to > switch between indirect and direct and is further free to deal with any > implementation specific indirection in its own implementation. > @PaulSandoz Thank you for your suggestion! It might be harder to measure the > time to get to peak performance, but at least for the initial invocation, the > lazy VH is almost no different from the eager VH now. The old overhead was > mostly from LambdaForm spinning, same for the lazy DMH overhead. Ok, i did not mean to suggest measuring time to peak performance, it's hard as you say. I was more thinking of an intuitive understanding of the cost (work performed by C2 and runtime memory footprint). > Is this what you've envisioned? Close, I was suggesting the following: - `LazyInitializingVarHandle::target` just returns `target` and does not call `ensureInitialized`. - Override `checkAccessModeThenIsDirect` as you did before, but returns `initialized`. - Change only the static field var handle implementations to call `target()`, since it is unnecessary on the others. However, i think your approach is better as it avoids any implicit MH creation. Suggest refining as follows: - Change only the static field var handle implementations to call `target()`, since it is unnecessary on the others. - Split `ensureInitialized` in two: @ForceInline private void ensureInitialized() { if (this.initialized) return; initialize(); } private void initialize() { UNSAFE.ensureClassInitialized(refc); this.initialized = true; ... } I am wondering if the simplest approach in `initialize` is to set the `methodHandleTable` to null? ------------- PR Comment: https://git.openjdk.org/jdk/pull/13821#issuecomment-1581461851