2016-10-15 20:48:46 +00:00
|
|
|
// Copyright (c) 2016, 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_KERNEL_H_
|
|
|
|
#define RUNTIME_VM_KERNEL_H_
|
2016-10-15 20:48:46 +00:00
|
|
|
|
2019-06-21 19:41:08 +00:00
|
|
|
#include <memory>
|
|
|
|
|
2016-10-15 20:48:46 +00:00
|
|
|
#include "platform/assert.h"
|
|
|
|
#include "vm/allocation.h"
|
|
|
|
#include "vm/globals.h"
|
2017-01-31 10:59:06 +00:00
|
|
|
#include "vm/growable_array.h"
|
2017-08-29 08:59:15 +00:00
|
|
|
#include "vm/object.h"
|
2016-11-21 13:13:46 +00:00
|
|
|
#include "vm/token_position.h"
|
2016-10-15 20:48:46 +00:00
|
|
|
|
2018-01-09 13:36:01 +00:00
|
|
|
namespace dart {
|
|
|
|
namespace kernel {
|
|
|
|
class NameIndex {
|
|
|
|
public:
|
2018-04-30 10:57:45 +00:00
|
|
|
static const int kInvalidName = -1;
|
|
|
|
|
|
|
|
NameIndex() : value_(kInvalidName) {}
|
2018-01-09 13:36:01 +00:00
|
|
|
explicit NameIndex(int value) : value_(value) {}
|
|
|
|
|
|
|
|
operator int() const { return value_; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
int value_;
|
|
|
|
};
|
2018-02-07 19:35:39 +00:00
|
|
|
} // namespace kernel
|
|
|
|
} // namespace dart
|
2018-01-09 13:36:01 +00:00
|
|
|
|
|
|
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
2016-10-15 20:48:46 +00:00
|
|
|
namespace dart {
|
|
|
|
|
2019-03-12 17:58:46 +00:00
|
|
|
class BitVector;
|
2016-11-21 14:53:00 +00:00
|
|
|
class Field;
|
|
|
|
class ParsedFunction;
|
|
|
|
class Zone;
|
|
|
|
|
2016-10-15 20:48:46 +00:00
|
|
|
namespace kernel {
|
|
|
|
|
|
|
|
class Reader;
|
2018-10-09 17:23:43 +00:00
|
|
|
struct ProcedureAttributesMetadata;
|
2020-02-13 15:32:48 +00:00
|
|
|
class TableSelectorMetadata;
|
2016-10-15 20:48:46 +00:00
|
|
|
|
2017-05-03 22:43:14 +00:00
|
|
|
class StringIndex {
|
|
|
|
public:
|
|
|
|
StringIndex() : value_(-1) {}
|
|
|
|
explicit StringIndex(int value) : value_(value) {}
|
|
|
|
|
|
|
|
operator int() const { return value_; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
int value_;
|
|
|
|
};
|
|
|
|
|
2017-08-17 12:34:00 +00:00
|
|
|
const uint8_t kNativeYieldFlags = 0x2;
|
2016-10-15 20:48:46 +00:00
|
|
|
|
2017-08-17 12:34:00 +00:00
|
|
|
enum LogicalOperator { kAnd, kOr };
|
2016-10-15 20:48:46 +00:00
|
|
|
|
2021-02-04 09:46:17 +00:00
|
|
|
struct ProgramBinary {
|
|
|
|
ProgramBinary SubView(intptr_t start, intptr_t end) const {
|
|
|
|
return {typed_data, kernel_data + start, end - start};
|
|
|
|
}
|
|
|
|
|
|
|
|
const ExternalTypedData* typed_data;
|
|
|
|
const uint8_t* kernel_data;
|
|
|
|
intptr_t kernel_data_size;
|
|
|
|
};
|
|
|
|
|
2017-06-30 05:55:03 +00:00
|
|
|
class Program {
|
|
|
|
public:
|
2018-06-21 23:27:53 +00:00
|
|
|
// Read a kernel Program from the given Reader. Note the returned Program
|
|
|
|
// can potentially contain several "sub programs", though the library count
|
|
|
|
// etc will reference the last "sub program" only.
|
2019-06-21 19:41:08 +00:00
|
|
|
static std::unique_ptr<Program> ReadFrom(Reader* reader,
|
|
|
|
const char** error = nullptr);
|
|
|
|
|
|
|
|
static std::unique_ptr<Program> ReadFromFile(const char* script_uri,
|
|
|
|
const char** error = nullptr);
|
|
|
|
static std::unique_ptr<Program> ReadFromBuffer(const uint8_t* buffer,
|
|
|
|
intptr_t buffer_length,
|
|
|
|
const char** error = nullptr);
|
|
|
|
static std::unique_ptr<Program> ReadFromTypedData(
|
|
|
|
const ExternalTypedData& typed_data, const char** error = nullptr);
|
2018-03-15 23:24:44 +00:00
|
|
|
|
[kernel] Allow VM to load concatenated dill file
The kernel format has been designed so that one can concatenate several
dill files into one file and then load it. For instance the dart
function BinaryBuilder.readProgram supports this.
Currently a dill file contains one or more programs.
In the VM each of these programs are called either program or subprogram.
Technically a dill "program" isn't necessarily a program at all (e.g. it
could be missing a library).
This naming snafu should probably be cleaned up at some point, but that's
for another CL.
When loading a dill file via BinaryBuilder.readProgram what happens is
this:
- Each program in the dill file ends in 4 bytes that indicates the size
of the program.
- Reading the input from the end one can then read the size, skip back
that amount of bytes, if we have more data (i.e. there's another
program), read another size and so on, and continue until we have
accounted for all bytes in the input.
- We then read each program from the start, and basically overwrite any
library, class, procedure etc. we find.
The first main reference found is the one used though.
(Saying that we overwrite is not completely true, but when the library
is a non-external library that's basically what happens).
This CL introduces (some) support on the C++ side for the same thing.
So far the C++ side could only handle single-program-dills, and trying
to load anything else would probably crash the VM.
The support added is this:
- Assume the SDK (i.e. vm_platform.dill) is not a concatenated file
(error out if it is).
- For user provided input, loop over each contained program one-by-one,
for each individual one behave as normal.
- The way LibraryLoad is implemented (i.e. it skips if the library is
already loaded) this means that it currently would behave differently
than the dart version (i.e. the first one is used, not the last one).
For now it is assumed that that's not a problem.
- There is a possibly snafu if the same script is included several times.
This could probably mostly be remedied by not creating scripts up front,
but only as needed. By the "keep only one" (and fixing the above point,
probably by simply loading in the opposite order, i.e. last program
in the binary first) the (theoretical) problem would probably do away.
Note that we will have separate string tables, canonical name tables etc
per "sub program" and that there might be some duplication.
The implementation was tested as indicated below, but introduces no tests.
$ cat test_lib1.dart
import "test_lib2.dart" as lib2;
String lib1field = "lib #1 field!!";
main() {
foo();
lib2.foo();
print("From lib2: ${lib2.lib2field}");
}
foo() {
print("Hello, Foo, from test_lib1!");
var x = 42;
print(x);
}
$ cat test_lib2.dart
String lib2field = "Lib #2 field!!!!";
foo() {
print("Hello, Foo, from test_lib2!");
var y = 34;
print(y);
}
$ out/ReleaseX64/dart pkg/front_end/tool/_fasta/compile.dart --packages=.packages --platform=out/ReleaseX64/vm_platform.dill test_lib1.dart
$ ls -lha test_lib1.dart.dill
[...] 4.2M Oct 26 14:42 test_lib1.dart.dill
$ dart pkg/kernel/bin/split.dart test_lib1.dart.dill
Wrote test_lib1.dart.dill.part1.dill
Wrote test_lib1.dart.dill.part2.dill
$ ls -lha test_lib1.dart.dill.part{1,2}.dill
[...] 811 Oct 26 14:42 test_lib1.dart.dill.part1.dill
[...] 582 Oct 26 14:42 test_lib1.dart.dill.part2.dill
$ cat test_lib1.dart.dill.part1.dill test_lib1.dart.dill.part2.dill > test_lib1.dart.dill.concat.dill
$ ls -lha test_lib1.dart.dill.concat.dill
[...] 1.4K Oct 26 14:44 test_lib1.dart.dill.concat.dill
$ out/ReleaseX64/dart --kernel-binaries=out/ReleaseX64 --packages=.packages test_lib1.dart.dill.concat.dill
Hello, Foo, from test_lib1!
42
Hello, Foo, from test_lib2!
34
From lib2: Lib #2 field!!!!
Change-Id: I233a033aa3042b202dd4708908a5be3089474588
Reviewed-on: https://dart-review.googlesource.com/16820
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
2017-10-27 12:01:48 +00:00
|
|
|
bool is_single_program() { return single_program_; }
|
2019-03-20 09:39:33 +00:00
|
|
|
uint32_t binary_version() { return binary_version_; }
|
2017-06-30 05:55:03 +00:00
|
|
|
NameIndex main_method() { return main_method_reference_; }
|
2017-10-10 00:50:31 +00:00
|
|
|
intptr_t source_table_offset() const { return source_table_offset_; }
|
|
|
|
intptr_t string_table_offset() const { return string_table_offset_; }
|
|
|
|
intptr_t name_table_offset() const { return name_table_offset_; }
|
2018-05-15 00:41:08 +00:00
|
|
|
intptr_t metadata_payloads_offset() const {
|
|
|
|
return metadata_payloads_offset_;
|
|
|
|
}
|
|
|
|
intptr_t metadata_mappings_offset() const {
|
|
|
|
return metadata_mappings_offset_;
|
|
|
|
}
|
[kernel] Add kernel2kernel constant evaluation, binary format as well as vm support
The introduced "constants" transformation can evaluate constant expressions. The
original use-sites of constant expressions are replaced by a new [ConstantExpression]
node, which points to a subclass of a new [Constant] class hierarchy. Constant
[Field]s and [VariableDeclarations]s will be removed, since all use-sites are
re-written.
The [Constant] class hierarchy is, similarly to the [DartType] class hierarchy, not
part of the AST tree (also has no parent pointer). The constants form a
DAG (directed acyclic graph).
There is no canonicalization requirement of the [Constant] objects referenced by the
AST (via [ConstantExpression]). Although it is beneficial to canonicalize them during
construction, since it reduces time spent in operator==/hashCode.
This CL furthermore adds support for a constant table in the binary format. Similarly
to [String]s, we canonicalize the constants before writing the table to the binary.
The constant table entries in the binary are written in a post-order way, to ensure
easy construction on the backend side.
The text format will be augmented with a "constants { ... }" section at the end,
which lists the constants in the same order as in the binary format.
The transformation can be used by those backends who choose to do so. It is not
enabled by default atm. It should therefore not affect analyzer, fasta or other
components.
Change-Id: I57cd9624fedcf537ab6870db76246149647bed21
Reviewed-on: https://dart-review.googlesource.com/14382
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Kevin Millikin <kmillikin@google.com>
2017-11-16 11:08:02 +00:00
|
|
|
intptr_t constant_table_offset() { return constant_table_offset_; }
|
[kernel] Change constant references; remove need for map
Previously constants were referenced via there relative binary offset,
i.e. a constant reference saying 42 meant at byte offset 42 relative to
the start of the constant table in the binary. This was done to be able
to (on the VM side) read the needed constants lazily. It meant, though,
that constants had to be stored in a map, mapping from the byte position
to the constant.
This change adds a level of indirection when needing the lazy reading,
but lets the constant references reference the constant number instead
so that a constant reference saying 42 means constant number 42,
i.e. constants can be stored in a list instead of in a map.
This is done on the dart side, but the VM still stores it in a map.
The level of indirection is a tabel next to the constant table where
each entry has constant size (4 bytes) from which one can read the
relative byte offset into the constant table from the constant number,
thus still being able to read needed constants lazily.
This CL also cleans up a leftover where for instance double constants
had their textual representation saved as a string in the string indexer
(and thus the output dill) even though they were never referenced.
File size changes:
* Platform: increses 7,816 bytes.
* Compile of dart2js (including platform): decreases 71,424 bytes.
Speed changes:
* Adding `UserTag`s to the code and looking at observatories cpu profile
on a `pkg/kernel/test/binary_bench.dart --golem AstFromBinaryLazy`
run of a compile of dart2js reading the constant table has gone
from ~10% to ~5%.
* Doing statistics on
`pkg/kernel/test/binary_bench.dart --raw AstFromBinaryLazy` run of a
compile of dart2js says -6.28169% +/- 4.97269%.
* Golem runs has nothing above the noise level.
It does say "AstFromBinaryLazy (Intel Xeon) -4.006% (0.4 noise)" and
"AstFromBinaryEagerP50 (Intel Core i5) -8.929% (0.6 noise)" though.
TEST=All tests running the VM tests this.
Change-Id: I07ead457527a4477de803ee55ba742f5557413d3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196925
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2021-05-04 11:08:31 +00:00
|
|
|
intptr_t component_index_offset() { return component_index_offset_; }
|
2017-06-30 05:55:03 +00:00
|
|
|
intptr_t library_count() { return library_count_; }
|
2020-05-01 04:03:04 +00:00
|
|
|
NNBDCompiledMode compilation_mode() const { return compilation_mode_; }
|
2016-10-15 20:48:46 +00:00
|
|
|
|
2021-02-04 09:46:17 +00:00
|
|
|
const ProgramBinary& binary() const { return binary_; }
|
|
|
|
const ExternalTypedData* typed_data() { return binary().typed_data; }
|
|
|
|
const uint8_t* kernel_data() { return binary().kernel_data; }
|
|
|
|
intptr_t kernel_data_size() { return binary().kernel_data_size; }
|
|
|
|
|
2016-10-15 20:48:46 +00:00
|
|
|
private:
|
2021-02-04 09:46:17 +00:00
|
|
|
Program() : binary_() {}
|
2016-10-15 20:48:46 +00:00
|
|
|
|
[kernel] Allow VM to load concatenated dill file
The kernel format has been designed so that one can concatenate several
dill files into one file and then load it. For instance the dart
function BinaryBuilder.readProgram supports this.
Currently a dill file contains one or more programs.
In the VM each of these programs are called either program or subprogram.
Technically a dill "program" isn't necessarily a program at all (e.g. it
could be missing a library).
This naming snafu should probably be cleaned up at some point, but that's
for another CL.
When loading a dill file via BinaryBuilder.readProgram what happens is
this:
- Each program in the dill file ends in 4 bytes that indicates the size
of the program.
- Reading the input from the end one can then read the size, skip back
that amount of bytes, if we have more data (i.e. there's another
program), read another size and so on, and continue until we have
accounted for all bytes in the input.
- We then read each program from the start, and basically overwrite any
library, class, procedure etc. we find.
The first main reference found is the one used though.
(Saying that we overwrite is not completely true, but when the library
is a non-external library that's basically what happens).
This CL introduces (some) support on the C++ side for the same thing.
So far the C++ side could only handle single-program-dills, and trying
to load anything else would probably crash the VM.
The support added is this:
- Assume the SDK (i.e. vm_platform.dill) is not a concatenated file
(error out if it is).
- For user provided input, loop over each contained program one-by-one,
for each individual one behave as normal.
- The way LibraryLoad is implemented (i.e. it skips if the library is
already loaded) this means that it currently would behave differently
than the dart version (i.e. the first one is used, not the last one).
For now it is assumed that that's not a problem.
- There is a possibly snafu if the same script is included several times.
This could probably mostly be remedied by not creating scripts up front,
but only as needed. By the "keep only one" (and fixing the above point,
probably by simply loading in the opposite order, i.e. last program
in the binary first) the (theoretical) problem would probably do away.
Note that we will have separate string tables, canonical name tables etc
per "sub program" and that there might be some duplication.
The implementation was tested as indicated below, but introduces no tests.
$ cat test_lib1.dart
import "test_lib2.dart" as lib2;
String lib1field = "lib #1 field!!";
main() {
foo();
lib2.foo();
print("From lib2: ${lib2.lib2field}");
}
foo() {
print("Hello, Foo, from test_lib1!");
var x = 42;
print(x);
}
$ cat test_lib2.dart
String lib2field = "Lib #2 field!!!!";
foo() {
print("Hello, Foo, from test_lib2!");
var y = 34;
print(y);
}
$ out/ReleaseX64/dart pkg/front_end/tool/_fasta/compile.dart --packages=.packages --platform=out/ReleaseX64/vm_platform.dill test_lib1.dart
$ ls -lha test_lib1.dart.dill
[...] 4.2M Oct 26 14:42 test_lib1.dart.dill
$ dart pkg/kernel/bin/split.dart test_lib1.dart.dill
Wrote test_lib1.dart.dill.part1.dill
Wrote test_lib1.dart.dill.part2.dill
$ ls -lha test_lib1.dart.dill.part{1,2}.dill
[...] 811 Oct 26 14:42 test_lib1.dart.dill.part1.dill
[...] 582 Oct 26 14:42 test_lib1.dart.dill.part2.dill
$ cat test_lib1.dart.dill.part1.dill test_lib1.dart.dill.part2.dill > test_lib1.dart.dill.concat.dill
$ ls -lha test_lib1.dart.dill.concat.dill
[...] 1.4K Oct 26 14:44 test_lib1.dart.dill.concat.dill
$ out/ReleaseX64/dart --kernel-binaries=out/ReleaseX64 --packages=.packages test_lib1.dart.dill.concat.dill
Hello, Foo, from test_lib1!
42
Hello, Foo, from test_lib2!
34
From lib2: Lib #2 field!!!!
Change-Id: I233a033aa3042b202dd4708908a5be3089474588
Reviewed-on: https://dart-review.googlesource.com/16820
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
2017-10-27 12:01:48 +00:00
|
|
|
bool single_program_;
|
2019-03-20 09:39:33 +00:00
|
|
|
uint32_t binary_version_;
|
2017-06-30 05:55:03 +00:00
|
|
|
NameIndex main_method_reference_; // Procedure.
|
2020-05-01 04:03:04 +00:00
|
|
|
NNBDCompiledMode compilation_mode_;
|
2017-06-30 05:55:03 +00:00
|
|
|
intptr_t library_count_;
|
2016-10-15 20:48:46 +00:00
|
|
|
|
2017-09-06 06:38:14 +00:00
|
|
|
// The offset from the start of the binary to the start of the source table.
|
|
|
|
intptr_t source_table_offset_;
|
2017-04-21 08:32:43 +00:00
|
|
|
|
[kernel] Add kernel2kernel constant evaluation, binary format as well as vm support
The introduced "constants" transformation can evaluate constant expressions. The
original use-sites of constant expressions are replaced by a new [ConstantExpression]
node, which points to a subclass of a new [Constant] class hierarchy. Constant
[Field]s and [VariableDeclarations]s will be removed, since all use-sites are
re-written.
The [Constant] class hierarchy is, similarly to the [DartType] class hierarchy, not
part of the AST tree (also has no parent pointer). The constants form a
DAG (directed acyclic graph).
There is no canonicalization requirement of the [Constant] objects referenced by the
AST (via [ConstantExpression]). Although it is beneficial to canonicalize them during
construction, since it reduces time spent in operator==/hashCode.
This CL furthermore adds support for a constant table in the binary format. Similarly
to [String]s, we canonicalize the constants before writing the table to the binary.
The constant table entries in the binary are written in a post-order way, to ensure
easy construction on the backend side.
The text format will be augmented with a "constants { ... }" section at the end,
which lists the constants in the same order as in the binary format.
The transformation can be used by those backends who choose to do so. It is not
enabled by default atm. It should therefore not affect analyzer, fasta or other
components.
Change-Id: I57cd9624fedcf537ab6870db76246149647bed21
Reviewed-on: https://dart-review.googlesource.com/14382
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Kevin Millikin <kmillikin@google.com>
2017-11-16 11:08:02 +00:00
|
|
|
// The offset from the start of the binary to the start of the constant table.
|
|
|
|
intptr_t constant_table_offset_;
|
|
|
|
|
[kernel] Change constant references; remove need for map
Previously constants were referenced via there relative binary offset,
i.e. a constant reference saying 42 meant at byte offset 42 relative to
the start of the constant table in the binary. This was done to be able
to (on the VM side) read the needed constants lazily. It meant, though,
that constants had to be stored in a map, mapping from the byte position
to the constant.
This change adds a level of indirection when needing the lazy reading,
but lets the constant references reference the constant number instead
so that a constant reference saying 42 means constant number 42,
i.e. constants can be stored in a list instead of in a map.
This is done on the dart side, but the VM still stores it in a map.
The level of indirection is a tabel next to the constant table where
each entry has constant size (4 bytes) from which one can read the
relative byte offset into the constant table from the constant number,
thus still being able to read needed constants lazily.
This CL also cleans up a leftover where for instance double constants
had their textual representation saved as a string in the string indexer
(and thus the output dill) even though they were never referenced.
File size changes:
* Platform: increses 7,816 bytes.
* Compile of dart2js (including platform): decreases 71,424 bytes.
Speed changes:
* Adding `UserTag`s to the code and looking at observatories cpu profile
on a `pkg/kernel/test/binary_bench.dart --golem AstFromBinaryLazy`
run of a compile of dart2js reading the constant table has gone
from ~10% to ~5%.
* Doing statistics on
`pkg/kernel/test/binary_bench.dart --raw AstFromBinaryLazy` run of a
compile of dart2js says -6.28169% +/- 4.97269%.
* Golem runs has nothing above the noise level.
It does say "AstFromBinaryLazy (Intel Xeon) -4.006% (0.4 noise)" and
"AstFromBinaryEagerP50 (Intel Core i5) -8.929% (0.6 noise)" though.
TEST=All tests running the VM tests this.
Change-Id: I07ead457527a4477de803ee55ba742f5557413d3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196925
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2021-05-04 11:08:31 +00:00
|
|
|
// The offset from the start of the binary to the start of the ending-index.
|
|
|
|
intptr_t component_index_offset_;
|
|
|
|
|
2017-05-03 17:27:01 +00:00
|
|
|
// The offset from the start of the binary to the canonical name table.
|
|
|
|
intptr_t name_table_offset_;
|
|
|
|
|
2018-05-15 00:41:08 +00:00
|
|
|
// The offset from the start of the binary to the metadata payloads.
|
|
|
|
intptr_t metadata_payloads_offset_;
|
|
|
|
|
|
|
|
// The offset from the start of the binary to the metadata mappings.
|
|
|
|
intptr_t metadata_mappings_offset_;
|
|
|
|
|
2017-09-06 06:38:14 +00:00
|
|
|
// The offset from the start of the binary to the start of the string table.
|
|
|
|
intptr_t string_table_offset_;
|
|
|
|
|
2021-02-04 09:46:17 +00:00
|
|
|
ProgramBinary binary_;
|
2016-10-15 20:48:46 +00:00
|
|
|
|
2017-06-30 05:55:03 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(Program);
|
2016-10-15 20:48:46 +00:00
|
|
|
};
|
|
|
|
|
2017-12-01 05:16:48 +00:00
|
|
|
class KernelLineStartsReader {
|
|
|
|
public:
|
|
|
|
KernelLineStartsReader(const dart::TypedData& line_starts_data,
|
|
|
|
dart::Zone* zone);
|
|
|
|
|
|
|
|
~KernelLineStartsReader() { delete helper_; }
|
|
|
|
|
|
|
|
int32_t DeltaAt(intptr_t index) const {
|
|
|
|
return helper_->At(line_starts_data_, index);
|
|
|
|
}
|
|
|
|
|
[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
|
|
|
int32_t MaxPosition() const;
|
|
|
|
|
[vm] Signal bad token positions and lines in KernelLineStartsReader.
First, change LocationForPosition and TokenRangeAtLine to return
whether they successfully located the offset/line. Also change the
wrappers in Script (GetTokenLocation and TokenRangeAtLine) to return
whether or not any information was successfully located.
These methods now only change the out parameters in the case that
appropriate information was found, so any unconditional uses of the out
parameters need the out parameters to be appropriately initialized.
We now allow negative lines to be requested in TokenRangeAtLine (with
the failure behavior described above) so the line returned by
LocationAtPosition can be fed into TokenRangeAtLine without intermediate
checking.
The calculation of the token length, which uses the script source and
not the line starts array, has been moved to a new method,
Script::GetTokenLength. The new method returns the length (or a
negative value if the token length could not be determined) instead of
using an out parameter.
TEST=Existing tests on trybots, to ensure tests using current
line/number info aren't affected.
Bug: https://github.com/dart-lang/sdk/issues/44436
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-product-x64-try,vm-kernel-linux-product-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-linux-release-simarm-try
Change-Id: Ibc048a226d11ff9a340a8d249654d07720fdf115
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175365
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Clement Skau <cskau@google.com>
2020-12-16 11:14:12 +00:00
|
|
|
// Returns whether the given offset corresponds to a valid source offset
|
|
|
|
// If it does, then *line and *column (if column is not nullptr) are set
|
|
|
|
// to the line and column the token starts at.
|
|
|
|
DART_WARN_UNUSED_RESULT bool LocationForPosition(
|
|
|
|
intptr_t position,
|
|
|
|
intptr_t* line,
|
|
|
|
intptr_t* col = nullptr) const;
|
|
|
|
|
|
|
|
// Returns whether any tokens were found for the given line. When found,
|
|
|
|
// *first_token_index and *last_token_index are set to the first and
|
|
|
|
// last token on the line, respectively.
|
|
|
|
DART_WARN_UNUSED_RESULT bool TokenRangeAtLine(
|
|
|
|
intptr_t line_number,
|
|
|
|
dart::TokenPosition* first_token_index,
|
|
|
|
dart::TokenPosition* last_token_index) const;
|
2017-12-01 05:16:48 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
class KernelLineStartsHelper {
|
|
|
|
public:
|
|
|
|
KernelLineStartsHelper() {}
|
|
|
|
virtual ~KernelLineStartsHelper() {}
|
|
|
|
virtual int32_t At(const dart::TypedData& data, intptr_t index) const = 0;
|
|
|
|
|
|
|
|
private:
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(KernelLineStartsHelper);
|
|
|
|
};
|
|
|
|
|
|
|
|
class KernelInt8LineStartsHelper : public KernelLineStartsHelper {
|
|
|
|
public:
|
|
|
|
KernelInt8LineStartsHelper() {}
|
|
|
|
virtual int32_t At(const dart::TypedData& data, intptr_t index) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(KernelInt8LineStartsHelper);
|
|
|
|
};
|
|
|
|
|
|
|
|
class KernelInt16LineStartsHelper : public KernelLineStartsHelper {
|
|
|
|
public:
|
|
|
|
KernelInt16LineStartsHelper() {}
|
|
|
|
virtual int32_t At(const dart::TypedData& data, intptr_t index) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(KernelInt16LineStartsHelper);
|
|
|
|
};
|
|
|
|
|
|
|
|
class KernelInt32LineStartsHelper : public KernelLineStartsHelper {
|
|
|
|
public:
|
|
|
|
KernelInt32LineStartsHelper() {}
|
|
|
|
virtual int32_t At(const dart::TypedData& data, intptr_t index) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(KernelInt32LineStartsHelper);
|
|
|
|
};
|
|
|
|
|
|
|
|
const dart::TypedData& line_starts_data_;
|
|
|
|
KernelLineStartsHelper* helper_;
|
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(KernelLineStartsReader);
|
|
|
|
};
|
|
|
|
|
2018-07-17 16:36:50 +00:00
|
|
|
void CollectTokenPositionsFor(const Script& script);
|
|
|
|
|
2020-12-08 10:47:43 +00:00
|
|
|
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
ArrayPtr CollectConstConstructorCoverageFrom(const Script& interesting_script);
|
|
|
|
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
|
2020-11-06 10:41:43 +00:00
|
|
|
ObjectPtr EvaluateStaticConstFieldInitializer(const Field& field);
|
2020-12-07 19:43:48 +00:00
|
|
|
ObjectPtr EvaluateMetadata(const Library& library,
|
|
|
|
intptr_t kernel_offset,
|
2020-04-25 05:21:27 +00:00
|
|
|
bool is_annotations_offset);
|
|
|
|
ObjectPtr BuildParameterDescriptor(const Function& function);
|
2018-07-17 16:36:50 +00:00
|
|
|
|
2019-03-12 17:58:46 +00:00
|
|
|
// Fills in [is_covariant] and [is_generic_covariant_impl] vectors
|
|
|
|
// according to covariance attributes of [function] parameters.
|
|
|
|
//
|
|
|
|
// [is_covariant] and [is_generic_covariant_impl] should contain bitvectors
|
|
|
|
// of function.NumParameters() length.
|
|
|
|
void ReadParameterCovariance(const Function& function,
|
|
|
|
BitVector* is_covariant,
|
|
|
|
BitVector* is_generic_covariant_impl);
|
|
|
|
|
2018-07-17 16:36:50 +00:00
|
|
|
// Returns true if the given function needs dynamic invocation forwarder:
|
|
|
|
// that is if any of the arguments require checking on the dynamic
|
|
|
|
// call-site: if function has no parameters or has only covariant parameters
|
|
|
|
// as such function already checks all of its parameters.
|
|
|
|
bool NeedsDynamicInvocationForwarder(const Function& function);
|
|
|
|
|
2018-10-09 17:23:43 +00:00
|
|
|
ProcedureAttributesMetadata ProcedureAttributesOf(const Function& function,
|
|
|
|
Zone* zone);
|
|
|
|
|
|
|
|
ProcedureAttributesMetadata ProcedureAttributesOf(const Field& field,
|
|
|
|
Zone* zone);
|
2018-09-28 23:49:09 +00:00
|
|
|
|
2020-02-13 15:32:48 +00:00
|
|
|
TableSelectorMetadata* TableSelectorMetadataForProgram(
|
|
|
|
const KernelProgramInfo& info,
|
|
|
|
Zone* zone);
|
|
|
|
|
2016-10-15 20:48:46 +00:00
|
|
|
} // namespace kernel
|
|
|
|
} // namespace dart
|
|
|
|
|
2016-11-16 12:56:20 +00:00
|
|
|
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
2016-10-26 07:26:03 +00:00
|
|
|
#endif // RUNTIME_VM_KERNEL_H_
|