> `acmp` for value object might be expensive: it may need substitutability > test, which is done through a Java call. That is the last resort when > everything failed, that is: we are in the presence of two value objects of > the same class, not statically known or speculated (profile absent or > polluted). While a lot of the acmp logic is trying to improve acmp at > compile-time, this change proposes a runtime check to take a fast path. > > The idea is that if the object is small enough, we can read all the fields at > once with a single 8-byte load, we exclude the non-interesting bits with a > mask, and we can simply compare the masked value from both objects. > > The first step happens at class loading. When the class is loaded, we check > whether all the fields can be read at once, from which offset, and the mask > to filter out useless bits. Useless bits may have two sources: > - padding between fields > - header: this happens because we cannot necessarily start reading at > `payload_offset`, the payload might be smaller than a long, and we could > overread. On the other hand, the header is always long enough (never less > than 8 bytes), so we may read from somewhere in the header to make sure we > don't go further than the payload. This piece of header must be filtered out. > > This strategy may not apply if the object is too big, or if it contains an > oop. Loading oop without precaution, concurrently with the GC is not a good > idea. This limitation is rather harmless: this fast path is mostly made not > to pay the price of a complicated `acmp` for magically migrated classes (such > as `Integer`), which are small and don't contain oops. > > There is an interesting corner case: the mask can be 0 for an empty value > class. We use a negative offset to signal that the fast path doesn't apply, > since it is not a valid value for the offset: we shouldn't load before the > object. > > The second step is to prepare the runtime check. In `do_acmp`, when we used > to prepare the Java call, now we have a parallel fast path. The condition > uses the fact that we already have the class node available (used for > checking operands have the same types). We can get the fast acmp offset from > the class, check if it looks valid (that is non-negative), and if so, take > the fast path that will load the mask, do the two loads and masking, and > compare the given values. If the class of the operand is known precisely at > parsing, we don't emit the fast path since the call will be nicely > intrinsified. > > The third step is to prevent the fast ...
Marc Chevalier has updated the pull request incrementally with six additional commits since the last revision: - Printing is gone again - Remove the old way - Fix asserts - Let new version do the job - Flag + using _layout_info - Printing is back ------------- Changes: - all: https://git.openjdk.org/valhalla/pull/2353/files - new: https://git.openjdk.org/valhalla/pull/2353/files/05cc91d6..51ffe9d9 Webrevs: - full: https://webrevs.openjdk.org/?repo=valhalla&pr=2353&range=04 - incr: https://webrevs.openjdk.org/?repo=valhalla&pr=2353&range=03-04 Stats: 198 lines in 6 files changed: 121 ins; 41 del; 36 mod Patch: https://git.openjdk.org/valhalla/pull/2353.diff Fetch: git fetch https://git.openjdk.org/valhalla.git pull/2353/head:pull/2353 PR: https://git.openjdk.org/valhalla/pull/2353
