2012-03-23 01:27:35 +00:00
|
|
|
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
|
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
|
2016-10-26 07:26:03 +00:00
|
|
|
#ifndef RUNTIME_VM_CODE_DESCRIPTORS_H_
|
|
|
|
#define RUNTIME_VM_CODE_DESCRIPTORS_H_
|
2012-03-23 01:27:35 +00:00
|
|
|
|
2017-03-13 12:27:00 +00:00
|
|
|
#include "vm/datastream.h"
|
2012-03-23 01:27:35 +00:00
|
|
|
#include "vm/globals.h"
|
|
|
|
#include "vm/growable_array.h"
|
2017-02-10 02:03:41 +00:00
|
|
|
#include "vm/log.h"
|
2017-04-19 17:21:53 +00:00
|
|
|
#include "vm/runtime_entry.h"
|
[vm/compiler] Copy inlined IDs with token positions.
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>
2020-12-18 00:42:14 +00:00
|
|
|
#include "vm/token_position.h"
|
2012-03-23 01:27:35 +00:00
|
|
|
|
|
|
|
namespace dart {
|
|
|
|
|
2018-10-10 18:00:21 +00:00
|
|
|
static const intptr_t kInvalidTryIndex = -1;
|
|
|
|
|
2012-03-23 01:27:35 +00:00
|
|
|
class DescriptorList : public ZoneAllocated {
|
|
|
|
public:
|
2020-12-17 12:19:43 +00:00
|
|
|
explicit DescriptorList(
|
|
|
|
Zone* zone,
|
|
|
|
const GrowableArray<const Function*>* inline_id_to_function = nullptr);
|
2012-03-23 01:27:35 +00:00
|
|
|
|
2016-11-08 21:54:47 +00:00
|
|
|
~DescriptorList() {}
|
2015-05-13 20:24:47 +00:00
|
|
|
|
2021-01-15 23:32:02 +00:00
|
|
|
void AddDescriptor(UntaggedPcDescriptors::Kind kind,
|
2012-03-23 01:27:35 +00:00
|
|
|
intptr_t pc_offset,
|
2012-08-06 20:24:03 +00:00
|
|
|
intptr_t deopt_id,
|
2016-02-02 18:15:44 +00:00
|
|
|
TokenPosition token_pos,
|
2019-11-18 11:50:13 +00:00
|
|
|
intptr_t try_index,
|
|
|
|
intptr_t yield_index);
|
2012-03-23 01:27:35 +00:00
|
|
|
|
2020-04-25 05:21:27 +00:00
|
|
|
PcDescriptorsPtr FinalizePcDescriptors(uword entry_point);
|
2012-03-23 01:27:35 +00:00
|
|
|
|
|
|
|
private:
|
[vm] Add (S)LEB128 encoding/decoding to BaseWriteStream.
Unlike cfc8e6de, this does _not_ replace the default variable length
encoding for {Read,Write}Streams, but insteads adds separate
{Read,Write}{S,}LEB128 methods to the appropriate classes. If we later
find the cause of the issues that led to the revert of cfc8e6de, it'll
be easy to switch over then.
Note that WriteLEB128 asserts that the value is non-negative if used
with a signed type (since negative values suggests that SLEB128 should
be used instead for minimal encoding).
Also removes the various other encoding and decoding methods for
(S)LEB128 across the codebase and changes those clients to use
{Read,Write}Streams instead.
Other cleanups:
* Various constant-related cleanups in datastream.h.
* Adds DART_FORCE_INLINE to ReadStream::ReadByte and uses it in the
default variable length decoding methods for retrieving bytes
from the stream instead of managing current_ by hand.
* Creates a canonical empty CompressedStackMaps instance and uses
that instead of the null CompressedStackMaps instance in most cases.
The only remaining (expected) use of the null CompressedStackMaps
instance is for the global table in the object store when no global
table exists (e.g., in JIT mode before any snapshotting).
* Moves CompressedStackMapsIterator from code_descriptors.h to an
Iterator class within CompressedStackMaps in object.h (similar to
PcDescriptors::Iterator), to limit friend declarations and because it
conceptually makes more sense as part of CompressedStackMaps.
* Removed CompressedStackMaps::PayloadByte, since existing clients
(CompressedStackMaps::Iterator, StackMapEntry in program_visitor.cc)
are better served by just operating on the payload buffer directly
(with appropriate NoSafepointScopes).
* WriteStreams no longer allocate their initial space on construction,
but rather on the first write, so no allocation is performed by
constructing a never-used WriteStream.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-ubsan-linux-release-x64-try,vm-kernel-tsan-linux-release-x64-try,vm-kernel-precomp-ubsan-linux-release-x64-try,vm-kernel-precomp-tsan-linux-release-x64-try,vm-kernel-precomp-msan-linux-release-x64-try,vm-kernel-precomp-asan-linux-release-x64-try,vm-kernel-msan-linux-release-x64-try,vm-kernel-asan-linux-release-x64-try
Change-Id: Ice63321abaa79157fbe9f230a864c8bba0e6dea9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166421
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-10-09 10:08:16 +00:00
|
|
|
static constexpr intptr_t kInitialStreamSize = 64;
|
|
|
|
|
2020-12-17 12:19:43 +00:00
|
|
|
const Function& function_;
|
|
|
|
const Script& script_;
|
[vm] Add (S)LEB128 encoding/decoding to BaseWriteStream.
Unlike cfc8e6de, this does _not_ replace the default variable length
encoding for {Read,Write}Streams, but insteads adds separate
{Read,Write}{S,}LEB128 methods to the appropriate classes. If we later
find the cause of the issues that led to the revert of cfc8e6de, it'll
be easy to switch over then.
Note that WriteLEB128 asserts that the value is non-negative if used
with a signed type (since negative values suggests that SLEB128 should
be used instead for minimal encoding).
Also removes the various other encoding and decoding methods for
(S)LEB128 across the codebase and changes those clients to use
{Read,Write}Streams instead.
Other cleanups:
* Various constant-related cleanups in datastream.h.
* Adds DART_FORCE_INLINE to ReadStream::ReadByte and uses it in the
default variable length decoding methods for retrieving bytes
from the stream instead of managing current_ by hand.
* Creates a canonical empty CompressedStackMaps instance and uses
that instead of the null CompressedStackMaps instance in most cases.
The only remaining (expected) use of the null CompressedStackMaps
instance is for the global table in the object store when no global
table exists (e.g., in JIT mode before any snapshotting).
* Moves CompressedStackMapsIterator from code_descriptors.h to an
Iterator class within CompressedStackMaps in object.h (similar to
PcDescriptors::Iterator), to limit friend declarations and because it
conceptually makes more sense as part of CompressedStackMaps.
* Removed CompressedStackMaps::PayloadByte, since existing clients
(CompressedStackMaps::Iterator, StackMapEntry in program_visitor.cc)
are better served by just operating on the payload buffer directly
(with appropriate NoSafepointScopes).
* WriteStreams no longer allocate their initial space on construction,
but rather on the first write, so no allocation is performed by
constructing a never-used WriteStream.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-ubsan-linux-release-x64-try,vm-kernel-tsan-linux-release-x64-try,vm-kernel-precomp-ubsan-linux-release-x64-try,vm-kernel-precomp-tsan-linux-release-x64-try,vm-kernel-precomp-msan-linux-release-x64-try,vm-kernel-precomp-asan-linux-release-x64-try,vm-kernel-msan-linux-release-x64-try,vm-kernel-asan-linux-release-x64-try
Change-Id: Ice63321abaa79157fbe9f230a864c8bba0e6dea9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166421
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-10-09 10:08:16 +00:00
|
|
|
ZoneWriteStream encoded_data_;
|
2015-05-18 18:04:45 +00:00
|
|
|
|
|
|
|
intptr_t prev_pc_offset;
|
|
|
|
intptr_t prev_deopt_id;
|
[vm] Remove non-private uses of TokenPosition::value().
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>
2020-12-16 08:27:32 +00:00
|
|
|
int32_t prev_token_pos;
|
2015-05-18 18:04:45 +00:00
|
|
|
|
2012-03-23 01:27:35 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(DescriptorList);
|
|
|
|
};
|
|
|
|
|
[vm/compiler] Reland "Further compress the information... in StackMaps."
Fixes an assumption that CompressedStackMapsIterator::Find() is never
passed a PC offset of 0. Adds back an ASSERT that was dropped which checks
for specific cases where a given PC offset does not have a stack map entry.
Original commit message:
Lifting the PC offset in a2bb730 was a small, lightweight change that
gave us big gains, at least on 32-bit architectures. Here, we make
much more invasive changes that will improve the amount of memory used
by the information previously stored in StackMap objects.
Instead of allocating separate objects for StackMaps, we instead compress
all StackMap information for a given Code object into a single object
(CompressedStackMaps, or CSM for short). This replaces the Array used to
store PC offsets (as Smis) and the individual StackMap objects.
While we lose all canonicalization for individual StackMap entries, the
drop in space required to store stack map information more than offsets that.
-----
The impact on AOT snapshot size when compiling the Flutter Gallery
in release mode:
armv7: Total size -2.58% (Isolate RO: +14.46%, Isolate snapshot: -22.93%)
armv8: Total size -1.85% (Isolate RO: +15.69%, Isolate snapshot: -22.97%)
The impact on in-memory, not on-disk, size for the Flutter Gallery as seen
in the Observatory while running a profile (not release) build:
armv7: Drops from 7.1 MB to 6.2MB (-0.9 MB)
armv8: Drops from 13.5MB to 11.7MB (-1.8 MB)
-----
Bug: https://github.com/dart-lang/sdk/issues/35274, https://github.com/dart-lang/sdk/issues/38873
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-mac-debug-simdbc64-try
Change-Id: I111b129b0ed64f03184370bceb7cda69d5d4b3c9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121700
Commit-Queue: Teagan Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2019-10-16 08:25:53 +00:00
|
|
|
class CompressedStackMapsBuilder : public ZoneAllocated {
|
2012-03-23 01:27:35 +00:00
|
|
|
public:
|
[vm] Add (S)LEB128 encoding/decoding to BaseWriteStream.
Unlike cfc8e6de, this does _not_ replace the default variable length
encoding for {Read,Write}Streams, but insteads adds separate
{Read,Write}{S,}LEB128 methods to the appropriate classes. If we later
find the cause of the issues that led to the revert of cfc8e6de, it'll
be easy to switch over then.
Note that WriteLEB128 asserts that the value is non-negative if used
with a signed type (since negative values suggests that SLEB128 should
be used instead for minimal encoding).
Also removes the various other encoding and decoding methods for
(S)LEB128 across the codebase and changes those clients to use
{Read,Write}Streams instead.
Other cleanups:
* Various constant-related cleanups in datastream.h.
* Adds DART_FORCE_INLINE to ReadStream::ReadByte and uses it in the
default variable length decoding methods for retrieving bytes
from the stream instead of managing current_ by hand.
* Creates a canonical empty CompressedStackMaps instance and uses
that instead of the null CompressedStackMaps instance in most cases.
The only remaining (expected) use of the null CompressedStackMaps
instance is for the global table in the object store when no global
table exists (e.g., in JIT mode before any snapshotting).
* Moves CompressedStackMapsIterator from code_descriptors.h to an
Iterator class within CompressedStackMaps in object.h (similar to
PcDescriptors::Iterator), to limit friend declarations and because it
conceptually makes more sense as part of CompressedStackMaps.
* Removed CompressedStackMaps::PayloadByte, since existing clients
(CompressedStackMaps::Iterator, StackMapEntry in program_visitor.cc)
are better served by just operating on the payload buffer directly
(with appropriate NoSafepointScopes).
* WriteStreams no longer allocate their initial space on construction,
but rather on the first write, so no allocation is performed by
constructing a never-used WriteStream.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-ubsan-linux-release-x64-try,vm-kernel-tsan-linux-release-x64-try,vm-kernel-precomp-ubsan-linux-release-x64-try,vm-kernel-precomp-tsan-linux-release-x64-try,vm-kernel-precomp-msan-linux-release-x64-try,vm-kernel-precomp-asan-linux-release-x64-try,vm-kernel-msan-linux-release-x64-try,vm-kernel-asan-linux-release-x64-try
Change-Id: Ice63321abaa79157fbe9f230a864c8bba0e6dea9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166421
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-10-09 10:08:16 +00:00
|
|
|
explicit CompressedStackMapsBuilder(Zone* zone)
|
|
|
|
: encoded_bytes_(zone, kInitialStreamSize) {}
|
2019-11-14 12:49:06 +00:00
|
|
|
|
2012-08-30 10:20:26 +00:00
|
|
|
void AddEntry(intptr_t pc_offset,
|
|
|
|
BitmapBuilder* bitmap,
|
[vm/compiler] Reland "Further compress the information... in StackMaps."
Fixes an assumption that CompressedStackMapsIterator::Find() is never
passed a PC offset of 0. Adds back an ASSERT that was dropped which checks
for specific cases where a given PC offset does not have a stack map entry.
Original commit message:
Lifting the PC offset in a2bb730 was a small, lightweight change that
gave us big gains, at least on 32-bit architectures. Here, we make
much more invasive changes that will improve the amount of memory used
by the information previously stored in StackMap objects.
Instead of allocating separate objects for StackMaps, we instead compress
all StackMap information for a given Code object into a single object
(CompressedStackMaps, or CSM for short). This replaces the Array used to
store PC offsets (as Smis) and the individual StackMap objects.
While we lose all canonicalization for individual StackMap entries, the
drop in space required to store stack map information more than offsets that.
-----
The impact on AOT snapshot size when compiling the Flutter Gallery
in release mode:
armv7: Total size -2.58% (Isolate RO: +14.46%, Isolate snapshot: -22.93%)
armv8: Total size -1.85% (Isolate RO: +15.69%, Isolate snapshot: -22.97%)
The impact on in-memory, not on-disk, size for the Flutter Gallery as seen
in the Observatory while running a profile (not release) build:
armv7: Drops from 7.1 MB to 6.2MB (-0.9 MB)
armv8: Drops from 13.5MB to 11.7MB (-1.8 MB)
-----
Bug: https://github.com/dart-lang/sdk/issues/35274, https://github.com/dart-lang/sdk/issues/38873
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-mac-debug-simdbc64-try
Change-Id: I111b129b0ed64f03184370bceb7cda69d5d4b3c9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121700
Commit-Queue: Teagan Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2019-10-16 08:25:53 +00:00
|
|
|
intptr_t spill_slot_bit_count);
|
2012-03-23 01:27:35 +00:00
|
|
|
|
2020-04-25 05:21:27 +00:00
|
|
|
CompressedStackMapsPtr Finalize() const;
|
2012-03-23 01:27:35 +00:00
|
|
|
|
[vm/compiler] Reland "Further compress the information... in StackMaps."
Fixes an assumption that CompressedStackMapsIterator::Find() is never
passed a PC offset of 0. Adds back an ASSERT that was dropped which checks
for specific cases where a given PC offset does not have a stack map entry.
Original commit message:
Lifting the PC offset in a2bb730 was a small, lightweight change that
gave us big gains, at least on 32-bit architectures. Here, we make
much more invasive changes that will improve the amount of memory used
by the information previously stored in StackMap objects.
Instead of allocating separate objects for StackMaps, we instead compress
all StackMap information for a given Code object into a single object
(CompressedStackMaps, or CSM for short). This replaces the Array used to
store PC offsets (as Smis) and the individual StackMap objects.
While we lose all canonicalization for individual StackMap entries, the
drop in space required to store stack map information more than offsets that.
-----
The impact on AOT snapshot size when compiling the Flutter Gallery
in release mode:
armv7: Total size -2.58% (Isolate RO: +14.46%, Isolate snapshot: -22.93%)
armv8: Total size -1.85% (Isolate RO: +15.69%, Isolate snapshot: -22.97%)
The impact on in-memory, not on-disk, size for the Flutter Gallery as seen
in the Observatory while running a profile (not release) build:
armv7: Drops from 7.1 MB to 6.2MB (-0.9 MB)
armv8: Drops from 13.5MB to 11.7MB (-1.8 MB)
-----
Bug: https://github.com/dart-lang/sdk/issues/35274, https://github.com/dart-lang/sdk/issues/38873
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-mac-debug-simdbc64-try
Change-Id: I111b129b0ed64f03184370bceb7cda69d5d4b3c9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121700
Commit-Queue: Teagan Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2019-10-16 08:25:53 +00:00
|
|
|
private:
|
[vm] Add (S)LEB128 encoding/decoding to BaseWriteStream.
Unlike cfc8e6de, this does _not_ replace the default variable length
encoding for {Read,Write}Streams, but insteads adds separate
{Read,Write}{S,}LEB128 methods to the appropriate classes. If we later
find the cause of the issues that led to the revert of cfc8e6de, it'll
be easy to switch over then.
Note that WriteLEB128 asserts that the value is non-negative if used
with a signed type (since negative values suggests that SLEB128 should
be used instead for minimal encoding).
Also removes the various other encoding and decoding methods for
(S)LEB128 across the codebase and changes those clients to use
{Read,Write}Streams instead.
Other cleanups:
* Various constant-related cleanups in datastream.h.
* Adds DART_FORCE_INLINE to ReadStream::ReadByte and uses it in the
default variable length decoding methods for retrieving bytes
from the stream instead of managing current_ by hand.
* Creates a canonical empty CompressedStackMaps instance and uses
that instead of the null CompressedStackMaps instance in most cases.
The only remaining (expected) use of the null CompressedStackMaps
instance is for the global table in the object store when no global
table exists (e.g., in JIT mode before any snapshotting).
* Moves CompressedStackMapsIterator from code_descriptors.h to an
Iterator class within CompressedStackMaps in object.h (similar to
PcDescriptors::Iterator), to limit friend declarations and because it
conceptually makes more sense as part of CompressedStackMaps.
* Removed CompressedStackMaps::PayloadByte, since existing clients
(CompressedStackMaps::Iterator, StackMapEntry in program_visitor.cc)
are better served by just operating on the payload buffer directly
(with appropriate NoSafepointScopes).
* WriteStreams no longer allocate their initial space on construction,
but rather on the first write, so no allocation is performed by
constructing a never-used WriteStream.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-mac-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-ubsan-linux-release-x64-try,vm-kernel-tsan-linux-release-x64-try,vm-kernel-precomp-ubsan-linux-release-x64-try,vm-kernel-precomp-tsan-linux-release-x64-try,vm-kernel-precomp-msan-linux-release-x64-try,vm-kernel-precomp-asan-linux-release-x64-try,vm-kernel-msan-linux-release-x64-try,vm-kernel-asan-linux-release-x64-try
Change-Id: Ice63321abaa79157fbe9f230a864c8bba0e6dea9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166421
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
2020-10-09 10:08:16 +00:00
|
|
|
static constexpr intptr_t kInitialStreamSize = 16;
|
|
|
|
|
|
|
|
ZoneWriteStream encoded_bytes_;
|
[vm/compiler] Reland "Further compress the information... in StackMaps."
Fixes an assumption that CompressedStackMapsIterator::Find() is never
passed a PC offset of 0. Adds back an ASSERT that was dropped which checks
for specific cases where a given PC offset does not have a stack map entry.
Original commit message:
Lifting the PC offset in a2bb730 was a small, lightweight change that
gave us big gains, at least on 32-bit architectures. Here, we make
much more invasive changes that will improve the amount of memory used
by the information previously stored in StackMap objects.
Instead of allocating separate objects for StackMaps, we instead compress
all StackMap information for a given Code object into a single object
(CompressedStackMaps, or CSM for short). This replaces the Array used to
store PC offsets (as Smis) and the individual StackMap objects.
While we lose all canonicalization for individual StackMap entries, the
drop in space required to store stack map information more than offsets that.
-----
The impact on AOT snapshot size when compiling the Flutter Gallery
in release mode:
armv7: Total size -2.58% (Isolate RO: +14.46%, Isolate snapshot: -22.93%)
armv8: Total size -1.85% (Isolate RO: +15.69%, Isolate snapshot: -22.97%)
The impact on in-memory, not on-disk, size for the Flutter Gallery as seen
in the Observatory while running a profile (not release) build:
armv7: Drops from 7.1 MB to 6.2MB (-0.9 MB)
armv8: Drops from 13.5MB to 11.7MB (-1.8 MB)
-----
Bug: https://github.com/dart-lang/sdk/issues/35274, https://github.com/dart-lang/sdk/issues/38873
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-mac-debug-simdbc64-try
Change-Id: I111b129b0ed64f03184370bceb7cda69d5d4b3c9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121700
Commit-Queue: Teagan Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2019-10-16 08:25:53 +00:00
|
|
|
intptr_t last_pc_offset_ = 0;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(CompressedStackMapsBuilder);
|
|
|
|
};
|
|
|
|
|
2012-04-05 19:44:49 +00:00
|
|
|
class ExceptionHandlerList : public ZoneAllocated {
|
|
|
|
public:
|
|
|
|
struct HandlerDesc {
|
2016-11-08 21:54:47 +00:00
|
|
|
intptr_t outer_try_index; // Try block in which this try block is nested.
|
|
|
|
intptr_t pc_offset; // Handler PC offset value.
|
2017-02-28 15:13:41 +00:00
|
|
|
bool is_generated; // False if this is directly from Dart code.
|
2016-11-08 21:54:47 +00:00
|
|
|
const Array* handler_types; // Catch clause guards.
|
2013-08-28 22:42:21 +00:00
|
|
|
bool needs_stacktrace;
|
2012-04-05 19:44:49 +00:00
|
|
|
};
|
|
|
|
|
2022-04-29 01:03:50 +00:00
|
|
|
explicit ExceptionHandlerList(const Function& function)
|
2022-05-02 20:53:01 +00:00
|
|
|
: list_(),
|
2022-07-12 19:25:32 +00:00
|
|
|
has_async_handler_(function.IsAsyncFunction() ||
|
|
|
|
function.IsAsyncGenerator()) {}
|
2012-04-05 19:44:49 +00:00
|
|
|
|
2016-11-08 21:54:47 +00:00
|
|
|
intptr_t Length() const { return list_.length(); }
|
2012-04-05 19:44:49 +00:00
|
|
|
|
2013-01-17 01:10:42 +00:00
|
|
|
void AddPlaceHolder() {
|
|
|
|
struct HandlerDesc data;
|
|
|
|
data.outer_try_index = -1;
|
2015-03-12 21:40:05 +00:00
|
|
|
data.pc_offset = ExceptionHandlers::kInvalidPcOffset;
|
2017-02-28 15:13:41 +00:00
|
|
|
data.is_generated = true;
|
2013-01-17 01:10:42 +00:00
|
|
|
data.handler_types = NULL;
|
2013-08-28 22:42:21 +00:00
|
|
|
data.needs_stacktrace = false;
|
2013-01-17 01:10:42 +00:00
|
|
|
list_.Add(data);
|
2012-04-05 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2013-01-15 22:43:00 +00:00
|
|
|
void AddHandler(intptr_t try_index,
|
|
|
|
intptr_t outer_try_index,
|
|
|
|
intptr_t pc_offset,
|
2017-02-28 15:13:41 +00:00
|
|
|
bool is_generated,
|
2013-08-28 22:42:21 +00:00
|
|
|
const Array& handler_types,
|
|
|
|
bool needs_stacktrace) {
|
2013-01-17 01:10:42 +00:00
|
|
|
ASSERT(try_index >= 0);
|
|
|
|
while (Length() <= try_index) {
|
|
|
|
AddPlaceHolder();
|
|
|
|
}
|
|
|
|
list_[try_index].outer_try_index = outer_try_index;
|
2016-01-06 17:50:53 +00:00
|
|
|
ASSERT(list_[try_index].pc_offset == ExceptionHandlers::kInvalidPcOffset);
|
2013-01-17 01:10:42 +00:00
|
|
|
list_[try_index].pc_offset = pc_offset;
|
2017-02-28 15:13:41 +00:00
|
|
|
list_[try_index].is_generated = is_generated;
|
2022-08-22 15:07:47 +00:00
|
|
|
ASSERT(handler_types.IsNotTemporaryScopedHandle());
|
2013-01-17 01:10:42 +00:00
|
|
|
list_[try_index].handler_types = &handler_types;
|
2015-01-13 17:16:50 +00:00
|
|
|
list_[try_index].needs_stacktrace |= needs_stacktrace;
|
2012-04-05 19:44:49 +00:00
|
|
|
}
|
|
|
|
|
2013-08-31 00:26:47 +00:00
|
|
|
// Called by rethrows, to mark their enclosing handlers.
|
2016-12-12 22:51:30 +00:00
|
|
|
void SetNeedsStackTrace(intptr_t try_index) {
|
2013-08-31 00:26:47 +00:00
|
|
|
// Rethrows can be generated outside a try by the compiler.
|
2018-10-10 18:00:21 +00:00
|
|
|
if (try_index == kInvalidTryIndex) {
|
2013-08-31 00:26:47 +00:00
|
|
|
return;
|
|
|
|
}
|
2015-01-13 17:16:50 +00:00
|
|
|
ASSERT(try_index >= 0);
|
|
|
|
while (Length() <= try_index) {
|
|
|
|
AddPlaceHolder();
|
|
|
|
}
|
2013-08-31 00:26:47 +00:00
|
|
|
list_[try_index].needs_stacktrace = true;
|
|
|
|
}
|
|
|
|
|
2020-08-06 23:46:09 +00:00
|
|
|
static bool ContainsCatchAllType(const Array& array) {
|
|
|
|
auto& type = AbstractType::Handle();
|
2013-08-30 20:47:02 +00:00
|
|
|
for (intptr_t i = 0; i < array.Length(); i++) {
|
2020-08-06 23:46:09 +00:00
|
|
|
type ^= array.At(i);
|
|
|
|
if (type.IsCatchAllType()) {
|
2013-08-30 20:47:02 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-04-25 05:21:27 +00:00
|
|
|
ExceptionHandlersPtr FinalizeExceptionHandlers(uword entry_point) const;
|
2012-04-05 19:44:49 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
GrowableArray<struct HandlerDesc> list_;
|
2022-04-29 01:03:50 +00:00
|
|
|
const bool has_async_handler_;
|
2012-04-05 19:44:49 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerList);
|
|
|
|
};
|
|
|
|
|
2018-09-14 17:39:12 +00:00
|
|
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
// Used to construct CatchEntryMoves for the AOT mode of compilation.
|
|
|
|
class CatchEntryMovesMapBuilder : public ZoneAllocated {
|
2017-03-13 12:27:00 +00:00
|
|
|
public:
|
2018-09-14 17:39:12 +00:00
|
|
|
CatchEntryMovesMapBuilder();
|
2017-03-13 12:27:00 +00:00
|
|
|
|
|
|
|
void NewMapping(intptr_t pc_offset);
|
2018-09-14 17:39:12 +00:00
|
|
|
void Append(const CatchEntryMove& move);
|
2017-03-13 12:27:00 +00:00
|
|
|
void EndMapping();
|
2020-04-25 05:21:27 +00:00
|
|
|
TypedDataPtr FinalizeCatchEntryMovesMap();
|
2017-03-13 12:27:00 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
class TrieNode;
|
|
|
|
|
|
|
|
Zone* zone_;
|
|
|
|
TrieNode* root_;
|
|
|
|
intptr_t current_pc_offset_;
|
2018-09-14 17:39:12 +00:00
|
|
|
GrowableArray<CatchEntryMove> moves_;
|
[vm] Consolidate the *WriteStream hierarchy.
All *WriteStream classes are now part of the same hierarchy:
class BaseWriteStream : ValueObject;
Base class for all *WriteStreams. Provides all the methods from
the old WriteStream except for buffer() and SetPosition()
(relegated to NonStreamingWriteStreams). Has one pure virtual
method Realloc that must be overridden by concrete subclasses.
class NonStreamingWriteStream : BaseWriteStream;
Base class for all *WriteStreams where the entire stream is available
at all times (i.e., no flushing to an external sink). Extends the
public BaseWriteStream API with buffer() (for accessing the stream
contents) and SetPosition() (for changing the current stream pointer
to the given absolute position in the stream).
class MallocWriteStream : NonStreamingWriteStream;
Uses realloc to reallocate the internal buffer. Almost the same as
the old WriteStream, except that it only takes an initial size. Adds
one public method Steal() for taking ownership of the current buffer
contents (after which the buffer is reset to an empty state). Instead
of passing a pointer to a buffer, the internal buffer must be accessed
via either Steal() or buffer(), which allows access to the current
stream contents without changing ownership or resetting the stream.
The internal buffer is freed on stream destruction.
class ZoneWriteStream: NonStreamingWriteStream;
Takes a zone and reallocates the internal buffer in that zone. No
additional public methods beyond those available from
NonStreamingWriteStream.
class StreamingWriteStream : BaseWriteStream;
Uses realloc to reallocate the internal buffer. Generally same as
before, where the contents of the stream are periodically flushed
using Dart_StreamingWriteCallback. Since it extends BaseWriteStream,
there are now more methods available for writing data to the stream
than just Print/VPrint/WriteBytes. Since portions of the stream may be
flushed and thus no longer in the internal buffer, does not provide
access to the contents of the stream or a way to reposition the
current stream pointer. Flushes any unflushed data and frees the
internal buffer on stream destruction.
Also refactor things so that write streams are passed to appropriate
recipients, instead of the recipients taking arguments they only used to
create a WriteStream internally. Thus, recipients now can just specify
the appropriate base class for the public API used:
* BaseWriteStream for just writing to the stream, or
* NonStreamingWriteStream if re-positioning or the stream contents are
needed.
Change-Id: I419096ecd9331483d168b079fca55b69ef397f15
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164080
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-09-23 21:05:59 +00:00
|
|
|
ZoneWriteStream stream_;
|
2017-03-13 12:27:00 +00:00
|
|
|
|
2018-09-14 17:39:12 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(CatchEntryMovesMapBuilder);
|
2017-03-13 12:27:00 +00:00
|
|
|
};
|
2018-09-14 17:39:12 +00:00
|
|
|
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
2017-03-13 12:27:00 +00:00
|
|
|
|
[vm/compiler] Copy inlined IDs with token positions.
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>
2020-12-18 00:42:14 +00:00
|
|
|
// Instructions have two pieces of information needed to get accurate source
|
|
|
|
// locations: the token position and the inlining id. The inlining id tells us
|
|
|
|
// which function, and thus which script, to use for this instruction and the
|
|
|
|
// token position, when real, tells us the position in the source for the
|
|
|
|
// script for the instruction.
|
|
|
|
//
|
|
|
|
// Thus, we bundle the two pieces of information in InstructionSource structs
|
|
|
|
// when copying or retrieving to lower the likelihood that the token position
|
|
|
|
// is used without the appropriate inlining id.
|
|
|
|
struct InstructionSource {
|
|
|
|
// Treat an instruction source without inlining id information as unset.
|
|
|
|
InstructionSource() : InstructionSource(TokenPosition::kNoSource) {}
|
|
|
|
explicit InstructionSource(TokenPosition pos) : InstructionSource(pos, -1) {}
|
|
|
|
InstructionSource(TokenPosition pos, intptr_t id)
|
|
|
|
: token_pos(pos), inlining_id(id) {}
|
|
|
|
|
|
|
|
const TokenPosition token_pos;
|
|
|
|
const intptr_t inlining_id;
|
|
|
|
|
|
|
|
DISALLOW_ALLOCATION();
|
|
|
|
};
|
|
|
|
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
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: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
struct CodeSourceMapOps : AllStatic {
|
|
|
|
static const uint8_t kChangePosition = 0;
|
|
|
|
static const uint8_t kAdvancePC = 1;
|
|
|
|
static const uint8_t kPushFunction = 2;
|
|
|
|
static const uint8_t kPopFunction = 3;
|
|
|
|
static const uint8_t kNullCheck = 4;
|
|
|
|
|
|
|
|
static uint8_t Read(ReadStream* stream,
|
|
|
|
int32_t* arg1,
|
|
|
|
int32_t* arg2 = nullptr);
|
|
|
|
|
|
|
|
static void Write(BaseWriteStream* stream,
|
|
|
|
uint8_t op,
|
|
|
|
int32_t arg1 = 0,
|
|
|
|
int32_t arg2 = 0);
|
|
|
|
|
|
|
|
private:
|
|
|
|
static constexpr intptr_t kOpBits = 3;
|
|
|
|
|
|
|
|
using OpField = BitField<int32_t, uint8_t, 0, kOpBits>;
|
|
|
|
using ArgField = BitField<int32_t, int32_t, OpField::kNextBit>;
|
|
|
|
|
|
|
|
static constexpr int32_t kMaxArgValue =
|
2021-07-27 11:22:47 +00:00
|
|
|
Utils::NBitMask<int32_t>(ArgField::bitsize() - 1);
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
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: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
static constexpr int32_t kMinArgValue = ~kMaxArgValue;
|
|
|
|
static constexpr int32_t kSignBits = static_cast<uint32_t>(kMinArgValue) << 1;
|
|
|
|
};
|
|
|
|
|
2017-02-10 02:03:41 +00:00
|
|
|
// A CodeSourceMap maps from pc offsets to a stack of inlined functions and
|
|
|
|
// their positions. This is encoded as a little bytecode that pushes and pops
|
|
|
|
// functions and changes the top function's position as the PC advances.
|
|
|
|
// Decoding happens by running this bytecode until we reach the desired PC.
|
|
|
|
//
|
|
|
|
// The implementation keeps track of two sets of state: one written to the byte
|
|
|
|
// stream and one that is buffered. On the JIT, this buffering effectively gives
|
|
|
|
// us a peephole optimization that merges adjacent advance PC bytecodes. On AOT,
|
|
|
|
// this allows to skip encoding our position until we reach a PC where we might
|
|
|
|
// throw.
|
2017-02-07 20:52:21 +00:00
|
|
|
class CodeSourceMapBuilder : public ZoneAllocated {
|
|
|
|
public:
|
|
|
|
CodeSourceMapBuilder(
|
[vm] Consolidate the *WriteStream hierarchy.
All *WriteStream classes are now part of the same hierarchy:
class BaseWriteStream : ValueObject;
Base class for all *WriteStreams. Provides all the methods from
the old WriteStream except for buffer() and SetPosition()
(relegated to NonStreamingWriteStreams). Has one pure virtual
method Realloc that must be overridden by concrete subclasses.
class NonStreamingWriteStream : BaseWriteStream;
Base class for all *WriteStreams where the entire stream is available
at all times (i.e., no flushing to an external sink). Extends the
public BaseWriteStream API with buffer() (for accessing the stream
contents) and SetPosition() (for changing the current stream pointer
to the given absolute position in the stream).
class MallocWriteStream : NonStreamingWriteStream;
Uses realloc to reallocate the internal buffer. Almost the same as
the old WriteStream, except that it only takes an initial size. Adds
one public method Steal() for taking ownership of the current buffer
contents (after which the buffer is reset to an empty state). Instead
of passing a pointer to a buffer, the internal buffer must be accessed
via either Steal() or buffer(), which allows access to the current
stream contents without changing ownership or resetting the stream.
The internal buffer is freed on stream destruction.
class ZoneWriteStream: NonStreamingWriteStream;
Takes a zone and reallocates the internal buffer in that zone. No
additional public methods beyond those available from
NonStreamingWriteStream.
class StreamingWriteStream : BaseWriteStream;
Uses realloc to reallocate the internal buffer. Generally same as
before, where the contents of the stream are periodically flushed
using Dart_StreamingWriteCallback. Since it extends BaseWriteStream,
there are now more methods available for writing data to the stream
than just Print/VPrint/WriteBytes. Since portions of the stream may be
flushed and thus no longer in the internal buffer, does not provide
access to the contents of the stream or a way to reposition the
current stream pointer. Flushes any unflushed data and frees the
internal buffer on stream destruction.
Also refactor things so that write streams are passed to appropriate
recipients, instead of the recipients taking arguments they only used to
create a WriteStream internally. Thus, recipients now can just specify
the appropriate base class for the public API used:
* BaseWriteStream for just writing to the stream, or
* NonStreamingWriteStream if re-positioning or the stream contents are
needed.
Change-Id: I419096ecd9331483d168b079fca55b69ef397f15
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164080
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-09-23 21:05:59 +00:00
|
|
|
Zone* zone,
|
2017-02-10 02:03:41 +00:00
|
|
|
bool stack_traces_only,
|
2017-02-07 20:52:21 +00:00
|
|
|
const GrowableArray<intptr_t>& caller_inline_id,
|
|
|
|
const GrowableArray<TokenPosition>& inline_id_to_token_pos,
|
|
|
|
const GrowableArray<const Function*>& inline_id_to_function);
|
|
|
|
|
|
|
|
// The position at which a function implicitly starts, for both the root and
|
|
|
|
// after a push bytecode. We use the classifying position kDartCodePrologue
|
|
|
|
// since it is the most common.
|
[vm] Remove non-private uses of TokenPosition::value().
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>
2020-12-16 08:27:32 +00:00
|
|
|
static const TokenPosition& kInitialPosition;
|
2017-02-07 20:52:21 +00:00
|
|
|
|
[vm/compiler] Copy inlined IDs with token positions.
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>
2020-12-18 00:42:14 +00:00
|
|
|
void BeginCodeSourceRange(int32_t pc_offset, const InstructionSource& source);
|
|
|
|
void EndCodeSourceRange(int32_t pc_offset, const InstructionSource& source);
|
2021-01-15 23:32:02 +00:00
|
|
|
void NoteDescriptor(UntaggedPcDescriptors::Kind kind,
|
2017-02-10 02:03:41 +00:00
|
|
|
int32_t pc_offset,
|
[vm/compiler] Copy inlined IDs with token positions.
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>
2020-12-18 00:42:14 +00:00
|
|
|
const InstructionSource& source);
|
|
|
|
void NoteNullCheck(int32_t pc_offset,
|
|
|
|
const InstructionSource& source,
|
|
|
|
intptr_t name_index);
|
2021-11-10 17:52:03 +00:00
|
|
|
void WriteFunctionEntrySourcePosition(const InstructionSource& source);
|
[vm/compiler] Copy inlined IDs with token positions.
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>
2020-12-18 00:42:14 +00:00
|
|
|
|
|
|
|
// If source is from an inlined call, returns the token position of the
|
|
|
|
// original call in the root function, otherwise the source's token position.
|
|
|
|
TokenPosition RootPosition(const InstructionSource& source);
|
2020-04-25 05:21:27 +00:00
|
|
|
ArrayPtr InliningIdToFunction();
|
|
|
|
CodeSourceMapPtr Finalize();
|
2017-02-07 20:52:21 +00:00
|
|
|
|
2020-12-17 12:19:43 +00:00
|
|
|
const GrowableArray<const Function*>& inline_id_to_function() const {
|
|
|
|
return inline_id_to_function_;
|
|
|
|
}
|
|
|
|
|
2017-02-07 20:52:21 +00:00
|
|
|
private:
|
2017-03-24 21:41:36 +00:00
|
|
|
intptr_t GetFunctionId(intptr_t inline_id);
|
[vm/compiler] Copy inlined IDs with token positions.
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>
2020-12-18 00:42:14 +00:00
|
|
|
void StartInliningInterval(int32_t pc_offset,
|
|
|
|
const InstructionSource& source);
|
2017-03-24 21:41:36 +00:00
|
|
|
|
2020-12-17 12:19:43 +00:00
|
|
|
void BufferChangePosition(TokenPosition pos);
|
2017-02-13 18:27:36 +00:00
|
|
|
void WriteChangePosition(TokenPosition pos);
|
2017-02-10 02:03:41 +00:00
|
|
|
void BufferAdvancePC(int32_t distance) { buffered_pc_offset_ += distance; }
|
|
|
|
void WriteAdvancePC(int32_t distance) {
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
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: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
CodeSourceMapOps::Write(&stream_, CodeSourceMapOps::kAdvancePC, distance);
|
2017-02-10 02:03:41 +00:00
|
|
|
written_pc_offset_ += distance;
|
|
|
|
}
|
|
|
|
void BufferPush(intptr_t inline_id) {
|
|
|
|
buffered_inline_id_stack_.Add(inline_id);
|
|
|
|
buffered_token_pos_stack_.Add(kInitialPosition);
|
2017-02-07 20:52:21 +00:00
|
|
|
}
|
2017-02-10 02:03:41 +00:00
|
|
|
void WritePush(intptr_t inline_id) {
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
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: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
CodeSourceMapOps::Write(&stream_, CodeSourceMapOps::kPushFunction,
|
|
|
|
GetFunctionId(inline_id));
|
2017-02-10 02:03:41 +00:00
|
|
|
written_inline_id_stack_.Add(inline_id);
|
|
|
|
written_token_pos_stack_.Add(kInitialPosition);
|
2017-02-07 20:52:21 +00:00
|
|
|
}
|
2017-02-10 02:03:41 +00:00
|
|
|
void BufferPop() {
|
|
|
|
buffered_inline_id_stack_.RemoveLast();
|
|
|
|
buffered_token_pos_stack_.RemoveLast();
|
|
|
|
}
|
|
|
|
void WritePop() {
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
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: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
CodeSourceMapOps::Write(&stream_, CodeSourceMapOps::kPopFunction);
|
2017-02-10 02:03:41 +00:00
|
|
|
written_inline_id_stack_.RemoveLast();
|
|
|
|
written_token_pos_stack_.RemoveLast();
|
2017-02-07 20:52:21 +00:00
|
|
|
}
|
2018-04-26 20:33:15 +00:00
|
|
|
void WriteNullCheck(int32_t name_index) {
|
[vm] Compress CodeSourceMaps by folding opcodes and arguments.
Also delta encode the position/line argument for ChangePosition.
Code size changes on Flutter gallery in release mode from compression:
* ARM7: total -1.39%, readonly -6.47%
* ARM8: total -1.28%, readonly -4.81%
Additional code size changes on Flutter gallery in release mode from
delta encoding position/line:
* ARM7: total -0.48%, readonly -2.37%
* ARM8: total -0.54%, readonly -2.09%
TEST=Existing test on trybots, including stack trace tests and
DWARF decoding tests.
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: Ibaf96b1d6c1916ce2f7c71942e333ca7a0b86c3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175725
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-12-18 00:42:14 +00:00
|
|
|
CodeSourceMapOps::Write(&stream_, CodeSourceMapOps::kNullCheck, name_index);
|
2018-04-26 20:33:15 +00:00
|
|
|
}
|
2017-02-07 20:52:21 +00:00
|
|
|
|
2017-02-10 02:03:41 +00:00
|
|
|
void FlushBuffer();
|
|
|
|
|
|
|
|
bool IsOnBufferedStack(intptr_t inline_id) {
|
|
|
|
for (intptr_t i = 0; i < buffered_inline_id_stack_.length(); i++) {
|
|
|
|
if (buffered_inline_id_stack_[i] == inline_id) return true;
|
2017-02-07 20:52:21 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
[vm/compiler] Copy inlined IDs with token positions.
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>
2020-12-18 00:42:14 +00:00
|
|
|
Zone* const zone_;
|
2017-02-10 02:03:41 +00:00
|
|
|
intptr_t buffered_pc_offset_;
|
|
|
|
GrowableArray<intptr_t> buffered_inline_id_stack_;
|
|
|
|
GrowableArray<TokenPosition> buffered_token_pos_stack_;
|
|
|
|
|
|
|
|
intptr_t written_pc_offset_;
|
|
|
|
GrowableArray<intptr_t> written_inline_id_stack_;
|
|
|
|
GrowableArray<TokenPosition> written_token_pos_stack_;
|
2017-02-07 20:52:21 +00:00
|
|
|
|
|
|
|
const GrowableArray<intptr_t>& caller_inline_id_;
|
|
|
|
const GrowableArray<TokenPosition>& inline_id_to_token_pos_;
|
|
|
|
const GrowableArray<const Function*>& inline_id_to_function_;
|
|
|
|
|
2017-03-24 21:41:36 +00:00
|
|
|
const GrowableObjectArray& inlined_functions_;
|
|
|
|
|
2020-12-17 12:19:43 +00:00
|
|
|
Script& script_;
|
[vm] Consolidate the *WriteStream hierarchy.
All *WriteStream classes are now part of the same hierarchy:
class BaseWriteStream : ValueObject;
Base class for all *WriteStreams. Provides all the methods from
the old WriteStream except for buffer() and SetPosition()
(relegated to NonStreamingWriteStreams). Has one pure virtual
method Realloc that must be overridden by concrete subclasses.
class NonStreamingWriteStream : BaseWriteStream;
Base class for all *WriteStreams where the entire stream is available
at all times (i.e., no flushing to an external sink). Extends the
public BaseWriteStream API with buffer() (for accessing the stream
contents) and SetPosition() (for changing the current stream pointer
to the given absolute position in the stream).
class MallocWriteStream : NonStreamingWriteStream;
Uses realloc to reallocate the internal buffer. Almost the same as
the old WriteStream, except that it only takes an initial size. Adds
one public method Steal() for taking ownership of the current buffer
contents (after which the buffer is reset to an empty state). Instead
of passing a pointer to a buffer, the internal buffer must be accessed
via either Steal() or buffer(), which allows access to the current
stream contents without changing ownership or resetting the stream.
The internal buffer is freed on stream destruction.
class ZoneWriteStream: NonStreamingWriteStream;
Takes a zone and reallocates the internal buffer in that zone. No
additional public methods beyond those available from
NonStreamingWriteStream.
class StreamingWriteStream : BaseWriteStream;
Uses realloc to reallocate the internal buffer. Generally same as
before, where the contents of the stream are periodically flushed
using Dart_StreamingWriteCallback. Since it extends BaseWriteStream,
there are now more methods available for writing data to the stream
than just Print/VPrint/WriteBytes. Since portions of the stream may be
flushed and thus no longer in the internal buffer, does not provide
access to the contents of the stream or a way to reposition the
current stream pointer. Flushes any unflushed data and frees the
internal buffer on stream destruction.
Also refactor things so that write streams are passed to appropriate
recipients, instead of the recipients taking arguments they only used to
create a WriteStream internally. Thus, recipients now can just specify
the appropriate base class for the public API used:
* BaseWriteStream for just writing to the stream, or
* NonStreamingWriteStream if re-positioning or the stream contents are
needed.
Change-Id: I419096ecd9331483d168b079fca55b69ef397f15
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164080
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-09-23 21:05:59 +00:00
|
|
|
ZoneWriteStream stream_;
|
2017-02-07 20:52:21 +00:00
|
|
|
|
2017-02-10 02:03:41 +00:00
|
|
|
const bool stack_traces_only_;
|
|
|
|
|
2017-02-07 20:52:21 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(CodeSourceMapBuilder);
|
|
|
|
};
|
|
|
|
|
|
|
|
class CodeSourceMapReader : public ValueObject {
|
|
|
|
public:
|
|
|
|
CodeSourceMapReader(const CodeSourceMap& map,
|
|
|
|
const Array& functions,
|
|
|
|
const Function& root)
|
|
|
|
: map_(map), functions_(functions), root_(root) {}
|
|
|
|
|
|
|
|
void GetInlinedFunctionsAt(int32_t pc_offset,
|
|
|
|
GrowableArray<const Function*>* function_stack,
|
|
|
|
GrowableArray<TokenPosition>* token_positions);
|
|
|
|
NOT_IN_PRODUCT(void PrintJSONInlineIntervals(JSONObject* jsobj));
|
|
|
|
void DumpInlineIntervals(uword start);
|
|
|
|
void DumpSourcePositions(uword start);
|
|
|
|
|
2018-04-26 20:33:15 +00:00
|
|
|
intptr_t GetNullCheckNameIndexAt(int32_t pc_offset);
|
|
|
|
|
2017-02-07 20:52:21 +00:00
|
|
|
private:
|
2020-12-16 15:13:02 +00:00
|
|
|
static const TokenPosition& InitialPosition() {
|
|
|
|
if (FLAG_precompiled_mode) {
|
|
|
|
// In precompiled mode, the CodeSourceMap stores lines instead of
|
|
|
|
// real token positions and uses kNoSourcePos for no line information.
|
|
|
|
return TokenPosition::kNoSource;
|
|
|
|
} else {
|
|
|
|
return CodeSourceMapBuilder::kInitialPosition;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-22 09:29:45 +00:00
|
|
|
// Reads a TokenPosition value from a CSM, handling the different encoding for
|
|
|
|
// when non-symbolic stack traces are enabled.
|
|
|
|
static TokenPosition ReadPosition(ReadStream* stream);
|
|
|
|
|
2017-02-07 20:52:21 +00:00
|
|
|
const CodeSourceMap& map_;
|
|
|
|
const Array& functions_;
|
|
|
|
const Function& root_;
|
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(CodeSourceMapReader);
|
|
|
|
};
|
|
|
|
|
2012-03-23 01:27:35 +00:00
|
|
|
} // namespace dart
|
|
|
|
|
2016-10-26 07:26:03 +00:00
|
|
|
#endif // RUNTIME_VM_CODE_DESCRIPTORS_H_
|