Keep list of all per-isolate BreakpointLocations on isolate_group so all of them
can be traversed by isolate group when function is compiled and
GroupDebugger::NotifyCompilation() is invoked.
This also fixes data race around line_number lazy-initialization.
Issue https://github.com/dart-lang/sdk/issues/36097
TEST=existing ci test suite
Change-Id: I821b49a56cdc28da8d0c0c97e7d850995285c48a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193380
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
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>
Many years ago those bailouts were seemingly added due to deferred
loading in [0]. Though it seems like those bailouts might've become
obsolete.
All places that clear the IC array on the function should run inside
a [NoBackgroundCompiler] scope, therefore ensuring no optimizing
compilations are done at that time. Those places also clear code,
therefore forcing re-compilation of unoptimized code (which will
re-create the ICData).
[0] https://codereview.chromium.org/1672873003/#ps60001
TEST=Removing dead code.
Change-Id: Iec4f22be500f6e874fa5286b51396bd6d978dd6c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/187902
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
The background compiler no longer has bailouts due to something that
cannot be done on BG compiler and has to be done on mutator (was
originally introduced in [0])
All optimizing compilations can happen on the BG thread. Class
finalization and other things no longer cause a bailout on BG
compiler.
If e.g. invalidated field guards cause a compilation to be discarded, it
can be retried on BG compiler.
[0] https://dart-review.googlesource.com/c/sdk/+/54886
Closes https://github.com/dart-lang/sdk/issues/45136
TEST=Fixes flaky hits of an assertion.
Change-Id: I50313dbedf96b8dec205acdb8c1ed5731d00433b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/187901
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
In presence of multiple mutators in one isolate group, same function might be unoptimized-compiled by more than one mutator. Avoid reinstallation of newly compiled unoptimized code if that happens. Unoptimized compilation itself is not that expensive, so we don't prevent multiple mutators to do actual compilation of the same function.
Fixes https://github.com/dart-lang/sdk/issues/44992.
Issue https://github.com/dart-lang/sdk/issues/36097
TEST=standalone_2\io\http_basic_test.dart on windows
Change-Id: I0fbd62e8f8299a5d8289a6689da157a691715b81
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/185460
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
With --enable-isolate-groups we will start sharing JITed code. The JITed
code - which will be executed by all isolates - should therefore not
depend on a particular isolate's state, flags or any other
isolate-specific information.
To avoid accidental bugs where the compiler starts using
isolate-specific information, we ensure the compiler runs without a
current isolate.
This CL doesn't add NoActiveIsolateScope because on unoptimized compiles
of natives, the compiler calls out to embedder for eager native
resolution of native functions. This API forces embedder to callback
into VM atm.
Issue https://github.com/dart-lang/sdk/issues/36097
TEST=Adds more checking.
Change-Id: I6c86674c010b74c15855652415706dbaa8749d33
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183692
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
The logic for background compiler can be simplified due to:
* we only have one bg compiler
* it always optimizes
* it is allocated at isolate startup and freed on isolate shutdown
* an existing check in the compiler for whether the BG compiler is
disabled is racy and therefore not helpful
* when a mutator communicates with BG compiler it will use
SafepointMutexLocker instead of MutexLocker
This CL also ecapsulates disabling the BG compiler via a
NoBackgroundCompilerScope object. It allows nested disabling and guards
against races.
Issue https://github.com/dart-lang/sdk/issues/36097
TEST=Refactoring of existing code.
Change-Id: I36ed6592c9a8b91e94181698b7de662b4ee984e9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183400
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@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>
Currently we have things called XPtr which are not what you get from ptr().
Old world:
handle->raw() returns RawObject* (tagged)
raw_obj->ptr() returns RawObject* (untagged)
After 6fe15f6df9:
handle->raw() returns ObjectPtr
obj_ptr->ptr() returns ObjectLayout*
New world:
handle->ptr() returns ObjectPtr
obj_ptr->untag() returns UntaggedObject*
TEST=ci
Change-Id: I6c7f34014cf20737607caaf84979838300d12df2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149367
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@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>
When this flag is enabled, then the validity of real token positions are
checked in three places:
* FlowGraphChecker::VisitInstruction
* CodeSourceMapBuilder::BufferChangeLocation
* DescriptorList::AddDescriptor
The validity check ensures that, if the flow graph has an inlining
ID, that the instruction has an inlining ID and that any real token
position is a valid source offset for the appropriate script (found
via the inlining ID) by attempting to look up line and column.
This flag is disabled by default until existing issues with invalid
inlining IDs and token positions are resolved.
TEST=Enabled the flag manually to check that it caught invalid token
positions.
Bug: https://github.com/dart-lang/sdk/issues/44436
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try
Change-Id: I86439db3661d976ac4ea608d132e3277425615d5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175641
Reviewed-by: Martin Kustermann <kustermann@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>
Instead, split each old use into the following cases:
* If the TokenPosition value is expected to be a real token position,
then use TokenPosition::Pos().
* If the TokenPosition is being serialized in some way, then use
TokenPosition::Serialize() and change the place where the
TokenPosition is recreated to use TokenPosition::Deserialize().
* If the value of the TokenPosition is being printed for debugging
purposes, then just use TokenPosition::ToCString() instead.
That is, we try to pin down when token positions are expected to
be real vs. when other types of token positions can be found.
Another source of possible error when using token positions is to
convert between synthetic and real token positions. In the past,
synthetic token positions may have been based off real token positions,
but that is no longer the case. Thus, all methods that allow
that conversion have been removed, and instead there is a new static
method for constructing synthetic tokens from valid nonces.
This CL also makes it so that Pos() and relational operators on token
positions are only defined on real token positions, to avoid any
assumptions about what the value encoded in synthetic positions mean. To
help with cases where non-real token positions may occur, four helper
methods are added:
* TokenPosition::Min(a, b): A static method that returns the smallest
real token position provided. If neither `a` or `b` are real,
returns `a`.
* TokenPosition::Max(a, b): A static method that returns the largest
real token position provided. If neither `a` or `b` are real,
returns `a`.
* TokenPosition::IsWithin(start, end): Determines whether `this` falls
between `start` and `end` (inclusive). If `this` is non-real, then it
must be either `start` or `end` if synthetic, otherwise false.
Otherwise, we mimic the old style of range checking, which means that
non-real starts and ends are treated as less than every real token.
* TokenPosition::CompareForSorting(other): Unlike the relational
operators, provides a comparison between any types of token positions
for purposes such as sorting. Currently only used in the profiler.
It also changes TokenPosition::ToCString() to tag synthetic token
positions, so they can be distinguished from real ones at a glance.
TEST=Existing test suite on trybots, especially the observatory tests
which make heavy use of the debugger and the unit tests for the
profiler/source report modules.
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
Change-Id: Ic06aa0bc7a1f0fbac7257ed22ca5e7e0ccd7f3f2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/174924
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
All existing embedders have been opted into --lazy-async-stacks, the
VM also uses it as it's default in all configurations.
After this CL, any user of --causal-async-stacks will get an error
message when trying to use it.
=> In any such case, please simply remove the flag.
TEST=Exhaustive CQ.
Bug: https://github.com/dart-lang/sdk/issues/37668
Change-Id: Ia440afcf2dba464aa8b8cf381b93bbac8eb9f8dc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/172564
Commit-Queue: Clement Skau <cskau@google.com>
Reviewed-by: Clement Skau <cskau@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Since the transition from Source based to Kernel based frontend to the
Dart VM, we have not supported callable redirecting factories. This has
caused all removed code in this CL to be unused and untested!
The support for reifing redirection related information would mainly be
used by embedder / dart:mirrors. Right now its not used by anyone and
the kernel support was never implemented.
I suggest we remove the unused and untested code until a decision has
been made that we actually want to support it - in which case it can be
properly implemented, possibly by re-using some of the deleted code in
this CL.
TEST=CL removes unused code, no test result changes.
Change-Id: I7ed45c85b4efcc1e81ce44cbe08bb555e52101b9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166853
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@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>
Additionally make it possible to filter the output of this tracing
using --print-flow-graph-filter=...
Expose should_filter() setting through CompilerState - to avoid
plumbing FlowGraph or Function through various methods that don't
already have access to either of these two.
Change-Id: Ia1b8bcff5702e869db23ea4407191741662b2417
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/147544
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Our TLAB sizes and maximum new space size constrain the number of
parallel mutator threads we can have. Having too many mutator threads
would cause constant races between threads to acquire TLABs.
In reality we should constrain the number of threads to be at most the
number of cores, since at most that many threads can run in parallel
(i.e. at the same time).
This CL extends the TreadPool implementation to be constrained by a
maximum size. Furthermore it makes each isolate group's have it's own
pool with constrained size and schedule all group member
mutator / message handler tasks on that pool.
Issue https://github.com/dart-lang/sdk/issues/36097
Change-Id: I095c749adad827ab892f33713a32be594d7606d1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/145382
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@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>
Make them form its own source set (libdart_compiler) and completely exclude
them from AOT runtime targets.
Previously we had some inconsistencies, with some files were using
DART_PRECOMPILED_RUNTIME to fully or partially exclude either contents
from their headers or from implementation, while other files did nothing
and relied on linker to throw their contents away.
This change tries to address this inconsistency.
A follow up change would include a check in most compiler headers which
would prohibit to use them while building AOT runtime.
Change-Id: Ief11b11cbc518b301d3e93fce80580a31bbad151
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/142993
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
In the early days of AOT, we performed compilation and then ran results in the same process and isolate. This bit was used to track which phase we were in. Today, these always happen in separate processes and separate binaries, distinguished by the macro DART_PRECOMPILED_RUNTIME.
Change-Id: Idd97908f2e692321a6f5aba8d5738625d42f16e7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134568
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Sets a threshold of five continuations determining if the old
if-else or the new igoto-based implementation will be used.
Informal benchmarking on x64 and arm_x64 point towards the overhead
of the igoto-based impl. dropping off around this point.
Benchmarks of this CL (threshold=5) show drastic improvement in
Calls.IterableManualIterablePolymorphicManyYields of about ~35-65%
across {dart,dart-aot}-{ia32,x64,armv7hf,armv8}.
Note: This is a second revision of a CL landed and reverted from:
https://dart-review.googlesource.com/c/sdk/+/133586
The fix for the previous revert was swapping the parameters to
BuildIndirectEntry(int, int) in kernel_binary_flowgraph.cc.
Bug: https://github.com/dart-lang/sdk/issues/37754
Change-Id: If035235ce8aa660af2ea7f8cfbc8066cde6329b7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/136126
Commit-Queue: Clement Skau <cskau@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Sets a threshold of five continuations determining if the old
if-else or the new igoto-based implementation will be used.
Informal benchmarking on x64 and arm_x64 point towards the overhead
of the igoto-based impl. dropping off around this point.
Benchmarks of this CL (threshold=5) show drastic improvement in
Calls.IterableManualIterablePolymorphicManyYields of about ~35-65%
across {dart,dart-aot}-{ia32,x64,armv7hf,armv8}.
Bug: https://github.com/dart-lang/sdk/issues/37754
Change-Id: I6e113f1f98e9ab0f994cf93004227d616e9e4d07
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133586
Commit-Queue: Clement Skau <cskau@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>