An allocation can - in the slow path - go to runtime which can cause a
pre-allocated OutOfMemory exception to be thrown. It therefore requires
correct deopt information.
Issue https://github.com/dart-lang/sdk/issues/45213
TEST=Existing test suite. A follow-up CL will add actual deoptimization tests for those instructions.
Change-Id: Iaf44904b82ec021919352483f58e9e8fed473955
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/192685
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
As part of making the compiler independent of a particular isolate
(since all isolates in a group share the same JITed code) we move the
boxed field list to IsolateGroup.
Any isolate that hits the lazy compile stub will then drain the fields
to be deoptimized and performs that work.
A follow-up investigation can decide whether it's beneficial (or
hurtful) for single vs multi isolate scenarios to deoptimize the field
immediately in BG compiler (and interrupt mutator). It is possibly
disadvantagues for single isolate scenarios to do so, since it causes
more mutator interruptions.
Issue https://github.com/dart-lang/sdk/issues/36097
TEST=Refactoring of existing code.
Change-Id: I64b42ad99056b43a7264bcc30280b9ba39389a2e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182505
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
When creating new instructions that inherit a token position that
represents a source location from another instruction, the inheriting
instruction must also have the same inlining ID in order for the source
position represented by the token position to be looked up in the
correct script.
Force this by wrapping both in a single InstructionSource struct which
is taken by instructions which take token positions instead of just a
token position. That way, it's more work to manually transfer the token
position separately from the inlining ID of the instruction than doing
the right thing of transfering both at once.
To ensure this information is kept consistent, we pass InstructionSource
structs through the FlowGraphCompiler all the way down to the
CodeSourceMapBuilder.
This CL also makes the following changes:
* Cache the upper bound of source positions in scripts and use it to add
a check for if a given real token position is valid for the script
without iterating over the line starts data for each token position.
* Start inlining intervals appropriately when adding descriptor and
null check information to the code source map.
Code size changes are minimal on Flutter gallery in release mode
(<0.05% decrease).
TEST=Existing tests on trybots, with manual checking with
--check-token-positions that previous errors are now removed.
Bug: https://github.com/dart-lang/sdk/issues/44436
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-release-x64-try,vm-kernel-nnbd-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-linux-release-simarm64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-ia32-try
Change-Id: I23ced262cb4e9fe9d81356f409e7e8d220d63ee0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/173967
Reviewed-by: Régis Crelier <regis@google.com>
Attempts to run class finalizaton on background thread revealed the problem where during optimization(which could run on mutator thread too) we might need to finalize previously unseen class, load annotatons for it, load and set some constant fields. This could result in updating Fields guarded_cid, requires check during installation of newly produced optimized code. Because mutator thread is currently exempt from cloning and validating fields guards, that could result in invalid optimized code installation.
This CL ensures that fields are always cloned in optimizing compiler even when it runs on mutator thread.
Ability to run multiple optimizing compilers is also needed for dartbug.com/36097.
Issue https://github.com/dart-lang/sdk/issues/36097
TEST=existing test suite with ltw isolate groups enabled, https://dart-review.googlesource.com/c/sdk/+/176300 mocked up test(still to be improved).
Change-Id: I608f4abff30b468cb9d0ab270221a0ba72c32470
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175341
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
To make implicit getters/setters frameless in common cases we use graph
intrinsics. We do this for boxed as well as unboxed fields. We do this
only for simple cases (e.g. not if field guards or possible boxing are
involved).
It also removes the hand-written assembly intrinsics for the getters,
which avoids bugs if boxing-state of field is not the same as
boxing-state of setter/getter.
Issue https://github.com/dart-lang/sdk/issues/40876
Change-Id: Id3bd7842ead0278fee61d4a21c8661ce18dbccee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155900
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Tess Strickland <sstrickl@google.com>
#if defined(DART_PRECOMPILED_RUNTIME)
#error "AOT runtime should not use compiler sources (including header files)"
#endif // defined(DART_PRECOMPILED_RUNTIME)
Remove #if defined(DART_PRECOMPILED_RUNTIME) from most compiler sources.
Change-Id: Id175c83fdbea38d9d5e1371ff433e3888f2afe8a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/143523
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This change hides InstanceCallInstr inside PolymorphicInstanceCallInstr
and makes sure that PolymorphicInstanceCallInstr owns its arguments
(which would become critical once call arguments become instruction
inputs).
Also, PolymorphicInstanceCallInstr now extends TemplateDartCall which
makes it possible to avoid duplication of methods related to all calls.
Issue: https://github.com/dart-lang/sdk/issues/39788
Change-Id: Ie3d4ff46a8e99a0988ba88a88ca9a60be8503ce0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/129307
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
dart-bytecode, arm64: +4.742% geomean
dart-bytecode-jit-unopt, arm64: +12.73% geomean
dart2js-compile, x64: +3.635% geomean
In the polymorphic and unlinked cases, call to a stub the does a linear scan against an ICData.
In the monomorphic case, call to a prologue of the expected target function that checks the expected receiver class. There is additional indirection in the JIT version compared to the AOT version to also tick a usage counter so the inliner can make good decisions.
In the megamorphic case, call to a stub that does a hash table lookup against a MegamorphicCache.
Megamorphic call sites face a loss of precision in usage counts. The call site count is not recorded and the usage counter of the target function is used as an approximation.
Monomorphic and megamorphic calls sites are reset to the polymorphic/unlinked state on hot reload.
Monomorphic and megamorphic calls sites do not check the stepping state, so they are reset to the polymorphic/unlinked state when stepping begins and disabled.
Back-edges now increment the usage counter in addition to checking it. This ensures function with loops containing monomorphic calls will eventually cross the optimization threshold.
Fixed backwards use of kMonomorphicEntryOffset and kPolymorphicEntryOffset.
Fixed C stack overflow when bouncing between the KBC interpreter and a simulator.
Bug: https://github.com/dart-lang/sdk/issues/26780
Bug: https://github.com/dart-lang/sdk/issues/36409
Bug: https://github.com/dart-lang/sdk/issues/36731
Change-Id: I78a49cccd962703a459288e71ce246ed845df474
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/102820
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This reverts commit fde6a5917e.
Reason for revert: This commit looks to be causing new test failures on dart2js. While there are some odd results on some builders that look like infra failures, some builders (for example, dart2js-minified-strong-linux-x64-d8) show the new failing tests clearly.
Original change's description:
> [vm, compiler] Unoptimized megamorphic calls.
>
> When an instance call in unoptimized code creates more than FLAG_max_polymorphic_checks cases, switch the call to use a MegamorphicCache instead of ICData. The prevents unbounded collection of type feedback, and gives improvements on microbenchmarks in the 3-8% range for unoptimized code.
>
> It also leads to a loss of target frequency information for the optimizer, leading to different ordering for range checks in polymorphic inlining. This leads to changes on megamorphic microbenchmarks from -31% to +60%, weighted toward the negative end.
>
> In practice the frequency information seems unimportant, as dart2js has 4.01% geomean improvement.
>
> This is a step toward direct monomorphic calls in unoptimized code, which will also make use of the patching and type feedback extraction added here.
>
> Bug: https://github.com/dart-lang/sdk/issues/26780
> Bug: https://github.com/dart-lang/sdk/issues/36409
> Bug: https://github.com/dart-lang/sdk/issues/36731
> Change-Id: I29f53f23b6794c5f5f0db8b8184788cee16fd9c5
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99270
> Reviewed-by: Alexander Markov <alexmarkov@google.com>
TBR=rmacnak@google.com,alexmarkov@google.com,ajcbik@google.com
Change-Id: Icad46b93cdf8541a00563f49da6b4ac0a4df1ba1
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: https://github.com/dart-lang/sdk/issues/26780, https://github.com/dart-lang/sdk/issues/36409, https://github.com/dart-lang/sdk/issues/36731
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103440
Reviewed-by: Teagan Strickland <sstrickl@google.com>
Commit-Queue: Teagan Strickland <sstrickl@google.com>
When an instance call in unoptimized code creates more than FLAG_max_polymorphic_checks cases, switch the call to use a MegamorphicCache instead of ICData. The prevents unbounded collection of type feedback, and gives improvements on microbenchmarks in the 3-8% range for unoptimized code.
It also leads to a loss of target frequency information for the optimizer, leading to different ordering for range checks in polymorphic inlining. This leads to changes on megamorphic microbenchmarks from -31% to +60%, weighted toward the negative end.
In practice the frequency information seems unimportant, as dart2js has 4.01% geomean improvement.
This is a step toward direct monomorphic calls in unoptimized code, which will also make use of the patching and type feedback extraction added here.
Bug: https://github.com/dart-lang/sdk/issues/26780
Bug: https://github.com/dart-lang/sdk/issues/36409
Bug: https://github.com/dart-lang/sdk/issues/36731
Change-Id: I29f53f23b6794c5f5f0db8b8184788cee16fd9c5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99270
Reviewed-by: Alexander Markov <alexmarkov@google.com>
We still see some trace messages related to the compiler coming from the
service isolate when debugging compilations. Chnaged some of the
OS::PrintErr calls in the trace code under the compiler to THR_Print
so traces from the service isolate can be filtered out.
Change-Id: Ib370cb3bf4a1ce175b4ade9fafa187fecfa91cef
Reviewed-on: https://dart-review.googlesource.com/c/91140
Commit-Queue: Siva Annamalai <asiva@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Aart Bik <ajcbik@google.com>
Also do the same for the unsafe version of StoreIndexed.
Similar to the inliner, we may replace calls in the specializers with
these non-definition instructions, so we make variants that allow an
unrelated value to be used for the old users of the call site value. (In
all cases, this ends up being null, since the original calls wouldn't
have returned a useable value anyway.)
Change-Id: I0befd54920c4c0e63e086b804860ee4c9a7d3767
Reviewed-on: https://dart-review.googlesource.com/c/89585
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Stevie Strickland <sstrickl@google.com>
This reverts commit a8777149a7.
Reason for revert: benchmarking infrastructure reports broken benchmarks on ARM.
Original change's description:
> [VM/Compiler] Revoke definition status of certain instructions.
>
> Change StoreIndexed, StoreIndexedUnsafe, and StoreInstanceField
> to be non-definition instructions. Fix up the flow graph builders
> so they no longer treat StoreIndexed and StoreIndexedUnsafe as
> pushing values on the stack that need to be dropped.
>
> We recently changed FlowGraphInliner::TryInlineRecognizedMethod
> to create a distinction between the last instruction to be inlined
> and the definition that should be used as the new result. Perform
> the same separation of replacement code and result in the call
> specializers.
>
> Change-Id: I66c7ab60a662dcca05092e47156d1d4ba809d51f
> Reviewed-on: https://dart-review.googlesource.com/c/88326
> Commit-Queue: Stevie Strickland <sstrickl@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
TBR=kustermann@google.com,sstrickl@google.com
Change-Id: I9c666d80a69ba6a5c37b421aae1ed83502694f19
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/89366
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Change StoreIndexed, StoreIndexedUnsafe, and StoreInstanceField
to be non-definition instructions. Fix up the flow graph builders
so they no longer treat StoreIndexed and StoreIndexedUnsafe as
pushing values on the stack that need to be dropped.
We recently changed FlowGraphInliner::TryInlineRecognizedMethod
to create a distinction between the last instruction to be inlined
and the definition that should be used as the new result. Perform
the same separation of replacement code and result in the call
specializers.
Change-Id: I66c7ab60a662dcca05092e47156d1d4ba809d51f
Reviewed-on: https://dart-review.googlesource.com/c/88326
Commit-Queue: Stevie Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Make StoreIntanceField and LoadField instructions use a single uniform
abstraction: Slot (used to be called NativeFieldDesc), which represents
either a real Dart field (i.e. a field that has a corresponding Field object)
or a native VM field that does not have a corresponding Field object.
This refactoring eliminates raw stores/loads that were just using offsets
before - now we always know what kind of slots we are accessing and
this yields better aliasing information.
Change-Id: I2f48332d58258219565bd961764e8cc9dd4d75ce
Reviewed-on: https://dart-review.googlesource.com/c/74582
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Also move deopt id computation logic into a separate class and add a comment
explaining while deopt ids are incremented by 2.
Change-Id: Ife489be7d10c7198a8e7adf9e97e0c516d78ea55
Reviewed-on: https://dart-review.googlesource.com/72685
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
JitCallSpecializer::VisitInstanceCall has two places where it converts
instance call into a static call. Previously we only made use of
exactness information in one of those places.
On dart2js compiling dart2js this change reduces number of times
we enter Map.putIfAbsent through checked entry point from
1107368 to 8640.
Bug: https://github.com/dart-lang/sdk/issues/31798
Change-Id: Id1665b998ecdf4c4d46cb7605a11bdde2e8c9782
Reviewed-on: https://dart-review.googlesource.com/72220
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
CloneContext is implemented as a runtime call so it is considerably slower
than AllocateContext which leads to performance issues in loops that capture
iteration variables in for loops.
Lowering CloneContext into AllocateUninitializedContext and a sequence of
explicit load&store instructions both improves the performance by avoiding
the runtime call and also makes CloneContext semantics exposed to store-load
forwarding and allocation sinking.
PutIfAbsent benchmark from issue #31113 is improved by 5x, while
ForInGeneratedLoop benchmark is improved by 8x.
Bug: https://github.com/dart-lang/sdk/issues/31113
Change-Id: I03fdede75f1a85fda92487aa8f9307ce06f23903
Reviewed-on: https://dart-review.googlesource.com/16280
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This CL is a draft implementation of optimizing 'is', int and double
operators using statically known strong mode types in Dart VM AOT.
As of now, not all cases are handled and null checks are not inserted
(required for correctness). The new logic is added under
--experimental-strong-mode flag.
The primary reason for submitting this code is to keep up with ongoing
refactoring of Dart VM compiler.
Issue: https://github.com/dart-lang/sdk/issues/30480
Change-Id: Ia441fa3e346a184a1e5c87d0749aec652e2cde0a
Reviewed-on: https://dart-review.googlesource.com/4144
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Originally these passes were a single confusingly named flow_graph_optimizer
pass, they later were completely split by duplicating flow_graph_optimizer
twice as jit_optimizer.cc and aot_optimizer.cc and tweaking them in few
places.
Duplication has been done in anticipation that these passes will diverge
considerably, however simple diffing reveals that in 2 years they have
not actually diverged much at all.
Diffing also reveals numerous bugs and inconsistencies between jit_optimizer
and aot_optimizer.
It does not make sense to keep these files duplicated so this change merges
them back together - extracting most of their common behaviour into
CallSpecializer base class.
The separation is not entirely clean - for simplicity we introduce
the knowledge about precompiled_mode into CallSpecializer base class.
You can look for FLAG_precompiled_mode and FLAG_use_field_guards in the
call_specializer.cc to see where base class has to be aware about both AOT and
JIT mode.
This change also renames XyzOptimizer to XyzCallSpecializer because the main
optimization these classes were doing was specialization of calls based on
type feedback or inferred types.
Bug: https://github.com/dart-lang/sdk/issues/30575
Change-Id: I0b062c4b7549d08b1bee9303d92a3fb549f54e21
Reviewed-on: https://dart-review.googlesource.com/3640
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Zach Anderson <zra@google.com>