Concept of range sizes is artificial and sometimes over-approximated
as it doesn't match representations used in IL instructions.
It is replaced by "full range" derived from representation.
Also, this change removes a bit of Smi-specific logic which cannot be
extended for arbitrary integers.
TEST=ci
Change-Id: Ifc3092b13e4655cd5790d39d3fb88bd9b40ba484
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/396481
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
SpeculattiveShiftInt64Op and SpeculativeShiftUint32Op instructions are
only used in JIT. The only advantage of these instructions over
non-speculative shifts is that they can be hoisted out of the loops
in more cases. However, speculative instructions can suffer from deopt
storm, introduce unnecessary differences in IL and generated code
between JIT and AOT and add sufficient amount of extra code to maintain.
TEST=ci
Change-Id: I689e44b54832e2af76cbc99b9fc4bc937b9f2c87
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/394566
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Previously, ComparisonInstr base class represented arbitrary conditions
used in Branch, IfThenElse and CheckCondition instructions and included
subclasses TestInt, TestCids, TestRange and unary DoubleTestOp which are
not comparisons. So this refactoring renames ComparisonInstr to
ConditionInstr.
In addition, a new Comparison instruction is added as a base class for
StrictCompare, EqualityCompare and RelationalOp.
TEST=ci (pure refactoring)
Change-Id: Ic8756ee5913ff2bc974c95cea8004370c9f5527f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/393420
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
UnboxedInt32 representation is no longer speculative, so
all speculative int32 range checks are removed from Unbox and
IntConverter instructions. Unbox and IntConverter instructions
are now always truncating. IntConverter cannot deoptimize.
TEST=ci
Change-Id: Ie9a83e055e8b8372859b0721ac6fbcf73da39ab8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/392740
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
All inputs of IL instructions are now non-speculative,
SelectRepresentations pass now always inserts non-speculative
unboxing instructions.
In call specializer, where JIT compiler speculates, speculative Unbox
instructions are now explicitly added for inputs which may have
incorrect type. Unbox instructions now have 'value_mode' (either
kHasValidType or kCheckType) instead of speculative mode.
Added canonicalization rule to change value mode if
compiler can prove that value has correct type.
Also, cleaned up speculations around UnboxedInt32 representation in
JIT mode, which aligns this representation with other unboxed
representations.
TEST=ci
Change-Id: I52f5c959c3f6515b1a7c9e8ab15b420beed0e3f5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/391492
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Canonicalization
v1 <- comparison(...)
Branch if (StrictCompare(===, v1, true))
=>
Branch if (comparison(...)
was not applied if comparison has unmatched representations.
However, checking for unmatched representations matters only
if comparison is speculative (in JIT mode).
Fixing this canonicalization rule improves range analysis in AOT.
As a result, range analysis can eliminate bounds check in a loop when
iterating over list using its iterator.
Also, add useful tracing to bounds check elimination code
under --trace_range_analysis.
In addition, BranchInstr::SpeculativeModeOfInput is fixed -
it should delegate to its comparison instead of returning
kGuardInputs default in order to support non-speculative
comparisons folded into branch.
Also, EqualityCompare canonicalization is now applied to
BranchInstr comparison, in order to keep optimizations which
were applied when EqualityCompare was not folded into
branches.
TEST=runtime/tests/vm/dart/regress_56807_il_test.dart
Fixes https://github.com/dart-lang/sdk/issues/56807
Change-Id: Ib69294d7ccf30b63dd3ff7ae5a47c0a238824952
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/387622
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
* Infer range for CheckArrayBound and GenericCheckBound instructions.
* Extend Constraint instruction to non-Smi values bounded by list
length.
* Unwrap UnboxInt64 during canonicalization of range boundaries.
* Use symbolic range for UnboxInt64 of list length.
As a result, bounds check can be eliminated in a loop over a growable
list:
```
for (int i = 0; i < a.length; ++i) {
final value = a[i];
...
}
```
TEST=runtime/tests/vm/dart/regress_56726_il_test.dart
Fixes https://github.com/dart-lang/sdk/issues/56726
Change-Id: Ic56df18f6fbf26abf91d6ecbff24d68678dccb60
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/386522
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Now Slots have an extra flag that describes whether or not the
instance object for that Slot is tagged (Dart objects) or untagged
(non-Dart objects like Thread).
Add new Slot categories for Slots with untagged instances, based on
the return value of the Slot:
* a tagged value (e.g., the finalizers_ field of Isolate),
* an untagged value (e.g., the isolate_ field of Thread), or
* an unboxed value (e.g., the enabled_ field of StreamInfo).
The primary difference in the specification of slots for untagged
instances vs tagged instances is that the slots for untagged instances
do not include an underlying type (as only Dart objects have an
Untagged<X> for each <X> class that specifies the actual object layout).
Also do a little more refactoring of Slot categories to simplify
some switch statements that now only need to be updated if the
categories the switch statement deals with change. For example,
methods for range analysis are only interested in Slots that are
guaranteed to contain integers, so now those methods are written in
a way that they only need to be updated if a new tagged integer
Slot declaration is added.
Adjust LoadFromSlot, StoreToSlot, and StoreToSlotNoBarrier to
appropriately handle Slots on untagged instances, and change
LoadField and StoreField's RequiredInputRepresentation methods
to appropriately returned kTagged or kUntagged based on the slot.
TEST=ci
Cq-Include-Trybots: luci.dart.try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-x64-try,vm-checked-mac-release-arm64-try,vm-eager-optimization-linux-release-ia32-try,vm-eager-optimization-linux-release-x64-try,vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64c-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-linux-debug-ia32-try,vm-linux-debug-x64c-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-ubsan-linux-release-x64-try,vm-win-debug-arm64-try,vm-win-debug-x64-try,vm-win-release-ia32-try
Change-Id: Ic27de4f092c9e087486066459f68a82b4e1685b0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/357341
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This is a reland of commit d24b5d1f5e
On top of the original change, the following is fixed and improved:
1) Flow graph builder (FGB) body is now also applied to
dynamic invocation forwarders (similarly to graph
intrinsics).
2) Frame can be omitted for functions which have a
call on a shared slow path. This is needed to make
FGB implementation of GetIndexed frameless, as it has
GenericCheckBound which calls on shared slow path.
(Graph intrinsics are frameless).
3) Range analysis is enabled for force-optimized functions,
so more efficient code can be generated for boxing
instructions. Range analysis is fixed to avoid crashes
and correctly intersect ranges with constant boundaries
(needed for some force-optimized FFI functions).
4) EliminateStackOverflowChecks pass is enabled for
force-optimized functions so CheckStackOverflow can be
eliminated.
Original change's description:
> [vm] Replace array GetIndexed graph intrinsics with flow graph builder implementation
>
> _Array, _GrowableList, internal and external typed data 'operator []'
> are now implemented in the flow graph builder.
>
> Unlike graph intrinsics, flow graph created in the flow graph builder
> can be used by the inliner. Corresponding graph intrinsics and native
> methods are removed.
>
> Also, this change adds missing external typed data indexing operations.
>
> TEST=ci
>
> Change-Id: Ic19784481feadf54c096a587413e67b4e18353dc
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/359940
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
> Commit-Queue: Alexander Markov <alexmarkov@google.com>
TEST=ci
Change-Id: I04ef008a04238d432683d7543cd047e35bad17c3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/360560
Reviewed-by: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This change removes support for external strings from the VM along with
Dart_NewExternalLatin1String, Dart_NewExternalUTF16String and
Dart_IsExternalString Dart C API functions.
External strings are not used by the VM nor any known embedder, but
Dart VM was paying the maintenance and performance price for
the external string implementation classes.
TEST=ci
Change-Id: I094cd2d2b7ec0840e9f09e1ca9e5a7acd4e78c28
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/358760
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Moves RepresentationOfArrayElement out of LoadIndexed and StoreIndexed
into RepresentationUtils. Adjusts RepresentationOfArrayElement
to work for all concrete typed data classes. Changes
RepresentationOfArrayElement to return the precise representation of
the array element, which requires adding two new representations,
kUnboxedInt8 and kUnboxedInt16.
Remove Address::OperandSizeFor and its only (ignored) use in the
RISCV assembler and change Address::OperandSizeFor in the ARM and
ARM64 assemblers to use RepresentationUtils::OperandSize and RepresentationUtils::RepresentationOfArrayElement appropriately.
Add Boxing::NativeRepresentation, which converts representations for
unboxed integers smaller than 4 bytes to kUnboxedIntPtr and otherwise
returns the original representation. This mimics the current semantics
for LoadIndexed and StoreIndexed where returned values represented by
unboxed integer values smaller than 4 bytes are zero or sign extended
to word size appropriately, and received values represented by unboxed
integer values smaller than 4 bytes are appropriately truncated from a
word sized signed integer.
Create LoadIndexedInstr::ReturnRepresentation and
StoreIndexedInstr::ValueRepresentation, which use
Boxing::NativeRepresentation to convert the precise representation
returned by RepresentationUtils::RepresentationOfArrayElement to
the actual returned/expected representation for those instructions.
Also use Boxing::NativeRepresentation to appropriately adjust
the representations used for SIMD operations returning int8_t.
Add checks that unboxing and integer conversion never get
representations which result in a different representation when
passed to Boxing::NativeRepresentation, as those instructions do
not currently work with unboxed integer representations smaller than
4 bytes. (Adding such support can be done in a future CL.)
Inside the optimizing compiler, use the precise representation of the
array element where appropriate. That is:
* Range analysis
* Type propagation
* Redundancy elimination
This CL also cleans up how Representations are printed to C, making
that part of RepresentationUtils. It also removes the representation
printing and parsing utils from Location since they were only used by
the original IL serializer and deserializer, which has been removed.
It also renames RepresentationUtils::IsUnsigned to IsUnsignedInteger,
to make it clear that it only returns true for unboxed integer
representations.
TEST=standalone/bytedata_test
Fixes: https://github.com/dart-lang/sdk/issues/54622
Cq-Include-Trybots: luci.dart.try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-aot-win-debug-x64-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-x64-try,vm-checked-mac-release-arm64-try,vm-eager-optimization-linux-release-ia32-try,vm-eager-optimization-linux-release-x64-try,vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64c-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-fuchsia-release-x64-try,vm-linux-debug-ia32-try,vm-linux-debug-x64-try,vm-linux-debug-x64c-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-ubsan-linux-release-x64-try,vm-win-debug-arm64-try,vm-win-debug-x64-try,vm-win-release-ia32-try
Change-Id: I8c0dab911463ee4d0c55cd59ffea9d01e0f0bb7c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/354885
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
Since we already cache instantiation of type argument vectors to avoid
runtime calls as long as the cache has room, remove the default
type arguments field from Closure objects. Instead, just perform any
needed instantiation when the default type arguments are needed
using the instantiator and parent function type arguments stored
in the closure.
Also rename DefaultTypeArgumentsKind to InstantiationMode and
generalize the calculations to determine how to instantiate default
type arguments to an operation that can be performed on type arguments
in general.
TEST=ci
Fixes: https://github.com/dart-lang/sdk/issues/54589
Issue: https://github.com/dart-lang/sdk/issues/54564
Change-Id: I704ea4244fb10cbc08175629c8e92cf05b8aabea
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-release-arm64-try,vm-aot-linux-release-x64-try,vm-aot-tsan-linux-release-x64-try,vm-tsan-linux-release-x64-try,vm-aot-linux-debug-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/346021
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Previously, the default type arguments for closure functions were
instantiated in the same way as other types of functions, where the
instantiator and function type arguments of the call were used. However,
the defaults for closure functions should be instantiated with the
instantiator and parent function type arguments stored within the
closure itself.
Since the instantiation of the default type arguments only depends on
the instantiator and parent function type arguments, which are shared
between partial instantiations of the same generic closure, the VM
performs this instantiation once at closure creation and caches it in
the closure object, so it can be retrieved when the default type
arguments are needed and copied to new partial instantiations of the
same closure without need for recalculation.
As a side effect, this should speed up dynamic invocation of generic
closures, since the invoke field dispatcher that implements them
previously performed this instantiation when needed on every invocation,
but now it just retrieves the cached version instead.
TEST=language/closure/type_arguments vm/dart/regress_54426
Fixes: https://github.com/dart-lang/sdk/issues/54426
Change-Id: I9baad807befa0323f3c5b66196b9664e4d78af0a
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-release-x64-try,vm-reload-linux-release-x64-try,vm-reload-rollback-linux-release-x64-try,vm-tsan-linux-release-x64-try,vm-aot-tsan-linux-release-x64-try,vm-aot-msan-linux-release-x64-try,vm-msan-linux-release-x64-try,vm-aot-linux-release-arm64-try,vm-aot-dwarf-linux-product-x64-try,vm-aot-mac-product-arm64-try,vm-aot-obfuscate-linux-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/344700
Reviewed-by: Daco Harkes <dacoharkes@google.com>
This is a reland of commit baa18e6d29
Fixes IsRepresentable to take a int64_t, not a uint64_t.
Original change's description:
> [vm/compiler] Unify methods for UnboxIntegerOpInstr subclasses.
>
> Unify the Canonicalize() methods on subclasses of UnboxIntegerOp
> so that there aren't subtle differences between canonicalizing
> UnboxInt32 and UnboxUint32 instructions. Also unify the
> ComputeCanDeoptimize() methods for similar reasons.
>
> If canonicalizing a truncating unbox of a constant, then create an
> unboxed constant of the truncated value instead of an unboxed
> constant of the original untruncated value.
>
> Previously, a subclass of Definition that didn't override InferRange
> got a default range solely based on its type. Now, if the representation
> of the definition is an unboxed integer, the default range is the
> intersection of the range inferred from its type with the range
> inferred from its representation.
>
> TEST=ci
>
> Change-Id: Ib022c366904ee6f8a81995bd4c16b87bd876176d
> Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-simarm_x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-win-release-x64-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-android-debug-arm-try
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/332400
> Reviewed-by: Slava Egorov <vegorov@google.com>
TEST=ci (including simarm, not just simarm_x64)
Change-Id: I6f3d3976634da9725d1a81faa62ab9b718d6663e
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-simarm_x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-win-release-x64-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-android-debug-arm-try,vm-linux-release-simarm-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/333001
Reviewed-by: Slava Egorov <vegorov@google.com>
Unify the Canonicalize() methods on subclasses of UnboxIntegerOp
so that there aren't subtle differences between canonicalizing
UnboxInt32 and UnboxUint32 instructions. Also unify the
ComputeCanDeoptimize() methods for similar reasons.
If canonicalizing a truncating unbox of a constant, then create an
unboxed constant of the truncated value instead of an unboxed
constant of the original untruncated value.
Previously, a subclass of Definition that didn't override InferRange
got a default range solely based on its type. Now, if the representation
of the definition is an unboxed integer, the default range is the
intersection of the range inferred from its type with the range
inferred from its representation.
TEST=ci
Change-Id: Ib022c366904ee6f8a81995bd4c16b87bd876176d
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-simarm_x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-win-release-x64-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-android-debug-arm-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/332400
Reviewed-by: Slava Egorov <vegorov@google.com>
We can simplify and improve the range analysis in IntConverter if we
generalize based on the sizes and signs of the source and target
representations and whether the operation truncates or deoptimizes.
Adds RepresentationUtils::MinValue() and ::MaxValue(), which return the
minimum and maximum value (as an int64_t) for an unboxed integer
representation.
TEST=ci
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-simarm_x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-win-release-x64-try,vm-gcc-linux-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-android-debug-arm-try
Change-Id: Ic8dc0d58059e30d85fb2816e15ab3c19fbee461c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/332203
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
This reverts commit 5c4fd50667.
Reason for revert: breaks ffi/data_test on ARM bots
Original change's description:
> [vm/compiler] Consistently use PointerBase.data values as FFiIntPtr.
>
> Also if converting an unboxed int with only non-negative values
> that fit in 32 bits to a uint32, then keep the range from the value.
>
> TEST=regress_306327173_il_test
>
> Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-simarm_x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try
> Change-Id: Id9e7c2d5f477e560822a02574739c57d77b5a6d1
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/332202
> Reviewed-by: Daco Harkes <dacoharkes@google.com>
> Reviewed-by: Slava Egorov <vegorov@google.com>
> Commit-Queue: Tess Strickland <sstrickl@google.com>
Change-Id: I35f6b3b03c9d2dec0f35005f850dab7f2dd54515
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-simarm_x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/332205
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Auto-Submit: Tess Strickland <sstrickl@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Also if converting an unboxed int with only non-negative values
that fit in 32 bits to a uint32, then keep the range from the value.
TEST=regress_306327173_il_test
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-simarm_x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try
Change-Id: Id9e7c2d5f477e560822a02574739c57d77b5a6d1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/332202
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
Before, converting a Uint32 to a Int32 would just clamp the range
to be within the possible Int32 range. However, that's not what the
IntConverterInstr represents in this case: in this case, it's just
a reinterpretation of the bits as signed instead of unsigned.
For simplicity's sake, the initial fix for this is to keep the range
[x, y] if it is 0 <= x <= y <= kMaxInt32, and otherwise just use
the full Int32 range.
Also add a version of Range::Full that takes a Representation instead
of a RangeSize, so that the ranges for unsigned unboxed ints can be
made more precise. Previously, they'd be overapproximated by the next
largest signed representation instead.
Also check that we're never trying to create a range for x->untagged,
and that untagged->x just uses the full range for x.
TEST=vm/dart/regress_306327173_il_test
Fixes: b/306327173
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-simarm_x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try
Change-Id: Ic60d24be016844deda56ee477a6950a315b8506f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/332040
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
This is a reland of commit 06d7a2352e
This version fixes an issue when a phi node has multiple inputs with
different unboxed integer representations. The original CL made a
change where only the representations were considered, not the range
of values for the Phi calculated by range analysis. The reland goes
back to the old behavior for this case.
Also fixes the new tests on 32-bit architectures.
Original change's description:
> [vm/compiler] Change MemoryCopy to also take untagged addresses.
>
> This CL adds the ability to pass the payload address of the source
> and destination directly to the MemoryCopy instruction as an untagged
> value.
>
> The new translation of the _TypedListBase._memMoveN methods use the new
> MemoryCopy constructor, retrieving the untagged value of the data field
> of both the source and destination. This way, if inlining exposes the
> allocation of the object from which the data field is being retrieved,
> then allocation sinking can remove the intermediate allocation if there
> are no escaping uses of the object.
>
> Since Pointer.asTypedList allocates such ExternalTypedData objects,
> this CL makes that method inlined if at all possible, which removes
> the intermediate allocation if the only use of the TypedData object
> is to call setRange for memory copying purposes.
>
> This CL also separates unboxed native slots into two groups: those
> that contain untagged addresses and those that do not. The former
> group now have the kUntagged representation, which mimics the old
> use of LoadUntagged for the PointerBase data field and also ensures
> that any arithmetic operations on untagged addresses must first be
> explicitly converted to an unboxed integer and then explicitly converted
> back to untagged before being stored in a slot that contains untagged
> addresses.
>
> When a unboxed native slot that contains untagged addresses is defined,
> the definition also includes a boolean which represents whether
> addresses that may be moved by the GC can be stored in this slot or not.
> The redundancy eliminator uses this to decide whether it is safe to
> eliminate a duplicate load, replace a load with the value originally
> stored in the slot, or lift a load out of a loop.
>
> In particular, the PointerBase data field may contain GC-moveable
> addresses, but only for internal TypedData objects and views, not
> for external TypedData objects or Pointers. To allow load optimizations
> involving the latter, the LoadField and StoreField instructions now
> take boolean flags for whether loads or stores from the slot are
> guaranteed to not be GC-moveable, to override the information from
> the slot argument.
>
> Notable benchmark changes on x64 (similar for other archs unless noted):
>
> JIT:
> * FfiMemory.PointerPointer: 250.7%
> * FfiStructCopy.Copy1Bytes: -26.73% (only x64)
> * FfiStructCopy.Copy32Bytes: -25.18% (only x64)
> * MemoryCopy.64.setRange.Pointer.Uint8: 19.36%
> * MemoryCopy.64.setRange.Pointer.Double: 18.96%
> * MemoryCopy.8.setRange.Pointer.Double: 17.59%
> * MemoryCopy.8.setRange.Pointer.Uint8: 19.46%
>
> AOT:
> * FfiMemory.PointerPointer: 323.5%
> * FfiStruct.FieldLoadStore: 483.3%
> * FileIO_readwrite_64kb: 15.39%
> * FileIO_readwrite_512kb (Intel Xeon): 46.22%
> * MemoryCopy.512.setRange.Pointer.Uint8: 35.20%
> * MemoryCopy.64.setRange.Pointer.Uint8: 55.40%
> * MemoryCopy.512.setRange.Pointer.Double: 29.45%
> * MemoryCopy.64.setRange.Pointer.Double: 60.37%
> * MemoryCopy.8.setRange.Pointer.Double: 59.54%
> * MemoryCopy.8.setRange.Pointer.Uint8: 55.40%
> * FfiStructCopy.Copy32Bytes: 398.3%
> * FfiStructCopy.Copy1Bytes: 1233%
>
> TEST=vm/dart/address_local_pointer, vm/dart/pointer_as_typed_list
>
> Issue: https://github.com/dart-lang/sdk/issues/42072
> Fixes: https://github.com/dart-lang/sdk/issues/53124
>
> Cq-Include-Trybots: luci.dart.try:vm-ffi-qemu-linux-release-arm-try,vm-eager-optimization-linux-release-x64-try,vm-linux-release-x64-try,vm-linux-debug-x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try
> Change-Id: I563e0bfac5b1ac6cf1111649934067c12891b631
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/324820
> Reviewed-by: Alexander Markov <alexmarkov@google.com>
> Commit-Queue: Tess Strickland <sstrickl@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
TEST=vm/dart/address_local_pointer, vm/dart/pointer_as_typed_list
Issue: https://github.com/dart-lang/sdk/issues/42072
Fixes: https://github.com/dart-lang/sdk/issues/53124
Change-Id: Iabb0e910f12636d0ff51e711c8c9c98ad40e5811
Cq-Include-Trybots: luci.dart.try:vm-ffi-qemu-linux-release-arm-try,vm-eager-optimization-linux-release-x64-try,vm-linux-release-x64-try,vm-linux-debug-x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-release-simarm_x64-try,vm-aot-linux-debug-simarm_x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/330600
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This reverts commit 06d7a2352e.
Reason for revert: everything crashes on vm-aot-linux-debug-simarm_x64
Original change's description:
> [vm/compiler] Change MemoryCopy to also take untagged addresses.
>
> This CL adds the ability to pass the payload address of the source
> and destination directly to the MemoryCopy instruction as an untagged
> value.
>
> The new translation of the _TypedListBase._memMoveN methods use the new
> MemoryCopy constructor, retrieving the untagged value of the data field
> of both the source and destination. This way, if inlining exposes the
> allocation of the object from which the data field is being retrieved,
> then allocation sinking can remove the intermediate allocation if there
> are no escaping uses of the object.
>
> Since Pointer.asTypedList allocates such ExternalTypedData objects,
> this CL makes that method inlined if at all possible, which removes
> the intermediate allocation if the only use of the TypedData object
> is to call setRange for memory copying purposes.
>
> This CL also separates unboxed native slots into two groups: those
> that contain untagged addresses and those that do not. The former
> group now have the kUntagged representation, which mimics the old
> use of LoadUntagged for the PointerBase data field and also ensures
> that any arithmetic operations on untagged addresses must first be
> explicitly converted to an unboxed integer and then explicitly converted
> back to untagged before being stored in a slot that contains untagged
> addresses.
>
> When a unboxed native slot that contains untagged addresses is defined,
> the definition also includes a boolean which represents whether
> addresses that may be moved by the GC can be stored in this slot or not.
> The redundancy eliminator uses this to decide whether it is safe to
> eliminate a duplicate load, replace a load with the value originally
> stored in the slot, or lift a load out of a loop.
>
> In particular, the PointerBase data field may contain GC-moveable
> addresses, but only for internal TypedData objects and views, not
> for external TypedData objects or Pointers. To allow load optimizations
> involving the latter, the LoadField and StoreField instructions now
> take boolean flags for whether loads or stores from the slot are
> guaranteed to not be GC-moveable, to override the information from
> the slot argument.
>
> Notable benchmark changes on x64 (similar for other archs unless noted):
>
> JIT:
> * FfiMemory.PointerPointer: 250.7%
> * FfiStructCopy.Copy1Bytes: -26.73% (only x64)
> * FfiStructCopy.Copy32Bytes: -25.18% (only x64)
> * MemoryCopy.64.setRange.Pointer.Uint8: 19.36%
> * MemoryCopy.64.setRange.Pointer.Double: 18.96%
> * MemoryCopy.8.setRange.Pointer.Double: 17.59%
> * MemoryCopy.8.setRange.Pointer.Uint8: 19.46%
>
> AOT:
> * FfiMemory.PointerPointer: 323.5%
> * FfiStruct.FieldLoadStore: 483.3%
> * FileIO_readwrite_64kb: 15.39%
> * FileIO_readwrite_512kb (Intel Xeon): 46.22%
> * MemoryCopy.512.setRange.Pointer.Uint8: 35.20%
> * MemoryCopy.64.setRange.Pointer.Uint8: 55.40%
> * MemoryCopy.512.setRange.Pointer.Double: 29.45%
> * MemoryCopy.64.setRange.Pointer.Double: 60.37%
> * MemoryCopy.8.setRange.Pointer.Double: 59.54%
> * MemoryCopy.8.setRange.Pointer.Uint8: 55.40%
> * FfiStructCopy.Copy32Bytes: 398.3%
> * FfiStructCopy.Copy1Bytes: 1233%
>
> TEST=vm/dart/address_local_pointer, vm/dart/pointer_as_typed_list
>
> Issue: https://github.com/dart-lang/sdk/issues/42072
> Fixes: https://github.com/dart-lang/sdk/issues/53124
>
> Cq-Include-Trybots: luci.dart.try:vm-ffi-qemu-linux-release-arm-try,vm-eager-optimization-linux-release-x64-try,vm-linux-release-x64-try,vm-linux-debug-x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try
> Change-Id: I563e0bfac5b1ac6cf1111649934067c12891b631
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/324820
> Reviewed-by: Alexander Markov <alexmarkov@google.com>
> Commit-Queue: Tess Strickland <sstrickl@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
Issue: https://github.com/dart-lang/sdk/issues/42072
Change-Id: I7c31434e01108487de69a32154bbefd1538c6f0f
Cq-Include-Trybots: luci.dart.try:vm-ffi-qemu-linux-release-arm-try,vm-eager-optimization-linux-release-x64-try,vm-linux-release-x64-try,vm-linux-debug-x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/330523
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
Auto-Submit: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
This CL adds the ability to pass the payload address of the source
and destination directly to the MemoryCopy instruction as an untagged
value.
The new translation of the _TypedListBase._memMoveN methods use the new
MemoryCopy constructor, retrieving the untagged value of the data field
of both the source and destination. This way, if inlining exposes the
allocation of the object from which the data field is being retrieved,
then allocation sinking can remove the intermediate allocation if there
are no escaping uses of the object.
Since Pointer.asTypedList allocates such ExternalTypedData objects,
this CL makes that method inlined if at all possible, which removes
the intermediate allocation if the only use of the TypedData object
is to call setRange for memory copying purposes.
This CL also separates unboxed native slots into two groups: those
that contain untagged addresses and those that do not. The former
group now have the kUntagged representation, which mimics the old
use of LoadUntagged for the PointerBase data field and also ensures
that any arithmetic operations on untagged addresses must first be
explicitly converted to an unboxed integer and then explicitly converted
back to untagged before being stored in a slot that contains untagged
addresses.
When a unboxed native slot that contains untagged addresses is defined,
the definition also includes a boolean which represents whether
addresses that may be moved by the GC can be stored in this slot or not.
The redundancy eliminator uses this to decide whether it is safe to
eliminate a duplicate load, replace a load with the value originally
stored in the slot, or lift a load out of a loop.
In particular, the PointerBase data field may contain GC-moveable
addresses, but only for internal TypedData objects and views, not
for external TypedData objects or Pointers. To allow load optimizations
involving the latter, the LoadField and StoreField instructions now
take boolean flags for whether loads or stores from the slot are
guaranteed to not be GC-moveable, to override the information from
the slot argument.
Notable benchmark changes on x64 (similar for other archs unless noted):
JIT:
* FfiMemory.PointerPointer: 250.7%
* FfiStructCopy.Copy1Bytes: -26.73% (only x64)
* FfiStructCopy.Copy32Bytes: -25.18% (only x64)
* MemoryCopy.64.setRange.Pointer.Uint8: 19.36%
* MemoryCopy.64.setRange.Pointer.Double: 18.96%
* MemoryCopy.8.setRange.Pointer.Double: 17.59%
* MemoryCopy.8.setRange.Pointer.Uint8: 19.46%
AOT:
* FfiMemory.PointerPointer: 323.5%
* FfiStruct.FieldLoadStore: 483.3%
* FileIO_readwrite_64kb: 15.39%
* FileIO_readwrite_512kb (Intel Xeon): 46.22%
* MemoryCopy.512.setRange.Pointer.Uint8: 35.20%
* MemoryCopy.64.setRange.Pointer.Uint8: 55.40%
* MemoryCopy.512.setRange.Pointer.Double: 29.45%
* MemoryCopy.64.setRange.Pointer.Double: 60.37%
* MemoryCopy.8.setRange.Pointer.Double: 59.54%
* MemoryCopy.8.setRange.Pointer.Uint8: 55.40%
* FfiStructCopy.Copy32Bytes: 398.3%
* FfiStructCopy.Copy1Bytes: 1233%
TEST=vm/dart/address_local_pointer, vm/dart/pointer_as_typed_list
Issue: https://github.com/dart-lang/sdk/issues/42072
Fixes: https://github.com/dart-lang/sdk/issues/53124
Cq-Include-Trybots: luci.dart.try:vm-ffi-qemu-linux-release-arm-try,vm-eager-optimization-linux-release-x64-try,vm-linux-release-x64-try,vm-linux-debug-x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try
Change-Id: I563e0bfac5b1ac6cf1111649934067c12891b631
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/324820
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Also marks CheckBoundBase as an abstract instruction, instead of it
being treated specially.
Now when matching IL graphs that use bounds check instructions, which
differ in JIT vs. AOT, the matcher can match the abstract base
instruction (CheckBoundBase) instead of having to separately match the
concrete subclasses on JIT (CheckArrayBound) and AOT
(GenericCheckBound).
TEST=ci
Change-Id: I73dd6bf6711a99cc2c52a69cf31f22ba4850f2b3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/327001
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
This also lowers the threshold for converting from a linear cache
to a hash-based cache from 100 to 30 on non-IA32 architectures.
(IA32 still goes to runtime if there's a hash-based cache.)
For SubtypeTestCache benchmarks above this threshold, we see an
improvement varying from ~50-100% to ~700-800% on all architectures,
from lowest number of checks (50) to highest (1000).
For SubtypeTestCache benchmarks below this threshold, no major
changes are seen: generally <5% improvement or <5% regression per
check at most.
TEST=vm/cc/TTS
Change-Id: I83aa7c085ab5a411e944ec660d6b8eba7a788ee0
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-simriscv64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-product-x64-try,vm-aot-linux-release-simarm64-try,vm-aot-linux-release-simarm_x64-try,vm-aot-linux-debug-x64c-try,vm-aot-tsan-linux-release-x64-try,vm-aot-mac-release-arm64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-aot-dwarf-linux-product-x64-try,vm-linux-release-ia32-try,vm-linux-debug-x64c-try,vm-linux-debug-x64-try,vm-linux-debug-simriscv64-try,vm-linux-release-simarm64-try,vm-linux-release-simarm-try,vm-mac-release-arm64-try,vm-mac-release-x64-try,vm-tsan-linux-release-x64-try,vm-reload-rollback-linux-release-x64-try,vm-reload-linux-release-x64-try,vm-ffi-qemu-linux-release-arm-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308941
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
TypeRef type wraps around another type and it was used to represent
a graph of recursive types. After [0], the only use of TypeRef is
for TypeParameter.bound which may indirectly reference the same
TypeParameter.
This change replaces TypeParameter.bound with TypeParameter.owner and
removes TypeRef entirely. Various parts of the VM no longer need to
handle and support TypeRefs.
TypeParameter.owner can reference a FunctionType, Class,
or, as an optimization, it can be set to null in order to share
class type parameters among different classes.
With the exception of the 'TypeParameter.owner' back pointer,
VM types are now not recursive and can be visited without
additional tracking.
Caveats:
* Generic FunctionType cannot be cloned in a shallow way:
when copying a FunctionType, type parameters should be cloned too
and their owners should be updated. For that reason,
a mapping between 'from' and 'to' function types
(FunctionTypeMapping) is maintained during type transformations
such as InstantiateFrom.
FunctionType::Clone is used instead of Object::Clone where
appropriate.
* When testing types for subtyping and equivalence, mapping
between function types is passed to make sure
type parameters belong to the equivalent function types.
* IL serializer needs to serialize function types as a whole before
serializing any types potentially pointing into the middle of a
function type (such as return type 'List<Y0>' pointing into
the middle of a function type 'List<Y0> Function<Y0>()').
[0] https://dart-review.googlesource.com/c/sdk/+/296300
TEST=ci
Change-Id: I67c2fd0117c6183a45e183919a7847fd1af70b3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/294165
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This is a reland of commit 135443706b
Original change's description:
> [vm] Avoid expanding/flattening type arguments vectors in Type objects
>
> Previously, vectors of type arguments were expanded to include type
> arguments corresponding to superclasses both in the instances of
> generic classes and in Type objects (after type finalization).
> As a result, Type objects after finalization could be recursive and
> need to use extra TypeRef objects to break loops. The finalization of
> types was very complex and sometimes slow.
>
> This change simplifies the representation of Type objects: now they
> always have short type argument vectors, corresponding only to
> the type parameters of their own classes (both before and after
> finalization). Vectors of type arguments in the instances of generic
> classes are still expanded/flattened.
>
> This greatly simplifies type finalization, makes Type objects
> non-recursive and removes the need to create and handle excessive
> TypeRefs for type arguments corresponding to superclasses,
> as those type arguments are no longer included into types.
> The only remaining use of TypeRefs is for bounds of type parameters.
>
> In order to expand/flatten type arguments, new methods Type::GetInstanceTypeArguments / Class::GetInstanceTypeArguments
> are introduced. They build canonical declaration type arguments
> once (for each class), and then instantiate them as needed.
>
> There are also simple helper methods to shrink type arguments (TypeArguments::FromInstanceTypeArguments) and expand type arguments without filling type arguments corresponding to superclasses (TypeArguments::ToInstantiatorTypeArguments).
>
> Time of edge case 'regress_51960_test' 15min -> 300ms.
>
> TEST=ci, runtime/tests/vm/dart/regress_51960_test.dart
>
> Fixes https://github.com/dart-lang/sdk/issues/52022
> Fixes https://github.com/dart-lang/sdk/issues/51960
>
> Change-Id: I75b466b74698a33c0bb5e1dcbd29542e413812a1
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/295060
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
> Commit-Queue: Alexander Markov <alexmarkov@google.com>
TEST=runtime/tests/vm/dart/regress_b_278841863_test.dart
Fixes b/278841863.
Change-Id: Ib1e20055bfb26e1df0a077300c69f0bec7152480
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/296300
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This reverts commit 135443706b.
Reason for revert: breaks many targets in G3, see b/278841863
Original change's description:
> [vm] Avoid expanding/flattening type arguments vectors in Type objects
>
> Previously, vectors of type arguments were expanded to include type
> arguments corresponding to superclasses both in the instances of
> generic classes and in Type objects (after type finalization).
> As a result, Type objects after finalization could be recursive and
> need to use extra TypeRef objects to break loops. The finalization of
> types was very complex and sometimes slow.
>
> This change simplifies the representation of Type objects: now they
> always have short type argument vectors, corresponding only to
> the type parameters of their own classes (both before and after
> finalization). Vectors of type arguments in the instances of generic
> classes are still expanded/flattened.
>
> This greatly simplifies type finalization, makes Type objects
> non-recursive and removes the need to create and handle excessive
> TypeRefs for type arguments corresponding to superclasses,
> as those type arguments are no longer included into types.
> The only remaining use of TypeRefs is for bounds of type parameters.
>
> In order to expand/flatten type arguments, new methods Type::GetInstanceTypeArguments / Class::GetInstanceTypeArguments
> are introduced. They build canonical declaration type arguments
> once (for each class), and then instantiate them as needed.
>
> There are also simple helper methods to shrink type arguments (TypeArguments::FromInstanceTypeArguments) and expand type arguments without filling type arguments corresponding to superclasses (TypeArguments::ToInstantiatorTypeArguments).
>
> Time of edge case 'regress_51960_test' 15min -> 300ms.
>
> TEST=ci, runtime/tests/vm/dart/regress_51960_test.dart
>
> Fixes https://github.com/dart-lang/sdk/issues/52022
> Fixes https://github.com/dart-lang/sdk/issues/51960
>
> Change-Id: I75b466b74698a33c0bb5e1dcbd29542e413812a1
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/295060
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
> Commit-Queue: Alexander Markov <alexmarkov@google.com>
Change-Id: If0b2077305620593b8f03ebf6c135375c4086b1a
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/296182
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Alexander Thomas <athom@google.com>
Commit-Queue: Ilya Yanok <yanok@google.com>
Previously, vectors of type arguments were expanded to include type
arguments corresponding to superclasses both in the instances of
generic classes and in Type objects (after type finalization).
As a result, Type objects after finalization could be recursive and
need to use extra TypeRef objects to break loops. The finalization of
types was very complex and sometimes slow.
This change simplifies the representation of Type objects: now they
always have short type argument vectors, corresponding only to
the type parameters of their own classes (both before and after
finalization). Vectors of type arguments in the instances of generic
classes are still expanded/flattened.
This greatly simplifies type finalization, makes Type objects
non-recursive and removes the need to create and handle excessive
TypeRefs for type arguments corresponding to superclasses,
as those type arguments are no longer included into types.
The only remaining use of TypeRefs is for bounds of type parameters.
In order to expand/flatten type arguments, new methods Type::GetInstanceTypeArguments / Class::GetInstanceTypeArguments
are introduced. They build canonical declaration type arguments
once (for each class), and then instantiate them as needed.
There are also simple helper methods to shrink type arguments (TypeArguments::FromInstanceTypeArguments) and expand type arguments without filling type arguments corresponding to superclasses (TypeArguments::ToInstantiatorTypeArguments).
Time of edge case 'regress_51960_test' 15min -> 300ms.
TEST=ci, runtime/tests/vm/dart/regress_51960_test.dart
Fixes https://github.com/dart-lang/sdk/issues/52022
Fixes https://github.com/dart-lang/sdk/issues/51960
Change-Id: I75b466b74698a33c0bb5e1dcbd29542e413812a1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/295060
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
- Use the currently-unused ReceivePort.handler field instead of a second map.
- Recognize ReceivePort's fields instead of using natives.
This also has the effect that if one discovers that a port handler is holding onto a large amount of memory via its context, the receive port along with its debug name will appear in the retaining path.
TEST=ci
Change-Id: I4b8d0764a41729a3b397b85bc4603e4d6b0ca9a7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/285403
Reviewed-by: Liam Appelbe <liama@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
The representation of record shape in record instances and record
types is changed from a pair
int num_fields
Array field_names
to a single integer - packed bitfield
int num_fields(16)
int field_names_index(kSmiBits-16)
where field names index is an index in the array available from
ObjectStore.
With the new representation of record shapes:
1) Size of record instances is reduced.
2) Number of comparisons for a shape test reduced from 2 to 1
(shape test is used during type checks).
3) A few operations removed from Record.hashCode.
4) Type testing stubs (TTS) are now supported for record types with
named fields. Previously it was not possible to check shape of records
with named fields in TTS as TTS cannot access object pool and cannot
load field names array).
TEST=existing
Issue: https://github.com/dart-lang/sdk/issues/49719
Change-Id: I7cdcbb53938aba5d561cd24dc99530395dbbea7e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/276201
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Lower the threshold for converting from a linear to a hash-based cache
on most architectures from 500 to 10.
Due to register pressure, the InstantiateTypeArguments stub on IA32
continues to go to the runtime for hash caches, and so we do not
lower the threshold for converting to a hash-based cache there.
The following are benchmark results for those benchmark that use enough
Instantiations to trigger the use of hash-based caches. In the following
tables, "Results 1" denotes the benchmark results from only this change,
whereas "Results 2" include from comparing to the results prior to
4f925105cf, when only linear caches were used.
Dart AOT:
* InstantiateTypeArguments.Instantiate100
Arch | CPU | Results 1 | Results 2
-------|----------------|-----------------------
ARM | Odroid-C2 | 382.8% | 381.5%
ARM | Raspberry Pi 4 | 486.7% | 449.2%
ARM64 | Odroid-C2 | 328.1% | 372.8%
ARM64 | Raspberry Pi 4 | 1283% | 1281%
ARM64C | Raspberry Pi 4 | 2353% | 2811%
X64 | Intel Xeon | 568.7% | 584.9%
* InstantiateTypeArguments.Instantiate1000
Arch | CPU | Results 1 | Results 2
-------|----------------|------------------------
ARM | Odroid-C2 | 743.7% | 3821%
ARM | Raspberry Pi 4 | 486.7% | 3218%
ARM64 | Odroid-C2 | 584.7% | 3222%
ARM64 | Raspberry Pi 4 | 430.7% | 8172%
ARM64C | Raspberry Pi 4 | 491.4% | 16699%
X64 | Intel Xeon | 954.1% | 5528%
Dart JIT:
* InstantiateTypeArguments.Instantiate100
Arch | CPU | Results 1 | Results 2
-------|----------------|-----------------------
ARM | Raspberry Pi 4 | 315.7% | 295.1%
ARM64 | Raspberry Pi 4 | 1070% | 1058%
ARM64C | Raspberry Pi 4 | 1769% | 2095%
X64 | Intel Xeon | 507.4% | 496.2%
* InstantiateTypeArguments.Instantiate1000
Arch | CPU | Results 1 | Results 2
-------|----------------|-----------------------
ARM | Raspberry Pi 4 | 565.2% | 2550%
ARM64 | Raspberry Pi 4 | 406.8% | 7375%
ARM64C | Raspberry Pi 4 | 379.6% | 12996%
X64 | Intel Xeon | 807.9% | 4459%
During work on this change, an issue was found where cache lookups
in the stub on ARM64C always failed and went to runtime, even with
the old linear-only caches, hence the much larger performance gains
in those rows above.
TEST=vm/cc/TypeArguments_Cache_{Some,Many}Instantiations
Fixes: https://github.com/dart-lang/sdk/issues/48344
Change-Id: I3d29566ba0582502954c9fc59626ceb8fd40317a
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-dwarf-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-mac-release-arm64-try,vm-kernel-precomp-nnbd-linux-release-simarm_x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-simarm64-try,vm-kernel-precomp-nnbd-linux-debug-simriscv64-try,vm-kernel-precomp-tsan-linux-release-x64-try,vm-kernel-tsan-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64c-try,vm-kernel-nnbd-linux-debug-simriscv64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-ia32-try,vm-kernel-nnbd-linux-release-simarm-try,vm-kernel-nnbd-linux-release-simarm64-try,vm-kernel-nnbd-linux-release-ia32-try,vm-kernel-nnbd-mac-release-arm64-try,vm-kernel-linux-debug-x64c-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/270702
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
'is' tests against record types are split into series of 'is' tests of
record fields. This is more efficient as record instances cannot be
added to subtype test caches (because type of a record instance
depends on types of its fields).
This change also adds canonicalization and constant evaluation of
LoadFieldInstr for record fields.
Performance on a trivial micro-benchmark (on x64):
JIT (RunTime): 4519104.5 -> 20031.5
AOT (RunTime): 4352583.0 -> 26281.6
TEST=ci
Issue: https://github.com/dart-lang/sdk/issues/49719
Change-Id: I2ed464cd3b31f365b17805f4e7debe1d6d1051fa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/268080
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>