mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:09:49 +00:00
Revert "[vm/aot] Remove object wrapping of bare instructions for AOT snapshots."
This reverts commit 7475c637c3
.
Reason for revert: Breakage on simarm_x64 (and thus arm_x64)
Original change's description:
> [vm/aot] Remove object wrapping of bare instructions for AOT snapshots.
>
> Now, when writing an AOT snapshot in bare instructions mode, only
> the actual instructions in the RawInstructions payload are serialized
> instead of the entire RawInstructions object.
>
> Since there are no longer RawInstructions objects in these AOT
> snapshots, we also change how Code objects are serialized. Instead
> of just containing a reference to the RawInstructions object, we
> serialize two pieces of information: where the instructions
> payload for this Code object begins and whether there was a single
> entry for the instructions payload. (To save space, the single
> entry bit is serialized as the low order bit of the unchecked
> offset, which was already being serialized).
>
> While we also need the length of the instructions payload, we
> approximate it for all but the last Code object by subtracting
> the next Code object's payload start from this Code object's
> payload start. For the last Code object, we assume it extends
> to the end of the instructions image.
>
> Changes on flutter gallery in release mode:
> armv7: instructions size -2.66%, total size -1.68%
> armv8: instructions size -5.81%, total size -3.49%
>
> Fixes https://github.com/dart-lang/sdk/issues/38451.
>
> Change-Id: Ia458e8d99bae18f5c3b6e849df2519027f06f574
> Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-linux-release-simarm_x64-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-precomp-win-release-x64-try
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/131067
> Commit-Queue: Teagan Strickland <sstrickl@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
TBR=kustermann@google.com,rmacnak@google.com,sstrickl@google.com
Change-Id: If2c8ca6b0993211b2509b275af7ff11a8fa2baa3
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try, vm-kernel-precomp-linux-release-simarm-try, vm-kernel-precomp-linux-release-simarm64-try, vm-kernel-precomp-linux-release-simarm_x64-try, vm-kernel-precomp-android-release-arm64-try, vm-kernel-precomp-android-release-arm_x64-try, vm-kernel-precomp-mac-release-simarm64-try, vm-kernel-precomp-win-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134322
Reviewed-by: Teagan Strickland <sstrickl@google.com>
Commit-Queue: Teagan Strickland <sstrickl@google.com>
This commit is contained in:
parent
592e59691b
commit
bb24f98616
|
@ -11,12 +11,7 @@ import "package:vm/v8_snapshot_profile.dart";
|
||||||
|
|
||||||
import 'use_flag_test_helper.dart';
|
import 'use_flag_test_helper.dart';
|
||||||
|
|
||||||
test(
|
test({String dillPath, bool useAsm, bool stripFlag, bool stripUtil}) async {
|
||||||
{String dillPath,
|
|
||||||
bool useAsm,
|
|
||||||
bool useBare,
|
|
||||||
bool stripFlag,
|
|
||||||
bool stripUtil}) async {
|
|
||||||
// The assembler may add extra unnecessary information to the compiled
|
// The assembler may add extra unnecessary information to the compiled
|
||||||
// snapshot whether or not we generate DWARF information in the assembly, so
|
// snapshot whether or not we generate DWARF information in the assembly, so
|
||||||
// we force the use of a utility when generating assembly.
|
// we force the use of a utility when generating assembly.
|
||||||
|
@ -28,7 +23,6 @@ test(
|
||||||
|
|
||||||
final tempDirPrefix = 'v8-snapshot-profile' +
|
final tempDirPrefix = 'v8-snapshot-profile' +
|
||||||
(useAsm ? '-assembly' : '-elf') +
|
(useAsm ? '-assembly' : '-elf') +
|
||||||
(useBare ? '-bare' : '-nonbare') +
|
|
||||||
(stripFlag ? '-intstrip' : '') +
|
(stripFlag ? '-intstrip' : '') +
|
||||||
(stripUtil ? '-extstrip' : '');
|
(stripUtil ? '-extstrip' : '');
|
||||||
|
|
||||||
|
@ -38,7 +32,6 @@ test(
|
||||||
final snapshotPath = path.join(tempDir, 'test.snap');
|
final snapshotPath = path.join(tempDir, 'test.snap');
|
||||||
final commonSnapshotArgs = [
|
final commonSnapshotArgs = [
|
||||||
if (stripFlag) '--strip',
|
if (stripFlag) '--strip',
|
||||||
useBare ? '--use-bare-instructions' : '--no-use-bare-instructions',
|
|
||||||
"--write-v8-snapshot-profile-to=$profilePath",
|
"--write-v8-snapshot-profile-to=$profilePath",
|
||||||
dillPath,
|
dillPath,
|
||||||
];
|
];
|
||||||
|
@ -78,7 +71,7 @@ test(
|
||||||
// graph (in some cases the shallow size can legitimately be 0, e.g. for
|
// graph (in some cases the shallow size can legitimately be 0, e.g. for
|
||||||
// "base objects").
|
// "base objects").
|
||||||
for (final int node in profile.nodes) {
|
for (final int node in profile.nodes) {
|
||||||
Expect.notEquals("Unknown", profile[node].type,
|
Expect.notEquals(profile[node].type, "Unknown",
|
||||||
"unknown node at ID ${profile[node].id}");
|
"unknown node at ID ${profile[node].id}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +89,6 @@ test(
|
||||||
final actual = await File(strippedPath).length();
|
final actual = await File(strippedPath).length();
|
||||||
final expected = profile.accountedBytes;
|
final expected = profile.accountedBytes;
|
||||||
|
|
||||||
final bareUsed = useBare ? "bare" : "non-bare";
|
|
||||||
final fileType = useAsm ? "assembly" : "ELF";
|
final fileType = useAsm ? "assembly" : "ELF";
|
||||||
String stripPrefix = "";
|
String stripPrefix = "";
|
||||||
if (stripFlag && stripUtil) {
|
if (stripFlag && stripUtil) {
|
||||||
|
@ -108,7 +100,7 @@ test(
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect.approxEquals(expected, actual, 0.03 * actual,
|
Expect.approxEquals(expected, actual, 0.03 * actual,
|
||||||
"failed on $bareUsed $stripPrefix$fileType snapshot type.");
|
"failed on $stripPrefix$fileType snapshot type.");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,17 +214,7 @@ main() async {
|
||||||
|
|
||||||
// Test stripped ELF generation directly.
|
// Test stripped ELF generation directly.
|
||||||
await test(
|
await test(
|
||||||
dillPath: dillPath,
|
dillPath: dillPath, stripFlag: true, stripUtil: false, useAsm: false);
|
||||||
stripFlag: true,
|
|
||||||
stripUtil: false,
|
|
||||||
useAsm: false,
|
|
||||||
useBare: false);
|
|
||||||
await test(
|
|
||||||
dillPath: dillPath,
|
|
||||||
stripFlag: true,
|
|
||||||
stripUtil: false,
|
|
||||||
useAsm: false,
|
|
||||||
useBare: true);
|
|
||||||
|
|
||||||
// We neither generate assembly nor have a stripping utility on Windows.
|
// We neither generate assembly nor have a stripping utility on Windows.
|
||||||
if (Platform.isWindows) {
|
if (Platform.isWindows) {
|
||||||
|
@ -246,17 +228,7 @@ main() async {
|
||||||
} else {
|
} else {
|
||||||
// Test unstripped ELF generation that is then stripped externally.
|
// Test unstripped ELF generation that is then stripped externally.
|
||||||
await test(
|
await test(
|
||||||
dillPath: dillPath,
|
dillPath: dillPath, stripFlag: false, stripUtil: true, useAsm: false);
|
||||||
stripFlag: false,
|
|
||||||
stripUtil: true,
|
|
||||||
useAsm: false,
|
|
||||||
useBare: false);
|
|
||||||
await test(
|
|
||||||
dillPath: dillPath,
|
|
||||||
stripFlag: false,
|
|
||||||
stripUtil: true,
|
|
||||||
useAsm: false,
|
|
||||||
useBare: true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(sstrickl): Currently we can't assemble for SIMARM64 on MacOSX.
|
// TODO(sstrickl): Currently we can't assemble for SIMARM64 on MacOSX.
|
||||||
|
@ -269,29 +241,9 @@ main() async {
|
||||||
|
|
||||||
// Test stripped assembly generation that is then compiled and stripped.
|
// Test stripped assembly generation that is then compiled and stripped.
|
||||||
await test(
|
await test(
|
||||||
dillPath: dillPath,
|
dillPath: dillPath, stripFlag: true, stripUtil: true, useAsm: true);
|
||||||
stripFlag: true,
|
|
||||||
stripUtil: true,
|
|
||||||
useAsm: true,
|
|
||||||
useBare: false);
|
|
||||||
await test(
|
|
||||||
dillPath: dillPath,
|
|
||||||
stripFlag: true,
|
|
||||||
stripUtil: true,
|
|
||||||
useAsm: true,
|
|
||||||
useBare: true);
|
|
||||||
// Test unstripped assembly generation that is then compiled and stripped.
|
// Test unstripped assembly generation that is then compiled and stripped.
|
||||||
await test(
|
await test(
|
||||||
dillPath: dillPath,
|
dillPath: dillPath, stripFlag: false, stripUtil: true, useAsm: true);
|
||||||
stripFlag: false,
|
|
||||||
stripUtil: true,
|
|
||||||
useAsm: true,
|
|
||||||
useBare: false);
|
|
||||||
await test(
|
|
||||||
dillPath: dillPath,
|
|
||||||
stripFlag: false,
|
|
||||||
stripUtil: true,
|
|
||||||
useAsm: true,
|
|
||||||
useBare: true);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ namespace dart {
|
||||||
V(Code) \
|
V(Code) \
|
||||||
V(Bytecode) \
|
V(Bytecode) \
|
||||||
V(Instructions) \
|
V(Instructions) \
|
||||||
V(InstructionsSection) \
|
|
||||||
V(ObjectPool) \
|
V(ObjectPool) \
|
||||||
V(PcDescriptors) \
|
V(PcDescriptors) \
|
||||||
V(CodeSourceMap) \
|
V(CodeSourceMap) \
|
||||||
|
|
|
@ -1509,16 +1509,15 @@ class CodeSerializationCluster : public SerializationCluster {
|
||||||
s->UnexpectedObject(code, "Disabled code");
|
s->UnexpectedObject(code, "Disabled code");
|
||||||
}
|
}
|
||||||
|
|
||||||
s->WriteInstructions(code->ptr()->instructions_,
|
s->WriteInstructions(code->ptr()->instructions_, code);
|
||||||
code->ptr()->unchecked_offset_, code);
|
s->WriteUnsigned(code->ptr()->unchecked_offset_);
|
||||||
if (kind == Snapshot::kFullJIT) {
|
if (kind == Snapshot::kFullJIT) {
|
||||||
// TODO(rmacnak): Fix references to disabled code before serializing.
|
// TODO(rmacnak): Fix references to disabled code before serializing.
|
||||||
// For now, we may write the FixCallersTarget or equivalent stub. This
|
// For now, we may write the FixCallersTarget or equivalent stub. This
|
||||||
// will cause a fixup if this code is called.
|
// will cause a fixup if this code is called.
|
||||||
const uint32_t active_unchecked_offset =
|
s->WriteInstructions(code->ptr()->active_instructions_, code);
|
||||||
code->ptr()->unchecked_entry_point_ - code->ptr()->entry_point_;
|
s->WriteUnsigned(code->ptr()->unchecked_entry_point_ -
|
||||||
s->WriteInstructions(code->ptr()->active_instructions_,
|
code->ptr()->entry_point_);
|
||||||
active_unchecked_offset, code);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteField(code, object_pool_);
|
WriteField(code, object_pool_);
|
||||||
|
@ -1599,10 +1598,24 @@ class CodeDeserializationCluster : public DeserializationCluster {
|
||||||
|
|
||||||
void ReadFill(Deserializer* d) {
|
void ReadFill(Deserializer* d) {
|
||||||
for (intptr_t id = start_index_; id < stop_index_; id++) {
|
for (intptr_t id = start_index_; id < stop_index_; id++) {
|
||||||
auto const code = reinterpret_cast<RawCode*>(d->Ref(id));
|
RawCode* code = reinterpret_cast<RawCode*>(d->Ref(id));
|
||||||
Deserializer::InitializeHeader(code, kCodeCid, Code::InstanceSize(0));
|
Deserializer::InitializeHeader(code, kCodeCid, Code::InstanceSize(0));
|
||||||
|
|
||||||
d->ReadInstructions(code);
|
RawInstructions* instr = d->ReadInstructions();
|
||||||
|
uint32_t unchecked_offset = d->ReadUnsigned();
|
||||||
|
|
||||||
|
code->ptr()->instructions_ = instr;
|
||||||
|
|
||||||
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||||
|
code->ptr()->unchecked_offset_ = unchecked_offset;
|
||||||
|
if (d->kind() == Snapshot::kFullJIT) {
|
||||||
|
instr = d->ReadInstructions();
|
||||||
|
unchecked_offset = d->ReadUnsigned();
|
||||||
|
}
|
||||||
|
code->ptr()->active_instructions_ = instr;
|
||||||
|
#endif // !DART_PRECOMPILED_RUNTIME
|
||||||
|
|
||||||
|
Code::InitializeCachedEntryPointsFrom(code, instr, unchecked_offset);
|
||||||
|
|
||||||
code->ptr()->object_pool_ =
|
code->ptr()->object_pool_ =
|
||||||
reinterpret_cast<RawObjectPool*>(d->ReadRef());
|
reinterpret_cast<RawObjectPool*>(d->ReadRef());
|
||||||
|
@ -1638,32 +1651,7 @@ class CodeDeserializationCluster : public DeserializationCluster {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
code->ptr()->state_bits_ = d->Read<int32_t>();
|
code->ptr()->state_bits_ = d->Read<int32_t>();
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
|
||||||
if (FLAG_use_bare_instructions && id != start_index_) {
|
|
||||||
// The following assumes that ReadInstructions put the offset of the
|
|
||||||
// entry point from the payload start into instructions_length_. We
|
|
||||||
// use this to calculate the length of the previous payload.
|
|
||||||
RawCode* prev = reinterpret_cast<RawCode*>(d->Ref(id - 1));
|
|
||||||
const uword prev_payload_start =
|
|
||||||
prev->ptr()->entry_point_ - prev->ptr()->instructions_length_;
|
|
||||||
const uword curr_payload_start =
|
|
||||||
code->ptr()->entry_point_ - code->ptr()->instructions_length_;
|
|
||||||
prev->ptr()->instructions_length_ =
|
|
||||||
curr_payload_start - prev_payload_start;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
|
||||||
if (FLAG_use_bare_instructions) {
|
|
||||||
// Since there is no following Code object, we assume that the last Code
|
|
||||||
// object ends at the end of the instructions snapshot.
|
|
||||||
auto const code = reinterpret_cast<RawCode*>(d->Ref(stop_index_ - 1));
|
|
||||||
const uword curr_payload_start =
|
|
||||||
code->ptr()->entry_point_ - code->ptr()->instructions_length_;
|
|
||||||
code->ptr()->instructions_length_ =
|
|
||||||
d->GetBareInstructionsEnd() - curr_payload_start;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
|
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
|
||||||
|
@ -4687,9 +4675,7 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||||
void Serializer::WriteInstructions(RawInstructions* instr,
|
void Serializer::WriteInstructions(RawInstructions* instr, RawCode* code) {
|
||||||
uint32_t unchecked_offset,
|
|
||||||
RawCode* code) {
|
|
||||||
ASSERT(code != Code::null());
|
ASSERT(code != Code::null());
|
||||||
|
|
||||||
const intptr_t offset = image_writer_->GetTextOffsetFor(instr, code);
|
const intptr_t offset = image_writer_->GetTextOffsetFor(instr, code);
|
||||||
|
@ -4698,17 +4684,6 @@ void Serializer::WriteInstructions(RawInstructions* instr,
|
||||||
UnexpectedObject(code, "Expected instructions to reuse");
|
UnexpectedObject(code, "Expected instructions to reuse");
|
||||||
}
|
}
|
||||||
Write<uint32_t>(offset);
|
Write<uint32_t>(offset);
|
||||||
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
|
|
||||||
// When writing only instruction payloads, we also need to serialize
|
|
||||||
// whether there was a single entry. We add this as the low order bit
|
|
||||||
// in the unchecked_offset.
|
|
||||||
ASSERT(unchecked_offset <= kMaxInt32);
|
|
||||||
const uint32_t payload_info =
|
|
||||||
(unchecked_offset << 1) | (Code::HasMonomorphicEntry(code) ? 0x1 : 0x0);
|
|
||||||
WriteUnsigned(payload_info);
|
|
||||||
} else {
|
|
||||||
WriteUnsigned(unchecked_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If offset < 0, it's pointing to a shared instruction. We don't profile
|
// If offset < 0, it's pointing to a shared instruction. We don't profile
|
||||||
// references to shared text/data (since they don't consume any space). Of
|
// references to shared text/data (since they don't consume any space). Of
|
||||||
|
@ -5448,74 +5423,11 @@ RawApiError* FullSnapshotReader::ConvertToApiError(char* message) {
|
||||||
return ApiError::New(msg, Heap::kOld);
|
return ApiError::New(msg, Heap::kOld);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Deserializer::ReadInstructions(RawCode* code) {
|
RawInstructions* Deserializer::ReadInstructions() {
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
uint32_t offset = Read<uint32_t>();
|
||||||
if (FLAG_use_bare_instructions) {
|
return image_reader_->GetInstructionsAt(offset);
|
||||||
const uint32_t bare_offset = Read<uint32_t>();
|
|
||||||
const uword payload_start =
|
|
||||||
image_reader_->GetBareInstructionsAt(bare_offset);
|
|
||||||
const uint32_t payload_info = ReadUnsigned();
|
|
||||||
const uint32_t unchecked_offset = payload_info >> 1;
|
|
||||||
const bool has_monomorphic_entrypoint = (payload_info & 0x1) == 0x1;
|
|
||||||
|
|
||||||
const uword entry_offset = has_monomorphic_entrypoint
|
|
||||||
? Instructions::kPolymorphicEntryOffsetAOT
|
|
||||||
: 0;
|
|
||||||
const uword monomorphic_entry_offset =
|
|
||||||
has_monomorphic_entrypoint ? Instructions::kMonomorphicEntryOffsetAOT
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
const uword entry_point = payload_start + entry_offset;
|
|
||||||
const uword monomorphic_entry_point =
|
|
||||||
payload_start + monomorphic_entry_offset;
|
|
||||||
|
|
||||||
code->ptr()->instructions_ = Instructions::null();
|
|
||||||
code->ptr()->entry_point_ = entry_point;
|
|
||||||
code->ptr()->unchecked_entry_point_ = entry_point + unchecked_offset;
|
|
||||||
code->ptr()->monomorphic_entry_point_ = monomorphic_entry_point;
|
|
||||||
code->ptr()->monomorphic_unchecked_entry_point_ =
|
|
||||||
monomorphic_entry_point + unchecked_offset;
|
|
||||||
// We don't serialize the length of the instructions payload. Instead, the
|
|
||||||
// deserializer calculates an approximate length (may include padding)
|
|
||||||
// by subtracting the payload offset of the next Code object (if any)
|
|
||||||
// from this one. (For the last Code object, we assume its serialization
|
|
||||||
// extends to the end of the instructions image.)
|
|
||||||
//
|
|
||||||
// Since the Code object doesn't include a field for the payload start,
|
|
||||||
// we store the entry_offset (calculated above) in instructions_length_
|
|
||||||
// for now, and subtract it from entry_point_ later after reading the
|
|
||||||
// next Code object.
|
|
||||||
ASSERT(entry_offset <= kMaxUint32);
|
|
||||||
code->ptr()->instructions_length_ = entry_offset;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const uint32_t offset = Read<uint32_t>();
|
|
||||||
RawInstructions* instr = image_reader_->GetInstructionsAt(offset);
|
|
||||||
uint32_t unchecked_offset = ReadUnsigned();
|
|
||||||
|
|
||||||
code->ptr()->instructions_ = instr;
|
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
|
||||||
code->ptr()->instructions_length_ = Instructions::Size(instr);
|
|
||||||
#else
|
|
||||||
code->ptr()->unchecked_offset_ = unchecked_offset;
|
|
||||||
if (kind() == Snapshot::kFullJIT) {
|
|
||||||
const uint32_t active_offset = Read<uint32_t>();
|
|
||||||
instr = image_reader_->GetInstructionsAt(active_offset);
|
|
||||||
unchecked_offset = ReadUnsigned();
|
|
||||||
}
|
|
||||||
code->ptr()->active_instructions_ = instr;
|
|
||||||
#endif
|
|
||||||
Code::InitializeCachedEntryPointsFrom(code, instr, unchecked_offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
|
||||||
uword Deserializer::GetBareInstructionsEnd() {
|
|
||||||
return image_reader_->GetBareInstructionsEnd();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RawObject* Deserializer::GetObjectAt(uint32_t offset) const {
|
RawObject* Deserializer::GetObjectAt(uint32_t offset) const {
|
||||||
return image_reader_->GetObjectAt(offset);
|
return image_reader_->GetObjectAt(offset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,9 +358,7 @@ class Serializer : public ThreadStackResource {
|
||||||
Write<int32_t>(cid);
|
Write<int32_t>(cid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteInstructions(RawInstructions* instr,
|
void WriteInstructions(RawInstructions* instr, RawCode* code);
|
||||||
uint32_t unchecked_offset,
|
|
||||||
RawCode* code);
|
|
||||||
uint32_t GetDataOffset(RawObject* object) const;
|
uint32_t GetDataOffset(RawObject* object) const;
|
||||||
void TraceDataOffset(uint32_t offset);
|
void TraceDataOffset(uint32_t offset);
|
||||||
intptr_t GetDataSize() const;
|
intptr_t GetDataSize() const;
|
||||||
|
@ -561,8 +559,7 @@ class Deserializer : public ThreadStackResource {
|
||||||
return Read<int32_t>();
|
return Read<int32_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ONLY_IN_PRECOMPILED(uword GetBareInstructionsEnd());
|
RawInstructions* ReadInstructions();
|
||||||
void ReadInstructions(RawCode* code);
|
|
||||||
RawObject* GetObjectAt(uint32_t offset) const;
|
RawObject* GetObjectAt(uint32_t offset) const;
|
||||||
|
|
||||||
void SkipHeader() { stream_.SetPosition(Snapshot::kHeaderSize); }
|
void SkipHeader() { stream_.SetPosition(Snapshot::kHeaderSize); }
|
||||||
|
|
|
@ -303,7 +303,7 @@ class AssemblerBase : public StackResource {
|
||||||
explicit AssemblerBase(ObjectPoolBuilder* object_pool_builder)
|
explicit AssemblerBase(ObjectPoolBuilder* object_pool_builder)
|
||||||
: StackResource(ThreadState::Current()),
|
: StackResource(ThreadState::Current()),
|
||||||
prologue_offset_(-1),
|
prologue_offset_(-1),
|
||||||
has_monomorphic_entry_(false),
|
has_single_entry_point_(true),
|
||||||
object_pool_builder_(object_pool_builder) {}
|
object_pool_builder_(object_pool_builder) {}
|
||||||
virtual ~AssemblerBase();
|
virtual ~AssemblerBase();
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ class AssemblerBase : public StackResource {
|
||||||
ObjectPoolBuilder& object_pool_builder() { return *object_pool_builder_; }
|
ObjectPoolBuilder& object_pool_builder() { return *object_pool_builder_; }
|
||||||
|
|
||||||
intptr_t prologue_offset() const { return prologue_offset_; }
|
intptr_t prologue_offset() const { return prologue_offset_; }
|
||||||
bool has_monomorphic_entry() const { return has_monomorphic_entry_; }
|
bool has_single_entry_point() const { return has_single_entry_point_; }
|
||||||
|
|
||||||
void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
|
void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
|
||||||
static bool EmittingComments();
|
static bool EmittingComments();
|
||||||
|
@ -370,7 +370,7 @@ class AssemblerBase : public StackResource {
|
||||||
protected:
|
protected:
|
||||||
AssemblerBuffer buffer_; // Contains position independent code.
|
AssemblerBuffer buffer_; // Contains position independent code.
|
||||||
int32_t prologue_offset_;
|
int32_t prologue_offset_;
|
||||||
bool has_monomorphic_entry_;
|
bool has_single_entry_point_;
|
||||||
|
|
||||||
intptr_t unchecked_entry_offset_ = 0;
|
intptr_t unchecked_entry_offset_ = 0;
|
||||||
|
|
||||||
|
|
|
@ -3437,7 +3437,7 @@ void Assembler::LeaveStubFrame() {
|
||||||
// R0 receiver, R9 ICData entries array
|
// R0 receiver, R9 ICData entries array
|
||||||
// Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
|
// Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
|
||||||
void Assembler::MonomorphicCheckedEntryJIT() {
|
void Assembler::MonomorphicCheckedEntryJIT() {
|
||||||
has_monomorphic_entry_ = true;
|
has_single_entry_point_ = false;
|
||||||
#if defined(TESTING) || defined(DEBUG)
|
#if defined(TESTING) || defined(DEBUG)
|
||||||
bool saved_use_far_branches = use_far_branches();
|
bool saved_use_far_branches = use_far_branches();
|
||||||
set_use_far_branches(false);
|
set_use_far_branches(false);
|
||||||
|
@ -3473,7 +3473,7 @@ void Assembler::MonomorphicCheckedEntryJIT() {
|
||||||
// R0 receiver, R9 guarded cid as Smi.
|
// R0 receiver, R9 guarded cid as Smi.
|
||||||
// Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
|
// Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
|
||||||
void Assembler::MonomorphicCheckedEntryAOT() {
|
void Assembler::MonomorphicCheckedEntryAOT() {
|
||||||
has_monomorphic_entry_ = true;
|
has_single_entry_point_ = false;
|
||||||
#if defined(TESTING) || defined(DEBUG)
|
#if defined(TESTING) || defined(DEBUG)
|
||||||
bool saved_use_far_branches = use_far_branches();
|
bool saved_use_far_branches = use_far_branches();
|
||||||
set_use_far_branches(false);
|
set_use_far_branches(false);
|
||||||
|
@ -3498,7 +3498,7 @@ void Assembler::MonomorphicCheckedEntryAOT() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::BranchOnMonomorphicCheckedEntryJIT(Label* label) {
|
void Assembler::BranchOnMonomorphicCheckedEntryJIT(Label* label) {
|
||||||
has_monomorphic_entry_ = true;
|
has_single_entry_point_ = false;
|
||||||
while (CodeSize() < target::Instructions::kMonomorphicEntryOffsetJIT) {
|
while (CodeSize() < target::Instructions::kMonomorphicEntryOffsetJIT) {
|
||||||
bkpt(0);
|
bkpt(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1532,7 +1532,7 @@ void Assembler::LeaveStubFrame() {
|
||||||
// R0 receiver, R5 ICData entries array
|
// R0 receiver, R5 ICData entries array
|
||||||
// Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
|
// Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
|
||||||
void Assembler::MonomorphicCheckedEntryJIT() {
|
void Assembler::MonomorphicCheckedEntryJIT() {
|
||||||
has_monomorphic_entry_ = true;
|
has_single_entry_point_ = false;
|
||||||
const bool saved_use_far_branches = use_far_branches();
|
const bool saved_use_far_branches = use_far_branches();
|
||||||
set_use_far_branches(false);
|
set_use_far_branches(false);
|
||||||
const intptr_t start = CodeSize();
|
const intptr_t start = CodeSize();
|
||||||
|
@ -1569,7 +1569,7 @@ void Assembler::MonomorphicCheckedEntryJIT() {
|
||||||
// R0 receiver, R5 guarded cid as Smi.
|
// R0 receiver, R5 guarded cid as Smi.
|
||||||
// Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
|
// Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
|
||||||
void Assembler::MonomorphicCheckedEntryAOT() {
|
void Assembler::MonomorphicCheckedEntryAOT() {
|
||||||
has_monomorphic_entry_ = true;
|
has_single_entry_point_ = false;
|
||||||
bool saved_use_far_branches = use_far_branches();
|
bool saved_use_far_branches = use_far_branches();
|
||||||
set_use_far_branches(false);
|
set_use_far_branches(false);
|
||||||
|
|
||||||
|
@ -1595,7 +1595,7 @@ void Assembler::MonomorphicCheckedEntryAOT() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::BranchOnMonomorphicCheckedEntryJIT(Label* label) {
|
void Assembler::BranchOnMonomorphicCheckedEntryJIT(Label* label) {
|
||||||
has_monomorphic_entry_ = true;
|
has_single_entry_point_ = false;
|
||||||
while (CodeSize() < target::Instructions::kMonomorphicEntryOffsetJIT) {
|
while (CodeSize() < target::Instructions::kMonomorphicEntryOffsetJIT) {
|
||||||
brk(0);
|
brk(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2117,7 +2117,7 @@ void Assembler::EmitEntryFrameVerification() {
|
||||||
// EBX receiver, ECX ICData entries array
|
// EBX receiver, ECX ICData entries array
|
||||||
// Preserve EDX (ARGS_DESC_REG), not required today, but maybe later.
|
// Preserve EDX (ARGS_DESC_REG), not required today, but maybe later.
|
||||||
void Assembler::MonomorphicCheckedEntryJIT() {
|
void Assembler::MonomorphicCheckedEntryJIT() {
|
||||||
has_monomorphic_entry_ = true;
|
has_single_entry_point_ = false;
|
||||||
intptr_t start = CodeSize();
|
intptr_t start = CodeSize();
|
||||||
Label have_cid, miss;
|
Label have_cid, miss;
|
||||||
Bind(&miss);
|
Bind(&miss);
|
||||||
|
@ -2156,7 +2156,7 @@ void Assembler::MonomorphicCheckedEntryAOT() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::BranchOnMonomorphicCheckedEntryJIT(Label* label) {
|
void Assembler::BranchOnMonomorphicCheckedEntryJIT(Label* label) {
|
||||||
has_monomorphic_entry_ = true;
|
has_single_entry_point_ = false;
|
||||||
while (CodeSize() < target::Instructions::kMonomorphicEntryOffsetJIT) {
|
while (CodeSize() < target::Instructions::kMonomorphicEntryOffsetJIT) {
|
||||||
int3();
|
int3();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1798,7 +1798,7 @@ void Assembler::LeaveStubFrame() {
|
||||||
// RDX receiver, RBX ICData entries array
|
// RDX receiver, RBX ICData entries array
|
||||||
// Preserve R10 (ARGS_DESC_REG), not required today, but maybe later.
|
// Preserve R10 (ARGS_DESC_REG), not required today, but maybe later.
|
||||||
void Assembler::MonomorphicCheckedEntryJIT() {
|
void Assembler::MonomorphicCheckedEntryJIT() {
|
||||||
has_monomorphic_entry_ = true;
|
has_single_entry_point_ = false;
|
||||||
intptr_t start = CodeSize();
|
intptr_t start = CodeSize();
|
||||||
Label have_cid, miss;
|
Label have_cid, miss;
|
||||||
Bind(&miss);
|
Bind(&miss);
|
||||||
|
@ -1831,7 +1831,7 @@ void Assembler::MonomorphicCheckedEntryJIT() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::MonomorphicCheckedEntryAOT() {
|
void Assembler::MonomorphicCheckedEntryAOT() {
|
||||||
has_monomorphic_entry_ = true;
|
has_single_entry_point_ = false;
|
||||||
intptr_t start = CodeSize();
|
intptr_t start = CodeSize();
|
||||||
Label have_cid, miss;
|
Label have_cid, miss;
|
||||||
Bind(&miss);
|
Bind(&miss);
|
||||||
|
@ -1862,7 +1862,7 @@ void Assembler::MonomorphicCheckedEntryAOT() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::BranchOnMonomorphicCheckedEntryJIT(Label* label) {
|
void Assembler::BranchOnMonomorphicCheckedEntryJIT(Label* label) {
|
||||||
has_monomorphic_entry_ = true;
|
has_single_entry_point_ = false;
|
||||||
while (CodeSize() < target::Instructions::kMonomorphicEntryOffsetJIT) {
|
while (CodeSize() < target::Instructions::kMonomorphicEntryOffsetJIT) {
|
||||||
int3();
|
int3();
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,7 +258,8 @@ void Disassembler::DisassembleCodeHelper(const char* function_fullname,
|
||||||
PcDescriptors::Handle(zone, code.pc_descriptors());
|
PcDescriptors::Handle(zone, code.pc_descriptors());
|
||||||
THR_Print("%s}\n", descriptors.ToCString());
|
THR_Print("%s}\n", descriptors.ToCString());
|
||||||
|
|
||||||
const uword start = code.PayloadStart();
|
const auto& instructions = Instructions::Handle(code.instructions());
|
||||||
|
const uword start = instructions.PayloadStart();
|
||||||
const uword base = FLAG_disassemble_relative ? 0 : start;
|
const uword base = FLAG_disassemble_relative ? 0 : start;
|
||||||
|
|
||||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||||
|
|
|
@ -157,7 +157,8 @@ void CodeRelocator::FindInstructionAndCallLimits() {
|
||||||
offset_into_target = call.distance();
|
offset_into_target = call.distance();
|
||||||
}
|
}
|
||||||
|
|
||||||
const uword destination_payload = destination_.PayloadStart();
|
const uword destination_payload =
|
||||||
|
Instructions::PayloadStart(destination_.instructions());
|
||||||
const uword entry_point = call_entry_point == Code::kUncheckedEntry
|
const uword entry_point = call_entry_point == Code::kUncheckedEntry
|
||||||
? destination_.UncheckedEntryPoint()
|
? destination_.UncheckedEntryPoint()
|
||||||
: destination_.EntryPoint();
|
: destination_.EntryPoint();
|
||||||
|
@ -271,16 +272,17 @@ void CodeRelocator::ScanCallTargets(const Code& code,
|
||||||
offset_into_target = call.distance();
|
offset_into_target = call.distance();
|
||||||
}
|
}
|
||||||
|
|
||||||
const uword destination_payload = destination_.PayloadStart();
|
const uword destination_payload =
|
||||||
|
Instructions::PayloadStart(destination_.instructions());
|
||||||
const uword entry_point = call_entry_point == Code::kUncheckedEntry
|
const uword entry_point = call_entry_point == Code::kUncheckedEntry
|
||||||
? destination_.UncheckedEntryPoint()
|
? destination_.UncheckedEntryPoint()
|
||||||
: destination_.EntryPoint();
|
: destination_.EntryPoint();
|
||||||
|
|
||||||
offset_into_target += (entry_point - destination_payload);
|
offset_into_target += (entry_point - destination_payload);
|
||||||
|
|
||||||
const intptr_t text_offset =
|
const intptr_t text_offset = code_text_offset +
|
||||||
code_text_offset + AdjustPayloadOffset(call_instruction_offset);
|
compiler::target::Instructions::HeaderSize() +
|
||||||
|
call_instruction_offset;
|
||||||
UnresolvedCall unresolved_call(code.raw(), call_instruction_offset,
|
UnresolvedCall unresolved_call(code.raw(), call_instruction_offset,
|
||||||
text_offset, destination_.raw(),
|
text_offset, destination_.raw(),
|
||||||
offset_into_target);
|
offset_into_target);
|
||||||
|
@ -366,12 +368,12 @@ void CodeRelocator::ResolveCallToDestination(UnresolvedCall* unresolved_call,
|
||||||
const intptr_t call_text_offset = unresolved_call->text_offset;
|
const intptr_t call_text_offset = unresolved_call->text_offset;
|
||||||
const intptr_t call_offset = unresolved_call->call_offset;
|
const intptr_t call_offset = unresolved_call->call_offset;
|
||||||
|
|
||||||
|
auto caller = Code::InstructionsOf(unresolved_call->caller);
|
||||||
const int32_t distance = destination_text - call_text_offset;
|
const int32_t distance = destination_text - call_text_offset;
|
||||||
{
|
{
|
||||||
auto const caller = unresolved_call->caller;
|
uword addr = Instructions::PayloadStart(caller) + call_offset;
|
||||||
uword addr = Code::PayloadStartOf(caller) + call_offset;
|
|
||||||
if (FLAG_write_protect_code) {
|
if (FLAG_write_protect_code) {
|
||||||
addr -= HeapPage::Of(Code::InstructionsOf(caller))->AliasOffset();
|
addr -= HeapPage::Of(caller)->AliasOffset();
|
||||||
}
|
}
|
||||||
PcRelativeCallPattern call(addr);
|
PcRelativeCallPattern call(addr);
|
||||||
ASSERT(call.IsValid());
|
ASSERT(call.IsValid());
|
||||||
|
@ -508,15 +510,9 @@ void CodeRelocator::BuildTrampolinesForAlmostOutOfRangeCalls() {
|
||||||
intptr_t CodeRelocator::FindDestinationInText(
|
intptr_t CodeRelocator::FindDestinationInText(
|
||||||
const RawInstructions* destination,
|
const RawInstructions* destination,
|
||||||
intptr_t offset_into_target) {
|
intptr_t offset_into_target) {
|
||||||
auto const destination_offset = text_offsets_.LookupValue(destination);
|
auto destination_offset = text_offsets_.LookupValue(destination);
|
||||||
return destination_offset + AdjustPayloadOffset(offset_into_target);
|
return destination_offset + compiler::target::Instructions::HeaderSize() +
|
||||||
}
|
offset_into_target;
|
||||||
|
|
||||||
intptr_t CodeRelocator::AdjustPayloadOffset(intptr_t payload_offset) {
|
|
||||||
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
|
|
||||||
return payload_offset;
|
|
||||||
}
|
|
||||||
return compiler::target::Instructions::HeaderSize() + payload_offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
|
#endif // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
|
||||||
|
|
|
@ -178,8 +178,6 @@ class CodeRelocator : public StackResource {
|
||||||
intptr_t FindDestinationInText(const RawInstructions* destination,
|
intptr_t FindDestinationInText(const RawInstructions* destination,
|
||||||
intptr_t offset_into_target);
|
intptr_t offset_into_target);
|
||||||
|
|
||||||
static intptr_t AdjustPayloadOffset(intptr_t payload_offset);
|
|
||||||
|
|
||||||
bool IsTargetInRangeFor(UnresolvedCall* unresolved_call,
|
bool IsTargetInRangeFor(UnresolvedCall* unresolved_call,
|
||||||
intptr_t target_text_offset);
|
intptr_t target_text_offset);
|
||||||
|
|
||||||
|
|
|
@ -513,11 +513,6 @@ const word StoreBufferBlock::kSize = dart::StoreBufferBlock::kSize;
|
||||||
|
|
||||||
const word MarkingStackBlock::kSize = dart::MarkingStackBlock::kSize;
|
const word MarkingStackBlock::kSize = dart::MarkingStackBlock::kSize;
|
||||||
|
|
||||||
word InstructionsSection::HeaderSize() {
|
|
||||||
return Utils::RoundUp(InstructionsSection::UnalignedHeaderSize(),
|
|
||||||
target::kWordSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
word Instructions::HeaderSize() {
|
word Instructions::HeaderSize() {
|
||||||
return Utils::RoundUp(Instructions::UnalignedHeaderSize(), target::kWordSize);
|
return Utils::RoundUp(Instructions::UnalignedHeaderSize(), target::kWordSize);
|
||||||
}
|
}
|
||||||
|
@ -916,10 +911,6 @@ word MonomorphicSmiableCall::NextFieldOffset() {
|
||||||
return -kWordSize;
|
return -kWordSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
word InstructionsSection::NextFieldOffset() {
|
|
||||||
return -kWordSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
word Instructions::NextFieldOffset() {
|
word Instructions::NextFieldOffset() {
|
||||||
return -kWordSize;
|
return -kWordSize;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1063,14 +1063,6 @@ class ClassTable : public AllStatic {
|
||||||
static const word kSizeOfClassPairLog2;
|
static const word kSizeOfClassPairLog2;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InstructionsSection : public AllStatic {
|
|
||||||
public:
|
|
||||||
static word HeaderSize();
|
|
||||||
static word UnalignedHeaderSize();
|
|
||||||
static word InstanceSize();
|
|
||||||
static word NextFieldOffset();
|
|
||||||
};
|
|
||||||
|
|
||||||
class Instructions : public AllStatic {
|
class Instructions : public AllStatic {
|
||||||
public:
|
public:
|
||||||
static const word kMonomorphicEntryOffsetJIT;
|
static const word kMonomorphicEntryOffsetJIT;
|
||||||
|
|
|
@ -415,10 +415,6 @@ static constexpr dart::compiler::target::word Instance_InstanceSize = 4;
|
||||||
static constexpr dart::compiler::target::word Instructions_InstanceSize = 8;
|
static constexpr dart::compiler::target::word Instructions_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||||
8;
|
8;
|
||||||
static constexpr dart::compiler::target::word InstructionsSection_InstanceSize =
|
|
||||||
8;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
InstructionsSection_UnalignedHeaderSize = 8;
|
|
||||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word Integer_InstanceSize = 4;
|
static constexpr dart::compiler::target::word Integer_InstanceSize = 4;
|
||||||
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
||||||
|
@ -878,10 +874,6 @@ static constexpr dart::compiler::target::word Instance_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word Instructions_InstanceSize = 12;
|
static constexpr dart::compiler::target::word Instructions_InstanceSize = 12;
|
||||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||||
12;
|
12;
|
||||||
static constexpr dart::compiler::target::word InstructionsSection_InstanceSize =
|
|
||||||
12;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
InstructionsSection_UnalignedHeaderSize = 12;
|
|
||||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
|
static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
||||||
|
@ -1334,10 +1326,6 @@ static constexpr dart::compiler::target::word Instance_InstanceSize = 4;
|
||||||
static constexpr dart::compiler::target::word Instructions_InstanceSize = 8;
|
static constexpr dart::compiler::target::word Instructions_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||||
8;
|
8;
|
||||||
static constexpr dart::compiler::target::word InstructionsSection_InstanceSize =
|
|
||||||
8;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
InstructionsSection_UnalignedHeaderSize = 8;
|
|
||||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word Integer_InstanceSize = 4;
|
static constexpr dart::compiler::target::word Integer_InstanceSize = 4;
|
||||||
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
||||||
|
@ -1798,10 +1786,6 @@ static constexpr dart::compiler::target::word Instance_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word Instructions_InstanceSize = 12;
|
static constexpr dart::compiler::target::word Instructions_InstanceSize = 12;
|
||||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||||
12;
|
12;
|
||||||
static constexpr dart::compiler::target::word InstructionsSection_InstanceSize =
|
|
||||||
12;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
InstructionsSection_UnalignedHeaderSize = 12;
|
|
||||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
|
static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
||||||
|
@ -2254,10 +2238,6 @@ static constexpr dart::compiler::target::word Instance_InstanceSize = 4;
|
||||||
static constexpr dart::compiler::target::word Instructions_InstanceSize = 8;
|
static constexpr dart::compiler::target::word Instructions_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||||
8;
|
8;
|
||||||
static constexpr dart::compiler::target::word InstructionsSection_InstanceSize =
|
|
||||||
8;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
InstructionsSection_UnalignedHeaderSize = 8;
|
|
||||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word Integer_InstanceSize = 4;
|
static constexpr dart::compiler::target::word Integer_InstanceSize = 4;
|
||||||
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
||||||
|
@ -2711,10 +2691,6 @@ static constexpr dart::compiler::target::word Instance_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word Instructions_InstanceSize = 12;
|
static constexpr dart::compiler::target::word Instructions_InstanceSize = 12;
|
||||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||||
12;
|
12;
|
||||||
static constexpr dart::compiler::target::word InstructionsSection_InstanceSize =
|
|
||||||
12;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
InstructionsSection_UnalignedHeaderSize = 12;
|
|
||||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
|
static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
||||||
|
@ -3161,10 +3137,6 @@ static constexpr dart::compiler::target::word Instance_InstanceSize = 4;
|
||||||
static constexpr dart::compiler::target::word Instructions_InstanceSize = 8;
|
static constexpr dart::compiler::target::word Instructions_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||||
8;
|
8;
|
||||||
static constexpr dart::compiler::target::word InstructionsSection_InstanceSize =
|
|
||||||
8;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
InstructionsSection_UnalignedHeaderSize = 8;
|
|
||||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word Integer_InstanceSize = 4;
|
static constexpr dart::compiler::target::word Integer_InstanceSize = 4;
|
||||||
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
||||||
|
@ -3619,10 +3591,6 @@ static constexpr dart::compiler::target::word Instance_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word Instructions_InstanceSize = 12;
|
static constexpr dart::compiler::target::word Instructions_InstanceSize = 12;
|
||||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||||
12;
|
12;
|
||||||
static constexpr dart::compiler::target::word InstructionsSection_InstanceSize =
|
|
||||||
12;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
InstructionsSection_UnalignedHeaderSize = 12;
|
|
||||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
|
static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
|
||||||
|
@ -4111,10 +4079,6 @@ static constexpr dart::compiler::target::word AOT_Instance_InstanceSize = 4;
|
||||||
static constexpr dart::compiler::target::word AOT_Instructions_InstanceSize = 8;
|
static constexpr dart::compiler::target::word AOT_Instructions_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word
|
static constexpr dart::compiler::target::word
|
||||||
AOT_Instructions_UnalignedHeaderSize = 8;
|
AOT_Instructions_UnalignedHeaderSize = 8;
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
AOT_InstructionsSection_InstanceSize = 8;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
AOT_InstructionsSection_UnalignedHeaderSize = 8;
|
|
||||||
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 4;
|
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 4;
|
||||||
static constexpr dart::compiler::target::word
|
static constexpr dart::compiler::target::word
|
||||||
|
@ -4617,10 +4581,6 @@ static constexpr dart::compiler::target::word AOT_Instructions_InstanceSize =
|
||||||
12;
|
12;
|
||||||
static constexpr dart::compiler::target::word
|
static constexpr dart::compiler::target::word
|
||||||
AOT_Instructions_UnalignedHeaderSize = 12;
|
AOT_Instructions_UnalignedHeaderSize = 12;
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
AOT_InstructionsSection_InstanceSize = 12;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
AOT_InstructionsSection_UnalignedHeaderSize = 12;
|
|
||||||
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
|
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word
|
static constexpr dart::compiler::target::word
|
||||||
|
@ -5127,10 +5087,6 @@ static constexpr dart::compiler::target::word AOT_Instructions_InstanceSize =
|
||||||
12;
|
12;
|
||||||
static constexpr dart::compiler::target::word
|
static constexpr dart::compiler::target::word
|
||||||
AOT_Instructions_UnalignedHeaderSize = 12;
|
AOT_Instructions_UnalignedHeaderSize = 12;
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
AOT_InstructionsSection_InstanceSize = 12;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
AOT_InstructionsSection_UnalignedHeaderSize = 12;
|
|
||||||
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
|
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word
|
static constexpr dart::compiler::target::word
|
||||||
|
@ -5593,7 +5549,7 @@ static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
|
||||||
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 112;
|
static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 112;
|
||||||
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 28;
|
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 28;
|
||||||
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 20;
|
static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 20;
|
||||||
static constexpr dart::compiler::target::word AOT_Code_InstanceSize = 64;
|
static constexpr dart::compiler::target::word AOT_Code_InstanceSize = 60;
|
||||||
static constexpr dart::compiler::target::word AOT_CodeSourceMap_InstanceSize =
|
static constexpr dart::compiler::target::word AOT_CodeSourceMap_InstanceSize =
|
||||||
8;
|
8;
|
||||||
static constexpr dart::compiler::target::word
|
static constexpr dart::compiler::target::word
|
||||||
|
@ -5626,10 +5582,6 @@ static constexpr dart::compiler::target::word AOT_Instance_InstanceSize = 4;
|
||||||
static constexpr dart::compiler::target::word AOT_Instructions_InstanceSize = 8;
|
static constexpr dart::compiler::target::word AOT_Instructions_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word
|
static constexpr dart::compiler::target::word
|
||||||
AOT_Instructions_UnalignedHeaderSize = 8;
|
AOT_Instructions_UnalignedHeaderSize = 8;
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
AOT_InstructionsSection_InstanceSize = 8;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
AOT_InstructionsSection_UnalignedHeaderSize = 8;
|
|
||||||
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 4;
|
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 4;
|
||||||
static constexpr dart::compiler::target::word
|
static constexpr dart::compiler::target::word
|
||||||
|
@ -6125,10 +6077,6 @@ static constexpr dart::compiler::target::word AOT_Instructions_InstanceSize =
|
||||||
12;
|
12;
|
||||||
static constexpr dart::compiler::target::word
|
static constexpr dart::compiler::target::word
|
||||||
AOT_Instructions_UnalignedHeaderSize = 12;
|
AOT_Instructions_UnalignedHeaderSize = 12;
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
AOT_InstructionsSection_InstanceSize = 12;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
AOT_InstructionsSection_UnalignedHeaderSize = 12;
|
|
||||||
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
|
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word
|
static constexpr dart::compiler::target::word
|
||||||
|
@ -6628,10 +6576,6 @@ static constexpr dart::compiler::target::word AOT_Instructions_InstanceSize =
|
||||||
12;
|
12;
|
||||||
static constexpr dart::compiler::target::word
|
static constexpr dart::compiler::target::word
|
||||||
AOT_Instructions_UnalignedHeaderSize = 12;
|
AOT_Instructions_UnalignedHeaderSize = 12;
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
AOT_InstructionsSection_InstanceSize = 12;
|
|
||||||
static constexpr dart::compiler::target::word
|
|
||||||
AOT_InstructionsSection_UnalignedHeaderSize = 12;
|
|
||||||
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
|
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
|
||||||
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
|
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
|
||||||
static constexpr dart::compiler::target::word
|
static constexpr dart::compiler::target::word
|
||||||
|
|
|
@ -286,8 +286,6 @@
|
||||||
SIZEOF(Instance, InstanceSize, RawInstance) \
|
SIZEOF(Instance, InstanceSize, RawInstance) \
|
||||||
SIZEOF(Instructions, InstanceSize, RawInstructions) \
|
SIZEOF(Instructions, InstanceSize, RawInstructions) \
|
||||||
SIZEOF(Instructions, UnalignedHeaderSize, RawInstructions) \
|
SIZEOF(Instructions, UnalignedHeaderSize, RawInstructions) \
|
||||||
SIZEOF(InstructionsSection, InstanceSize, RawInstructionsSection) \
|
|
||||||
SIZEOF(InstructionsSection, UnalignedHeaderSize, RawInstructionsSection) \
|
|
||||||
SIZEOF(Int32x4, InstanceSize, RawInt32x4) \
|
SIZEOF(Int32x4, InstanceSize, RawInt32x4) \
|
||||||
SIZEOF(Integer, InstanceSize, RawInteger) \
|
SIZEOF(Integer, InstanceSize, RawInteger) \
|
||||||
SIZEOF(KernelProgramInfo, InstanceSize, RawKernelProgramInfo) \
|
SIZEOF(KernelProgramInfo, InstanceSize, RawKernelProgramInfo) \
|
||||||
|
|
|
@ -78,12 +78,6 @@ const intptr_t kDefaultMaxOldGenHeapSize = (kWordSize <= 4) ? 1536 : 30720;
|
||||||
#define NOT_IN_PRECOMPILED(code) code
|
#define NOT_IN_PRECOMPILED(code) code
|
||||||
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
||||||
|
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
|
||||||
#define ONLY_IN_PRECOMPILED(code) code
|
|
||||||
#else
|
|
||||||
#define ONLY_IN_PRECOMPILED(code)
|
|
||||||
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
|
||||||
|
|
||||||
#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) || \
|
#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) || \
|
||||||
defined(TARGET_ARCH_X64)
|
defined(TARGET_ARCH_X64)
|
||||||
#define ONLY_IN_ARM_ARM64_X64(code) code
|
#define ONLY_IN_ARM_ARM64_X64(code) code
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "vm/image_snapshot.h"
|
#include "vm/image_snapshot.h"
|
||||||
|
|
||||||
#include "platform/assert.h"
|
#include "platform/assert.h"
|
||||||
#include "vm/class_id.h"
|
|
||||||
#include "vm/compiler/backend/code_statistics.h"
|
#include "vm/compiler/backend/code_statistics.h"
|
||||||
#include "vm/compiler/runtime_api.h"
|
#include "vm/compiler/runtime_api.h"
|
||||||
#include "vm/dwarf.h"
|
#include "vm/dwarf.h"
|
||||||
|
@ -136,25 +135,6 @@ int32_t ImageWriter::GetTextOffsetFor(RawInstructions* instructions,
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static intptr_t InstructionsSizeInSnapshot(RawInstructions* raw) {
|
|
||||||
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
|
|
||||||
// Currently, we align bare instruction payloads on 4 byte boundaries.
|
|
||||||
//
|
|
||||||
// If we later decide to align on larger boundaries to put entries at the
|
|
||||||
// start of cache lines, make sure to account for entry points that are
|
|
||||||
// _not_ at the start of the payload.
|
|
||||||
return Utils::RoundUp(Instructions::Size(raw),
|
|
||||||
ImageWriter::kBareInstructionsAlignment);
|
|
||||||
}
|
|
||||||
#if defined(IS_SIMARM_X64)
|
|
||||||
return Utils::RoundUp(
|
|
||||||
compiler::target::Instructions::HeaderSize() + Instructions::Size(raw),
|
|
||||||
compiler::target::ObjectAlignment::kObjectAlignment);
|
|
||||||
#else
|
|
||||||
return raw->HeapSize();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(IS_SIMARM_X64)
|
#if defined(IS_SIMARM_X64)
|
||||||
static intptr_t CompressedStackMapsSizeInSnapshot(intptr_t payload_size) {
|
static intptr_t CompressedStackMapsSizeInSnapshot(intptr_t payload_size) {
|
||||||
// We do not need to round the non-payload size up to a word boundary because
|
// We do not need to round the non-payload size up to a word boundary because
|
||||||
|
@ -191,6 +171,11 @@ static intptr_t PcDescriptorsSizeInSnapshot(intptr_t len) {
|
||||||
compiler::target::ObjectAlignment::kObjectAlignment);
|
compiler::target::ObjectAlignment::kObjectAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static intptr_t InstructionsSizeInSnapshot(intptr_t len) {
|
||||||
|
return Utils::RoundUp(compiler::target::Instructions::HeaderSize() + len,
|
||||||
|
compiler::target::ObjectAlignment::kObjectAlignment);
|
||||||
|
}
|
||||||
|
|
||||||
intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
|
intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
|
||||||
const classid_t cid = raw_object->GetClassId();
|
const classid_t cid = raw_object->GetClassId();
|
||||||
|
|
||||||
|
@ -216,7 +201,7 @@ intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
|
||||||
}
|
}
|
||||||
case kInstructionsCid: {
|
case kInstructionsCid: {
|
||||||
RawInstructions* raw_insns = static_cast<RawInstructions*>(raw_object);
|
RawInstructions* raw_insns = static_cast<RawInstructions*>(raw_object);
|
||||||
return InstructionsSizeInSnapshot(raw_insns);
|
return InstructionsSizeInSnapshot(Instructions::Size(raw_insns));
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
const Class& clazz = Class::Handle(Object::Handle(raw_object).clazz());
|
const Class& clazz = Class::Handle(Object::Handle(raw_object).clazz());
|
||||||
|
@ -226,13 +211,8 @@ intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else // defined(IS_SIMARM_X64)
|
#else // defined(IS_SIMARM_X64)
|
||||||
intptr_t ImageWriter::SizeInSnapshot(RawObject* raw) {
|
intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
|
||||||
switch (raw->GetClassId()) {
|
return raw_object->HeapSize();
|
||||||
case kInstructionsCid:
|
|
||||||
return InstructionsSizeInSnapshot(static_cast<RawInstructions*>(raw));
|
|
||||||
default:
|
|
||||||
return raw->HeapSize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif // defined(IS_SIMARM_X64)
|
#endif // defined(IS_SIMARM_X64)
|
||||||
|
|
||||||
|
@ -576,9 +556,6 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
#else
|
#else
|
||||||
Zone* zone = Thread::Current()->zone();
|
Zone* zone = Thread::Current()->zone();
|
||||||
|
|
||||||
const bool bare_instruction_payloads =
|
|
||||||
FLAG_precompiled_mode && FLAG_use_bare_instructions;
|
|
||||||
|
|
||||||
#if defined(DART_PRECOMPILER)
|
#if defined(DART_PRECOMPILER)
|
||||||
const char* bss_symbol =
|
const char* bss_symbol =
|
||||||
vm ? "_kDartVmSnapshotBss" : "_kDartIsolateSnapshotBss";
|
vm ? "_kDartVmSnapshotBss" : "_kDartIsolateSnapshotBss";
|
||||||
|
@ -595,14 +572,13 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
|
|
||||||
// Start snapshot at page boundary.
|
// Start snapshot at page boundary.
|
||||||
ASSERT(VirtualMemory::PageSize() >= kMaxObjectAlignment);
|
ASSERT(VirtualMemory::PageSize() >= kMaxObjectAlignment);
|
||||||
Align(VirtualMemory::PageSize());
|
assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize());
|
||||||
assembly_stream_.Print("%s:\n", instructions_symbol);
|
assembly_stream_.Print("%s:\n", instructions_symbol);
|
||||||
|
|
||||||
// This head also provides the gap to make the instructions snapshot
|
// This head also provides the gap to make the instructions snapshot
|
||||||
// look like a HeapPage.
|
// look like a HeapPage.
|
||||||
const intptr_t image_size = Utils::RoundUp(
|
intptr_t instructions_length = next_text_offset_;
|
||||||
next_text_offset_, compiler::target::ObjectAlignment::kObjectAlignment);
|
WriteWordLiteralText(instructions_length);
|
||||||
WriteWordLiteralText(image_size);
|
|
||||||
|
|
||||||
#if defined(DART_PRECOMPILER)
|
#if defined(DART_PRECOMPILER)
|
||||||
assembly_stream_.Print("%s %s - %s\n", kLiteralPrefix, bss_symbol,
|
assembly_stream_.Print("%s %s - %s\n", kLiteralPrefix, bss_symbol,
|
||||||
|
@ -616,43 +592,6 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
WriteWordLiteralText(0);
|
WriteWordLiteralText(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bare_instruction_payloads) {
|
|
||||||
const intptr_t image_payload_length = image_size - Image::kHeaderSize;
|
|
||||||
// Add the RawInstructionsSection header.
|
|
||||||
uword marked_tags = 0;
|
|
||||||
marked_tags = RawObject::OldBit::update(true, marked_tags);
|
|
||||||
marked_tags = RawObject::OldAndNotRememberedBit::update(true, marked_tags);
|
|
||||||
marked_tags = RawObject::SizeTag::update(image_payload_length, marked_tags);
|
|
||||||
marked_tags =
|
|
||||||
RawObject::ClassIdTag::update(kInstructionsSectionCid, marked_tags);
|
|
||||||
|
|
||||||
WriteWordLiteralText(marked_tags);
|
|
||||||
// Calculated using next_text_offset_, which doesn't include post-payload
|
|
||||||
// padding to object alignment.
|
|
||||||
const intptr_t instructions_length =
|
|
||||||
next_text_offset_ - Image::kHeaderSize -
|
|
||||||
compiler::target::InstructionsSection::HeaderSize();
|
|
||||||
WriteWordLiteralText(instructions_length);
|
|
||||||
|
|
||||||
if (profile_writer_ != nullptr) {
|
|
||||||
const intptr_t offset = Image::kHeaderSize;
|
|
||||||
const intptr_t non_instruction_bytes =
|
|
||||||
compiler::target::InstructionsSection::HeaderSize();
|
|
||||||
profile_writer_->SetObjectTypeAndName({offset_space_, offset},
|
|
||||||
"InstructionsSection",
|
|
||||||
/*name=*/nullptr);
|
|
||||||
profile_writer_->AttributeBytesTo({offset_space_, offset},
|
|
||||||
non_instruction_bytes);
|
|
||||||
profile_writer_->AddRoot({offset_space_, offset});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const intptr_t section_headers_size =
|
|
||||||
Image::kHeaderSize +
|
|
||||||
(bare_instruction_payloads
|
|
||||||
? compiler::target::InstructionsSection::HeaderSize()
|
|
||||||
: 0);
|
|
||||||
|
|
||||||
FrameUnwindPrologue();
|
FrameUnwindPrologue();
|
||||||
|
|
||||||
PcDescriptors& descriptors = PcDescriptors::Handle(zone);
|
PcDescriptors& descriptors = PcDescriptors::Handle(zone);
|
||||||
|
@ -665,19 +604,9 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
const bool is_trampoline = data.trampoline_bytes != nullptr;
|
const bool is_trampoline = data.trampoline_bytes != nullptr;
|
||||||
ASSERT((data.text_offset_ - instructions_[0].text_offset_) == text_offset);
|
ASSERT((data.text_offset_ - instructions_[0].text_offset_) == text_offset);
|
||||||
|
|
||||||
if (bare_instruction_payloads && profile_writer_ != nullptr) {
|
|
||||||
const intptr_t instructions_sections_offset = Image::kHeaderSize;
|
|
||||||
const intptr_t offset = section_headers_size + text_offset;
|
|
||||||
profile_writer_->AttributeReferenceTo(
|
|
||||||
{offset_space_, instructions_sections_offset},
|
|
||||||
{{offset_space_, offset},
|
|
||||||
V8SnapshotProfileWriter::Reference::kElement,
|
|
||||||
text_offset});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_trampoline) {
|
if (is_trampoline) {
|
||||||
if (profile_writer_ != nullptr) {
|
if (profile_writer_ != nullptr) {
|
||||||
const intptr_t offset = section_headers_size + text_offset;
|
const intptr_t offset = Image::kHeaderSize + text_offset;
|
||||||
profile_writer_->SetObjectTypeAndName({offset_space_, offset},
|
profile_writer_->SetObjectTypeAndName({offset_space_, offset},
|
||||||
"Trampolines",
|
"Trampolines",
|
||||||
/*name=*/nullptr);
|
/*name=*/nullptr);
|
||||||
|
@ -700,7 +629,7 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
descriptors = data.code_->pc_descriptors();
|
descriptors = data.code_->pc_descriptors();
|
||||||
|
|
||||||
if (profile_writer_ != nullptr) {
|
if (profile_writer_ != nullptr) {
|
||||||
const intptr_t offset = section_headers_size + text_offset;
|
const intptr_t offset = Image::kHeaderSize + text_offset;
|
||||||
profile_writer_->SetObjectTypeAndName({offset_space_, offset},
|
profile_writer_->SetObjectTypeAndName({offset_space_, offset},
|
||||||
"Instructions",
|
"Instructions",
|
||||||
/*name=*/nullptr);
|
/*name=*/nullptr);
|
||||||
|
@ -708,12 +637,9 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
SizeInSnapshot(insns.raw()));
|
SizeInSnapshot(insns.raw()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const uword payload_start = insns.PayloadStart();
|
|
||||||
|
|
||||||
// 1. Write from the object start to the payload start. This includes the
|
// 1. Write from the object start to the payload start. This includes the
|
||||||
// object header and the fixed fields. Not written for AOT snapshots using
|
// object header and the fixed fields.
|
||||||
// bare instructions.
|
{
|
||||||
if (!bare_instruction_payloads) {
|
|
||||||
NoSafepointScope no_safepoint;
|
NoSafepointScope no_safepoint;
|
||||||
|
|
||||||
// Write Instructions with the mark and read-only bits set.
|
// Write Instructions with the mark and read-only bits set.
|
||||||
|
@ -730,7 +656,7 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(IS_SIMARM_X64)
|
#if defined(IS_SIMARM_X64)
|
||||||
const intptr_t size_in_bytes = InstructionsSizeInSnapshot(insns.raw());
|
const intptr_t size_in_bytes = InstructionsSizeInSnapshot(insns.Size());
|
||||||
marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
|
marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
|
||||||
WriteWordLiteralText(marked_tags);
|
WriteWordLiteralText(marked_tags);
|
||||||
text_offset += sizeof(compiler::target::uword);
|
text_offset += sizeof(compiler::target::uword);
|
||||||
|
@ -738,6 +664,7 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
text_offset += sizeof(compiler::target::uword);
|
text_offset += sizeof(compiler::target::uword);
|
||||||
#else // defined(IS_SIMARM_X64)
|
#else // defined(IS_SIMARM_X64)
|
||||||
uword object_start = reinterpret_cast<uword>(insns.raw_ptr());
|
uword object_start = reinterpret_cast<uword>(insns.raw_ptr());
|
||||||
|
uword payload_start = insns.PayloadStart();
|
||||||
WriteWordLiteralText(marked_tags);
|
WriteWordLiteralText(marked_tags);
|
||||||
object_start += sizeof(uword);
|
object_start += sizeof(uword);
|
||||||
text_offset += sizeof(uword);
|
text_offset += sizeof(uword);
|
||||||
|
@ -756,7 +683,7 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
}
|
}
|
||||||
if (debug_dwarf_ != nullptr) {
|
if (debug_dwarf_ != nullptr) {
|
||||||
auto const virtual_address =
|
auto const virtual_address =
|
||||||
debug_segment_base + section_headers_size + text_offset;
|
debug_segment_base + Image::kHeaderSize + text_offset;
|
||||||
debug_dwarf_->AddCode(code, virtual_address);
|
debug_dwarf_->AddCode(code, virtual_address);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -765,29 +692,19 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
assembly_stream_.Print("%s:\n", namer.AssemblyNameFor(dwarf_index, code));
|
assembly_stream_.Print("%s:\n", namer.AssemblyNameFor(dwarf_index, code));
|
||||||
|
|
||||||
{
|
{
|
||||||
// 3. Write from the payload start to payload end. For AOT snapshots
|
// 3. Write from the payload start to payload end.
|
||||||
// with bare instructions, this is the only part serialized.
|
|
||||||
NoSafepointScope no_safepoint;
|
NoSafepointScope no_safepoint;
|
||||||
assert(kBareInstructionsAlignment <=
|
const uword payload_start = insns.PayloadStart();
|
||||||
compiler::target::ObjectAlignment::kObjectAlignment);
|
const uword payload_size =
|
||||||
const auto payload_align = bare_instruction_payloads
|
Utils::RoundUp(insns.Size(), sizeof(compiler::target::uword));
|
||||||
? kBareInstructionsAlignment
|
|
||||||
: sizeof(compiler::target::uword);
|
|
||||||
const uword payload_size = Utils::RoundUp(insns.Size(), payload_align);
|
|
||||||
const uword payload_end = payload_start + payload_size;
|
const uword payload_end = payload_start + payload_size;
|
||||||
|
|
||||||
ASSERT(Utils::IsAligned(text_offset, payload_align));
|
|
||||||
|
|
||||||
#if defined(DART_PRECOMPILER)
|
#if defined(DART_PRECOMPILER)
|
||||||
PcDescriptors::Iterator iterator(descriptors,
|
PcDescriptors::Iterator iterator(descriptors,
|
||||||
RawPcDescriptors::kBSSRelocation);
|
RawPcDescriptors::kBSSRelocation);
|
||||||
uword next_reloc_offset = iterator.MoveNext() ? iterator.PcOffset() : -1;
|
uword next_reloc_offset = iterator.MoveNext() ? iterator.PcOffset() : -1;
|
||||||
|
|
||||||
// We only generate BSS relocations that are word-sized and at
|
for (uword cursor = payload_start; cursor < payload_end;
|
||||||
// word-aligned offsets in the payload.
|
|
||||||
auto const possible_relocations_end =
|
|
||||||
Utils::RoundDown(payload_end, sizeof(compiler::target::uword));
|
|
||||||
for (uword cursor = payload_start; cursor < possible_relocations_end;
|
|
||||||
cursor += sizeof(compiler::target::uword)) {
|
cursor += sizeof(compiler::target::uword)) {
|
||||||
compiler::target::uword data =
|
compiler::target::uword data =
|
||||||
*reinterpret_cast<compiler::target::uword*>(cursor);
|
*reinterpret_cast<compiler::target::uword*>(cursor);
|
||||||
|
@ -799,8 +716,6 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
WriteWordLiteralText(data);
|
WriteWordLiteralText(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(next_reloc_offset != (possible_relocations_end - payload_start));
|
|
||||||
WriteByteSequence(possible_relocations_end, payload_end);
|
|
||||||
text_offset += payload_size;
|
text_offset += payload_size;
|
||||||
#else
|
#else
|
||||||
text_offset += WriteByteSequence(payload_start, payload_end);
|
text_offset += WriteByteSequence(payload_start, payload_end);
|
||||||
|
@ -808,43 +723,26 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
|
|
||||||
// 4. Write from the payload end to object end. Note we can't simply copy
|
// 4. Write from the payload end to object end. Note we can't simply copy
|
||||||
// from the object because the host object may have less alignment filler
|
// from the object because the host object may have less alignment filler
|
||||||
// than the target object in the cross-word case. Not written for AOT
|
// than the target object in the cross-word case.
|
||||||
// snapshots using bare instructions.
|
uword unaligned_size =
|
||||||
if (!bare_instruction_payloads) {
|
compiler::target::Instructions::HeaderSize() + payload_size;
|
||||||
uword unaligned_size =
|
uword alignment_size =
|
||||||
compiler::target::Instructions::HeaderSize() + payload_size;
|
Utils::RoundUp(unaligned_size,
|
||||||
uword alignment_size =
|
compiler::target::ObjectAlignment::kObjectAlignment) -
|
||||||
Utils::RoundUp(
|
unaligned_size;
|
||||||
unaligned_size,
|
while (alignment_size > 0) {
|
||||||
compiler::target::ObjectAlignment::kObjectAlignment) -
|
WriteWordLiteralText(compiler::Assembler::GetBreakInstructionFiller());
|
||||||
unaligned_size;
|
alignment_size -= sizeof(compiler::target::uword);
|
||||||
while (alignment_size > 0) {
|
text_offset += sizeof(compiler::target::uword);
|
||||||
WriteWordLiteralText(
|
|
||||||
compiler::Assembler::GetBreakInstructionFiller());
|
|
||||||
alignment_size -= sizeof(compiler::target::uword);
|
|
||||||
text_offset += sizeof(compiler::target::uword);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(kWordSize != compiler::target::kWordSize ||
|
|
||||||
(text_offset - instr_start) == insns.raw()->HeapSize());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASSERT(kWordSize != compiler::target::kWordSize ||
|
||||||
|
(text_offset - instr_start) == insns.raw()->HeapSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT((text_offset - instr_start) == SizeInSnapshot(insns.raw()));
|
ASSERT((text_offset - instr_start) == SizeInSnapshot(insns.raw()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should be a no-op unless writing bare instruction payloads, in which case
|
|
||||||
// we need to add post-payload padding to the object alignment.
|
|
||||||
text_offset +=
|
|
||||||
Align(compiler::target::ObjectAlignment::kObjectAlignment, text_offset);
|
|
||||||
|
|
||||||
ASSERT(Image::kHeaderSize +
|
|
||||||
(bare_instruction_payloads
|
|
||||||
? compiler::target::InstructionsSection::HeaderSize()
|
|
||||||
: 0) +
|
|
||||||
text_offset ==
|
|
||||||
image_size);
|
|
||||||
|
|
||||||
FrameUnwindEpilogue();
|
FrameUnwindEpilogue();
|
||||||
|
|
||||||
#if defined(DART_PRECOMPILER)
|
#if defined(DART_PRECOMPILER)
|
||||||
|
@ -865,7 +763,7 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
// we can pass nullptr for the bytes of the section/segment.
|
// we can pass nullptr for the bytes of the section/segment.
|
||||||
auto const debug_segment_base2 =
|
auto const debug_segment_base2 =
|
||||||
debug_dwarf_->elf()->AddText(instructions_symbol, /*bytes=*/nullptr,
|
debug_dwarf_->elf()->AddText(instructions_symbol, /*bytes=*/nullptr,
|
||||||
section_headers_size + text_offset);
|
Image::kHeaderSize + text_offset);
|
||||||
ASSERT(debug_segment_base2 == debug_segment_base);
|
ASSERT(debug_segment_base2 == debug_segment_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -890,7 +788,7 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
const char* data_symbol =
|
const char* data_symbol =
|
||||||
vm ? "_kDartVmSnapshotData" : "_kDartIsolateSnapshotData";
|
vm ? "_kDartVmSnapshotData" : "_kDartIsolateSnapshotData";
|
||||||
assembly_stream_.Print(".globl %s\n", data_symbol);
|
assembly_stream_.Print(".globl %s\n", data_symbol);
|
||||||
Align(kMaxObjectAlignment);
|
assembly_stream_.Print(".balign %" Pd ", 0\n", kMaxObjectAlignment);
|
||||||
assembly_stream_.Print("%s:\n", data_symbol);
|
assembly_stream_.Print("%s:\n", data_symbol);
|
||||||
uword buffer = reinterpret_cast<uword>(clustered_stream->buffer());
|
uword buffer = reinterpret_cast<uword>(clustered_stream->buffer());
|
||||||
intptr_t length = clustered_stream->bytes_written();
|
intptr_t length = clustered_stream->bytes_written();
|
||||||
|
@ -976,33 +874,13 @@ void AssemblyImageWriter::FrameUnwindEpilogue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t AssemblyImageWriter::WriteByteSequence(uword start, uword end) {
|
intptr_t AssemblyImageWriter::WriteByteSequence(uword start, uword end) {
|
||||||
assert(end >= start);
|
for (auto* cursor = reinterpret_cast<compiler::target::uword*>(start);
|
||||||
auto const end_of_words =
|
cursor < reinterpret_cast<compiler::target::uword*>(end); cursor++) {
|
||||||
Utils::RoundDown(end, sizeof(compiler::target::uword));
|
|
||||||
for (auto cursor = reinterpret_cast<compiler::target::uword*>(start);
|
|
||||||
cursor < reinterpret_cast<compiler::target::uword*>(end_of_words);
|
|
||||||
cursor++) {
|
|
||||||
WriteWordLiteralText(*cursor);
|
WriteWordLiteralText(*cursor);
|
||||||
}
|
}
|
||||||
if (end != end_of_words) {
|
|
||||||
auto start_of_rest = reinterpret_cast<const uint8_t*>(end_of_words);
|
|
||||||
assembly_stream_.Print(".byte ");
|
|
||||||
for (auto cursor = start_of_rest;
|
|
||||||
cursor < reinterpret_cast<const uint8_t*>(end); cursor++) {
|
|
||||||
if (cursor != start_of_rest) assembly_stream_.Print(", ");
|
|
||||||
assembly_stream_.Print("0x%0.2" Px "", *cursor);
|
|
||||||
}
|
|
||||||
assembly_stream_.Print("\n");
|
|
||||||
}
|
|
||||||
return end - start;
|
return end - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t AssemblyImageWriter::Align(intptr_t alignment, uword position) {
|
|
||||||
const uword next_position = Utils::RoundUp(position, alignment);
|
|
||||||
assembly_stream_.Print(".balign %" Pd ", 0\n", alignment);
|
|
||||||
return next_position - position;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlobImageWriter::BlobImageWriter(Thread* thread,
|
BlobImageWriter::BlobImageWriter(Thread* thread,
|
||||||
uint8_t** instructions_blob_buffer,
|
uint8_t** instructions_blob_buffer,
|
||||||
ReAlloc alloc,
|
ReAlloc alloc,
|
||||||
|
@ -1034,9 +912,7 @@ intptr_t BlobImageWriter::WriteByteSequence(uword start, uword end) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
const bool bare_instruction_payloads =
|
const intptr_t instructions_length = next_text_offset_;
|
||||||
FLAG_precompiled_mode && FLAG_use_bare_instructions;
|
|
||||||
|
|
||||||
#ifdef DART_PRECOMPILER
|
#ifdef DART_PRECOMPILER
|
||||||
intptr_t segment_base = 0;
|
intptr_t segment_base = 0;
|
||||||
if (elf_ != nullptr) {
|
if (elf_ != nullptr) {
|
||||||
|
@ -1050,9 +926,7 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
|
|
||||||
// This header provides the gap to make the instructions snapshot look like a
|
// This header provides the gap to make the instructions snapshot look like a
|
||||||
// HeapPage.
|
// HeapPage.
|
||||||
const intptr_t image_size = Utils::RoundUp(
|
instructions_blob_stream_.WriteTargetWord(instructions_length);
|
||||||
next_text_offset_, compiler::target::ObjectAlignment::kObjectAlignment);
|
|
||||||
instructions_blob_stream_.WriteTargetWord(image_size);
|
|
||||||
#if defined(DART_PRECOMPILER)
|
#if defined(DART_PRECOMPILER)
|
||||||
instructions_blob_stream_.WriteTargetWord(
|
instructions_blob_stream_.WriteTargetWord(
|
||||||
elf_ != nullptr ? bss_base_ - segment_base : 0);
|
elf_ != nullptr ? bss_base_ - segment_base : 0);
|
||||||
|
@ -1065,36 +939,6 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
instructions_blob_stream_.WriteTargetWord(0);
|
instructions_blob_stream_.WriteTargetWord(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bare_instruction_payloads) {
|
|
||||||
const intptr_t image_payload_length = image_size - Image::kHeaderSize;
|
|
||||||
// Add the RawInstructionsSection header.
|
|
||||||
uword marked_tags = 0;
|
|
||||||
marked_tags = RawObject::OldBit::update(true, marked_tags);
|
|
||||||
marked_tags = RawObject::OldAndNotRememberedBit::update(true, marked_tags);
|
|
||||||
marked_tags = RawObject::SizeTag::update(image_payload_length, marked_tags);
|
|
||||||
marked_tags =
|
|
||||||
RawObject::ClassIdTag::update(kInstructionsSectionCid, marked_tags);
|
|
||||||
|
|
||||||
instructions_blob_stream_.WriteTargetWord(marked_tags);
|
|
||||||
// Uses next_text_offset_ to avoid any post-payload padding.
|
|
||||||
const intptr_t instructions_length =
|
|
||||||
next_text_offset_ - Image::kHeaderSize -
|
|
||||||
compiler::target::InstructionsSection::HeaderSize();
|
|
||||||
instructions_blob_stream_.WriteTargetWord(instructions_length);
|
|
||||||
|
|
||||||
if (profile_writer_ != nullptr) {
|
|
||||||
const intptr_t offset = Image::kHeaderSize;
|
|
||||||
const intptr_t non_instruction_bytes =
|
|
||||||
compiler::target::InstructionsSection::HeaderSize();
|
|
||||||
profile_writer_->SetObjectTypeAndName({offset_space_, offset},
|
|
||||||
"InstructionsSection",
|
|
||||||
/*name=*/nullptr);
|
|
||||||
profile_writer_->AttributeBytesTo({offset_space_, offset},
|
|
||||||
non_instruction_bytes);
|
|
||||||
profile_writer_->AddRoot({offset_space_, offset});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
intptr_t text_offset = 0;
|
intptr_t text_offset = 0;
|
||||||
|
|
||||||
#if defined(DART_PRECOMPILER)
|
#if defined(DART_PRECOMPILER)
|
||||||
|
@ -1108,15 +952,6 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
const bool is_trampoline = data.trampoline_bytes != nullptr;
|
const bool is_trampoline = data.trampoline_bytes != nullptr;
|
||||||
ASSERT((data.text_offset_ - instructions_[0].text_offset_) == text_offset);
|
ASSERT((data.text_offset_ - instructions_[0].text_offset_) == text_offset);
|
||||||
|
|
||||||
if (bare_instruction_payloads && profile_writer_ != nullptr) {
|
|
||||||
const intptr_t instructions_sections_offset = Image::kHeaderSize;
|
|
||||||
profile_writer_->AttributeReferenceTo(
|
|
||||||
{offset_space_, instructions_sections_offset},
|
|
||||||
{{offset_space_, instructions_blob_stream_.Position()},
|
|
||||||
V8SnapshotProfileWriter::Reference::kElement,
|
|
||||||
text_offset});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_trampoline) {
|
if (is_trampoline) {
|
||||||
const auto start = reinterpret_cast<uword>(data.trampoline_bytes);
|
const auto start = reinterpret_cast<uword>(data.trampoline_bytes);
|
||||||
const auto end = start + data.trampline_length;
|
const auto end = start + data.trampline_length;
|
||||||
|
@ -1130,9 +965,17 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
|
|
||||||
const Instructions& insns = *instructions_[i].insns_;
|
const Instructions& insns = *instructions_[i].insns_;
|
||||||
AutoTraceImage(insns, 0, &this->instructions_blob_stream_);
|
AutoTraceImage(insns, 0, &this->instructions_blob_stream_);
|
||||||
const uword payload_start = insns.PayloadStart();
|
|
||||||
|
|
||||||
ASSERT(Utils::IsAligned(payload_start, sizeof(compiler::target::uword)));
|
uword object_start = reinterpret_cast<uword>(insns.raw_ptr());
|
||||||
|
uword payload_start = insns.PayloadStart();
|
||||||
|
uword payload_size =
|
||||||
|
Utils::RoundUp(
|
||||||
|
compiler::target::Instructions::HeaderSize() + insns.Size(),
|
||||||
|
compiler::target::ObjectAlignment::kObjectAlignment) -
|
||||||
|
compiler::target::Instructions::HeaderSize();
|
||||||
|
uword object_end = payload_start + payload_size;
|
||||||
|
|
||||||
|
ASSERT(Utils::IsAligned(payload_start, sizeof(uword)));
|
||||||
|
|
||||||
// Write Instructions with the mark and read-only bits set.
|
// Write Instructions with the mark and read-only bits set.
|
||||||
uword marked_tags = insns.raw_ptr()->tags_;
|
uword marked_tags = insns.raw_ptr()->tags_;
|
||||||
|
@ -1146,49 +989,32 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
marked_tags |= static_cast<uword>(insns.raw_ptr()->hash_) << 32;
|
marked_tags |= static_cast<uword>(insns.raw_ptr()->hash_) << 32;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
intptr_t payload_stream_start = 0;
|
||||||
|
|
||||||
#if defined(IS_SIMARM_X64)
|
#if defined(IS_SIMARM_X64)
|
||||||
const intptr_t start_offset = instructions_blob_stream_.bytes_written();
|
const intptr_t start_offset = instructions_blob_stream_.bytes_written();
|
||||||
const intptr_t size_in_bytes = InstructionsSizeInSnapshot(insns.raw());
|
const intptr_t size_in_bytes = InstructionsSizeInSnapshot(insns.Size());
|
||||||
marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
|
marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
|
||||||
|
instructions_blob_stream_.WriteTargetWord(marked_tags);
|
||||||
if (!bare_instruction_payloads) {
|
instructions_blob_stream_.WriteFixed<uint32_t>(
|
||||||
instructions_blob_stream_.WriteTargetWord(marked_tags);
|
insns.raw_ptr()->size_and_flags_);
|
||||||
instructions_blob_stream_.WriteFixed<uint32_t>(
|
payload_stream_start = instructions_blob_stream_.Position();
|
||||||
insns.raw_ptr()->size_and_flags_);
|
|
||||||
} else {
|
|
||||||
ASSERT(Utils::IsAligned(instructions_blob_stream_.Position(),
|
|
||||||
kBareInstructionsAlignment));
|
|
||||||
}
|
|
||||||
const intptr_t payload_stream_start = instructions_blob_stream_.Position();
|
|
||||||
instructions_blob_stream_.WriteBytes(
|
instructions_blob_stream_.WriteBytes(
|
||||||
reinterpret_cast<const void*>(insns.PayloadStart()), insns.Size());
|
reinterpret_cast<const void*>(insns.PayloadStart()), insns.Size());
|
||||||
const intptr_t alignment =
|
instructions_blob_stream_.Align(
|
||||||
bare_instruction_payloads
|
compiler::target::ObjectAlignment::kObjectAlignment);
|
||||||
? kBareInstructionsAlignment
|
|
||||||
: compiler::target::ObjectAlignment::kObjectAlignment;
|
|
||||||
instructions_blob_stream_.Align(alignment);
|
|
||||||
const intptr_t end_offset = instructions_blob_stream_.bytes_written();
|
const intptr_t end_offset = instructions_blob_stream_.bytes_written();
|
||||||
text_offset += (end_offset - start_offset);
|
text_offset += (end_offset - start_offset);
|
||||||
|
USE(object_start);
|
||||||
|
USE(object_end);
|
||||||
#else // defined(IS_SIMARM_X64)
|
#else // defined(IS_SIMARM_X64)
|
||||||
// Only payload is output in AOT snapshots.
|
payload_stream_start = instructions_blob_stream_.Position() +
|
||||||
const uword header_size =
|
(insns.PayloadStart() - object_start);
|
||||||
bare_instruction_payloads
|
|
||||||
? 0
|
instructions_blob_stream_.WriteWord(marked_tags);
|
||||||
: compiler::target::Instructions::HeaderSize();
|
text_offset += sizeof(uword);
|
||||||
const uword payload_size = SizeInSnapshot(insns.raw()) - header_size;
|
object_start += sizeof(uword);
|
||||||
const uword object_end = payload_start + payload_size;
|
text_offset += WriteByteSequence(object_start, object_end);
|
||||||
if (!bare_instruction_payloads) {
|
|
||||||
uword object_start = reinterpret_cast<uword>(insns.raw_ptr());
|
|
||||||
instructions_blob_stream_.WriteWord(marked_tags);
|
|
||||||
text_offset += sizeof(uword);
|
|
||||||
object_start += sizeof(uword);
|
|
||||||
text_offset += WriteByteSequence(object_start, payload_start);
|
|
||||||
} else {
|
|
||||||
ASSERT(Utils::IsAligned(instructions_blob_stream_.Position(),
|
|
||||||
kBareInstructionsAlignment));
|
|
||||||
}
|
|
||||||
const intptr_t payload_stream_start = instructions_blob_stream_.Position();
|
|
||||||
text_offset += WriteByteSequence(payload_start, object_end);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(DART_PRECOMPILER)
|
#if defined(DART_PRECOMPILER)
|
||||||
|
@ -1250,12 +1076,7 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||||
ImageWriter::SizeInSnapshot(insns.raw()));
|
ImageWriter::SizeInSnapshot(insns.raw()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should be a no-op unless writing bare instruction payloads, in which case
|
ASSERT(instructions_blob_stream_.bytes_written() == instructions_length);
|
||||||
// we need to add post-payload padding to the object alignment.
|
|
||||||
instructions_blob_stream_.Align(
|
|
||||||
compiler::target::ObjectAlignment::kObjectAlignment);
|
|
||||||
|
|
||||||
ASSERT(instructions_blob_stream_.bytes_written() == image_size);
|
|
||||||
|
|
||||||
#ifdef DART_PRECOMPILER
|
#ifdef DART_PRECOMPILER
|
||||||
const char* instructions_symbol =
|
const char* instructions_symbol =
|
||||||
|
@ -1293,18 +1114,6 @@ RawApiError* ImageReader::VerifyAlignment() const {
|
||||||
return ApiError::null();
|
return ApiError::null();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
|
||||||
uword ImageReader::GetBareInstructionsAt(uint32_t offset) const {
|
|
||||||
ASSERT(Utils::IsAligned(offset, ImageWriter::kBareInstructionsAlignment));
|
|
||||||
return reinterpret_cast<uword>(instructions_image_) + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
uword ImageReader::GetBareInstructionsEnd() const {
|
|
||||||
Image image(instructions_image_);
|
|
||||||
return reinterpret_cast<uword>(image.object_start()) + image.object_size();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RawInstructions* ImageReader::GetInstructionsAt(uint32_t offset) const {
|
RawInstructions* ImageReader::GetInstructionsAt(uint32_t offset) const {
|
||||||
ASSERT(Utils::IsAligned(offset, kObjectAlignment));
|
ASSERT(Utils::IsAligned(offset, kObjectAlignment));
|
||||||
|
|
||||||
|
|
|
@ -69,8 +69,6 @@ class ImageReader : public ZoneAllocated {
|
||||||
|
|
||||||
RawApiError* VerifyAlignment() const;
|
RawApiError* VerifyAlignment() const;
|
||||||
|
|
||||||
ONLY_IN_PRECOMPILED(uword GetBareInstructionsAt(uint32_t offset) const);
|
|
||||||
ONLY_IN_PRECOMPILED(uword GetBareInstructionsEnd() const);
|
|
||||||
RawInstructions* GetInstructionsAt(uint32_t offset) const;
|
RawInstructions* GetInstructionsAt(uint32_t offset) const;
|
||||||
RawObject* GetObjectAt(uint32_t offset) const;
|
RawObject* GetObjectAt(uint32_t offset) const;
|
||||||
|
|
||||||
|
@ -155,9 +153,6 @@ class ImageWriter : public ValueObject {
|
||||||
void ResetOffsets() {
|
void ResetOffsets() {
|
||||||
next_data_offset_ = Image::kHeaderSize;
|
next_data_offset_ = Image::kHeaderSize;
|
||||||
next_text_offset_ = Image::kHeaderSize;
|
next_text_offset_ = Image::kHeaderSize;
|
||||||
if (FLAG_use_bare_instructions && FLAG_precompiled_mode) {
|
|
||||||
next_text_offset_ += compiler::target::InstructionsSection::HeaderSize();
|
|
||||||
}
|
|
||||||
objects_.Clear();
|
objects_.Clear();
|
||||||
instructions_.Clear();
|
instructions_.Clear();
|
||||||
}
|
}
|
||||||
|
@ -184,7 +179,6 @@ class ImageWriter : public ValueObject {
|
||||||
void TraceInstructions(const Instructions& instructions);
|
void TraceInstructions(const Instructions& instructions);
|
||||||
|
|
||||||
static intptr_t SizeInSnapshot(RawObject* object);
|
static intptr_t SizeInSnapshot(RawObject* object);
|
||||||
static const intptr_t kBareInstructionsAlignment = 4;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void WriteROData(WriteStream* stream);
|
void WriteROData(WriteStream* stream);
|
||||||
|
@ -335,7 +329,6 @@ class AssemblyImageWriter : public ImageWriter {
|
||||||
void FrameUnwindPrologue();
|
void FrameUnwindPrologue();
|
||||||
void FrameUnwindEpilogue();
|
void FrameUnwindEpilogue();
|
||||||
intptr_t WriteByteSequence(uword start, uword end);
|
intptr_t WriteByteSequence(uword start, uword end);
|
||||||
intptr_t Align(intptr_t alignment, uword position = 0);
|
|
||||||
|
|
||||||
#if defined(TARGET_ARCH_IS_64_BIT)
|
#if defined(TARGET_ARCH_IS_64_BIT)
|
||||||
const char* kLiteralPrefix = ".quad";
|
const char* kLiteralPrefix = ".quad";
|
||||||
|
|
|
@ -150,8 +150,6 @@ RawClass* Object::kernel_program_info_class_ =
|
||||||
RawClass* Object::code_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
RawClass* Object::code_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
||||||
RawClass* Object::bytecode_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
RawClass* Object::bytecode_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
||||||
RawClass* Object::instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
RawClass* Object::instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
||||||
RawClass* Object::instructions_section_class_ =
|
|
||||||
reinterpret_cast<RawClass*>(RAW_NULL);
|
|
||||||
RawClass* Object::object_pool_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
RawClass* Object::object_pool_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
||||||
RawClass* Object::pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
RawClass* Object::pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
||||||
RawClass* Object::code_source_map_class_ =
|
RawClass* Object::code_source_map_class_ =
|
||||||
|
@ -795,9 +793,6 @@ void Object::Init(Isolate* isolate) {
|
||||||
cls = Class::New<Instructions, RTN::Instructions>(isolate);
|
cls = Class::New<Instructions, RTN::Instructions>(isolate);
|
||||||
instructions_class_ = cls.raw();
|
instructions_class_ = cls.raw();
|
||||||
|
|
||||||
cls = Class::New<InstructionsSection, RTN::InstructionsSection>(isolate);
|
|
||||||
instructions_section_class_ = cls.raw();
|
|
||||||
|
|
||||||
cls = Class::New<ObjectPool, RTN::ObjectPool>(isolate);
|
cls = Class::New<ObjectPool, RTN::ObjectPool>(isolate);
|
||||||
object_pool_class_ = cls.raw();
|
object_pool_class_ = cls.raw();
|
||||||
|
|
||||||
|
@ -1226,7 +1221,6 @@ void Object::Cleanup() {
|
||||||
code_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
code_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
||||||
bytecode_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
bytecode_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
||||||
instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
||||||
instructions_section_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
|
||||||
object_pool_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
object_pool_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
||||||
pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
||||||
code_source_map_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
code_source_map_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
||||||
|
@ -1329,7 +1323,6 @@ void Object::FinalizeVMIsolate(Isolate* isolate) {
|
||||||
SET_CLASS_NAME(code, Code);
|
SET_CLASS_NAME(code, Code);
|
||||||
SET_CLASS_NAME(bytecode, Bytecode);
|
SET_CLASS_NAME(bytecode, Bytecode);
|
||||||
SET_CLASS_NAME(instructions, Instructions);
|
SET_CLASS_NAME(instructions, Instructions);
|
||||||
SET_CLASS_NAME(instructions_section, InstructionsSection);
|
|
||||||
SET_CLASS_NAME(object_pool, ObjectPool);
|
SET_CLASS_NAME(object_pool, ObjectPool);
|
||||||
SET_CLASS_NAME(code_source_map, CodeSourceMap);
|
SET_CLASS_NAME(code_source_map, CodeSourceMap);
|
||||||
SET_CLASS_NAME(pc_descriptors, PcDescriptors);
|
SET_CLASS_NAME(pc_descriptors, PcDescriptors);
|
||||||
|
@ -4543,8 +4536,6 @@ const char* Class::GenerateUserVisibleName() const {
|
||||||
return Symbols::Bytecode().ToCString();
|
return Symbols::Bytecode().ToCString();
|
||||||
case kInstructionsCid:
|
case kInstructionsCid:
|
||||||
return Symbols::Instructions().ToCString();
|
return Symbols::Instructions().ToCString();
|
||||||
case kInstructionsSectionCid:
|
|
||||||
return Symbols::InstructionsSection().ToCString();
|
|
||||||
case kObjectPoolCid:
|
case kObjectPoolCid:
|
||||||
return Symbols::ObjectPool().ToCString();
|
return Symbols::ObjectPool().ToCString();
|
||||||
case kCodeSourceMapCid:
|
case kCodeSourceMapCid:
|
||||||
|
@ -13117,7 +13108,7 @@ void Library::CheckFunctionFingerprints() {
|
||||||
}
|
}
|
||||||
#endif // defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME).
|
#endif // defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME).
|
||||||
|
|
||||||
RawInstructions* Instructions::New(intptr_t size, bool has_monomorphic_entry) {
|
RawInstructions* Instructions::New(intptr_t size, bool has_single_entry_point) {
|
||||||
ASSERT(size >= 0);
|
ASSERT(size >= 0);
|
||||||
ASSERT(Object::instructions_class() != Class::null());
|
ASSERT(Object::instructions_class() != Class::null());
|
||||||
if (size < 0 || size > kMaxElements) {
|
if (size < 0 || size > kMaxElements) {
|
||||||
|
@ -13132,7 +13123,7 @@ RawInstructions* Instructions::New(intptr_t size, bool has_monomorphic_entry) {
|
||||||
NoSafepointScope no_safepoint;
|
NoSafepointScope no_safepoint;
|
||||||
result ^= raw;
|
result ^= raw;
|
||||||
result.SetSize(size);
|
result.SetSize(size);
|
||||||
result.SetHasMonomorphicEntry(has_monomorphic_entry);
|
result.SetHasSingleEntryPoint(has_single_entry_point);
|
||||||
result.set_stats(nullptr);
|
result.set_stats(nullptr);
|
||||||
}
|
}
|
||||||
return result.raw();
|
return result.raw();
|
||||||
|
@ -13157,10 +13148,6 @@ void Instructions::set_stats(CodeStatistics* stats) const {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* InstructionsSection::ToCString() const {
|
|
||||||
return "InstructionsSection";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode integer |value| in SLEB128 format and store into |data|.
|
// Encode integer |value| in SLEB128 format and store into |data|.
|
||||||
static void EncodeSLEB128(GrowableArray<uint8_t>* data, intptr_t value) {
|
static void EncodeSLEB128(GrowableArray<uint8_t>* data, intptr_t value) {
|
||||||
bool is_last_part = false;
|
bool is_last_part = false;
|
||||||
|
@ -15338,11 +15325,12 @@ void Code::Disassemble(DisassemblyFormatter* formatter) const {
|
||||||
if (!FLAG_support_disassembler) {
|
if (!FLAG_support_disassembler) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const uword start = PayloadStart();
|
const Instructions& instr = Instructions::Handle(instructions());
|
||||||
|
uword start = instr.PayloadStart();
|
||||||
if (formatter == NULL) {
|
if (formatter == NULL) {
|
||||||
Disassembler::Disassemble(start, start + Size(), *this);
|
Disassembler::Disassemble(start, start + instr.Size(), *this);
|
||||||
} else {
|
} else {
|
||||||
Disassembler::Disassemble(start, start + Size(), formatter, *this);
|
Disassembler::Disassemble(start, start + instr.Size(), formatter, *this);
|
||||||
}
|
}
|
||||||
#endif // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
|
#endif // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
|
||||||
}
|
}
|
||||||
|
@ -15482,7 +15470,7 @@ RawCode* Code::FinalizeCode(FlowGraphCompiler* compiler,
|
||||||
assembler->GetSelfHandle() = code.raw();
|
assembler->GetSelfHandle() = code.raw();
|
||||||
#endif
|
#endif
|
||||||
Instructions& instrs = Instructions::ZoneHandle(Instructions::New(
|
Instructions& instrs = Instructions::ZoneHandle(Instructions::New(
|
||||||
assembler->CodeSize(), assembler->has_monomorphic_entry()));
|
assembler->CodeSize(), assembler->has_single_entry_point()));
|
||||||
|
|
||||||
{
|
{
|
||||||
// Important: if GC is triggerred at any point between Instructions::New
|
// Important: if GC is triggerred at any point between Instructions::New
|
||||||
|
@ -15883,10 +15871,11 @@ void Code::DumpSourcePositions(bool relative_addresses) const {
|
||||||
|
|
||||||
bool Code::VerifyBSSRelocations() const {
|
bool Code::VerifyBSSRelocations() const {
|
||||||
const auto& descriptors = PcDescriptors::Handle(pc_descriptors());
|
const auto& descriptors = PcDescriptors::Handle(pc_descriptors());
|
||||||
|
const auto& insns = Instructions::Handle(instructions());
|
||||||
PcDescriptors::Iterator iterator(descriptors,
|
PcDescriptors::Iterator iterator(descriptors,
|
||||||
RawPcDescriptors::kBSSRelocation);
|
RawPcDescriptors::kBSSRelocation);
|
||||||
while (iterator.MoveNext()) {
|
while (iterator.MoveNext()) {
|
||||||
const uword reloc = PayloadStart() + iterator.PcOffset();
|
const uword reloc = insns.PayloadStart() + iterator.PcOffset();
|
||||||
const word target = *reinterpret_cast<word*>(reloc);
|
const word target = *reinterpret_cast<word*>(reloc);
|
||||||
// The relocation is in its original unpatched form -- the addend
|
// The relocation is in its original unpatched form -- the addend
|
||||||
// representing the target symbol itself.
|
// representing the target symbol itself.
|
||||||
|
|
|
@ -482,9 +482,6 @@ class Object {
|
||||||
static RawClass* code_class() { return code_class_; }
|
static RawClass* code_class() { return code_class_; }
|
||||||
static RawClass* bytecode_class() { return bytecode_class_; }
|
static RawClass* bytecode_class() { return bytecode_class_; }
|
||||||
static RawClass* instructions_class() { return instructions_class_; }
|
static RawClass* instructions_class() { return instructions_class_; }
|
||||||
static RawClass* instructions_section_class() {
|
|
||||||
return instructions_section_class_;
|
|
||||||
}
|
|
||||||
static RawClass* object_pool_class() { return object_pool_class_; }
|
static RawClass* object_pool_class() { return object_pool_class_; }
|
||||||
static RawClass* pc_descriptors_class() { return pc_descriptors_class_; }
|
static RawClass* pc_descriptors_class() { return pc_descriptors_class_; }
|
||||||
static RawClass* code_source_map_class() { return code_source_map_class_; }
|
static RawClass* code_source_map_class() { return code_source_map_class_; }
|
||||||
|
@ -769,8 +766,6 @@ class Object {
|
||||||
static RawClass* code_class_; // Class of the Code vm object.
|
static RawClass* code_class_; // Class of the Code vm object.
|
||||||
static RawClass* bytecode_class_; // Class of the Bytecode vm object.
|
static RawClass* bytecode_class_; // Class of the Bytecode vm object.
|
||||||
static RawClass* instructions_class_; // Class of the Instructions vm object.
|
static RawClass* instructions_class_; // Class of the Instructions vm object.
|
||||||
static RawClass*
|
|
||||||
instructions_section_class_; // Class of InstructionsSection.
|
|
||||||
static RawClass* object_pool_class_; // Class of the ObjectPool vm object.
|
static RawClass* object_pool_class_; // Class of the ObjectPool vm object.
|
||||||
static RawClass* pc_descriptors_class_; // Class of PcDescriptors vm object.
|
static RawClass* pc_descriptors_class_; // Class of PcDescriptors vm object.
|
||||||
static RawClass* code_source_map_class_; // Class of CodeSourceMap vm object.
|
static RawClass* code_source_map_class_; // Class of CodeSourceMap vm object.
|
||||||
|
@ -5057,13 +5052,21 @@ class Instructions : public Object {
|
||||||
return SizeBits::decode(instr->ptr()->size_and_flags_);
|
return SizeBits::decode(instr->ptr()->size_and_flags_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasMonomorphicEntry() const {
|
bool HasSingleEntryPoint() const {
|
||||||
return FlagsBits::decode(raw_ptr()->size_and_flags_);
|
return FlagsBits::decode(raw_ptr()->size_and_flags_);
|
||||||
}
|
}
|
||||||
static bool HasMonomorphicEntry(const RawInstructions* instr) {
|
static bool HasSingleEntryPoint(const RawInstructions* instr) {
|
||||||
return FlagsBits::decode(instr->ptr()->size_and_flags_);
|
return FlagsBits::decode(instr->ptr()->size_and_flags_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ContainsPc(RawInstructions* instruction, uword pc) {
|
||||||
|
const uword offset = pc - PayloadStart(instruction);
|
||||||
|
// We use <= instead of < here because the saved-pc can be outside the
|
||||||
|
// instruction stream if the last instruction is a call we don't expect to
|
||||||
|
// return (e.g. because it throws an exception).
|
||||||
|
return offset <= static_cast<uword>(Size(instruction));
|
||||||
|
}
|
||||||
|
|
||||||
uword PayloadStart() const { return PayloadStart(raw()); }
|
uword PayloadStart() const { return PayloadStart(raw()); }
|
||||||
uword MonomorphicEntryPoint() const { return MonomorphicEntryPoint(raw()); }
|
uword MonomorphicEntryPoint() const { return MonomorphicEntryPoint(raw()); }
|
||||||
uword EntryPoint() const { return EntryPoint(raw()); }
|
uword EntryPoint() const { return EntryPoint(raw()); }
|
||||||
|
@ -5099,7 +5102,7 @@ class Instructions : public Object {
|
||||||
|
|
||||||
static uword MonomorphicEntryPoint(const RawInstructions* instr) {
|
static uword MonomorphicEntryPoint(const RawInstructions* instr) {
|
||||||
uword entry = PayloadStart(instr);
|
uword entry = PayloadStart(instr);
|
||||||
if (HasMonomorphicEntry(instr)) {
|
if (!HasSingleEntryPoint(instr)) {
|
||||||
entry += !FLAG_precompiled_mode ? kMonomorphicEntryOffsetJIT
|
entry += !FLAG_precompiled_mode ? kMonomorphicEntryOffsetJIT
|
||||||
: kMonomorphicEntryOffsetAOT;
|
: kMonomorphicEntryOffsetAOT;
|
||||||
}
|
}
|
||||||
|
@ -5108,7 +5111,7 @@ class Instructions : public Object {
|
||||||
|
|
||||||
static uword EntryPoint(const RawInstructions* instr) {
|
static uword EntryPoint(const RawInstructions* instr) {
|
||||||
uword entry = PayloadStart(instr);
|
uword entry = PayloadStart(instr);
|
||||||
if (HasMonomorphicEntry(instr)) {
|
if (!HasSingleEntryPoint(instr)) {
|
||||||
entry += !FLAG_precompiled_mode ? kPolymorphicEntryOffsetJIT
|
entry += !FLAG_precompiled_mode ? kPolymorphicEntryOffsetJIT
|
||||||
: kPolymorphicEntryOffsetAOT;
|
: kPolymorphicEntryOffsetAOT;
|
||||||
}
|
}
|
||||||
|
@ -5158,7 +5161,7 @@ class Instructions : public Object {
|
||||||
SizeBits::update(value, raw_ptr()->size_and_flags_));
|
SizeBits::update(value, raw_ptr()->size_and_flags_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetHasMonomorphicEntry(bool value) const {
|
void SetHasSingleEntryPoint(bool value) const {
|
||||||
StoreNonPointer(&raw_ptr()->size_and_flags_,
|
StoreNonPointer(&raw_ptr()->size_and_flags_,
|
||||||
FlagsBits::update(value, raw_ptr()->size_and_flags_));
|
FlagsBits::update(value, raw_ptr()->size_and_flags_));
|
||||||
}
|
}
|
||||||
|
@ -5167,7 +5170,7 @@ class Instructions : public Object {
|
||||||
// only be created using the Code::FinalizeCode method. This method creates
|
// only be created using the Code::FinalizeCode method. This method creates
|
||||||
// the RawInstruction and RawCode objects, sets up the pointer offsets
|
// the RawInstruction and RawCode objects, sets up the pointer offsets
|
||||||
// and links the two in a GC safe manner.
|
// and links the two in a GC safe manner.
|
||||||
static RawInstructions* New(intptr_t size, bool has_monomorphic_entry);
|
static RawInstructions* New(intptr_t size, bool has_single_entry_point);
|
||||||
|
|
||||||
FINAL_HEAP_OBJECT_IMPLEMENTATION(Instructions, Object);
|
FINAL_HEAP_OBJECT_IMPLEMENTATION(Instructions, Object);
|
||||||
friend class Class;
|
friend class Class;
|
||||||
|
@ -5177,34 +5180,6 @@ class Instructions : public Object {
|
||||||
friend class ImageWriter;
|
friend class ImageWriter;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Used only to provide memory accounting for the bare instruction payloads
|
|
||||||
// we serialize, since they are no longer part of RawInstructions objects.
|
|
||||||
class InstructionsSection : public Object {
|
|
||||||
public:
|
|
||||||
// Excludes HeaderSize().
|
|
||||||
intptr_t Size() const { return raw_ptr()->payload_length_; }
|
|
||||||
static intptr_t Size(const RawInstructionsSection* instr) {
|
|
||||||
return instr->ptr()->payload_length_;
|
|
||||||
}
|
|
||||||
static intptr_t InstanceSize() {
|
|
||||||
ASSERT(sizeof(RawInstructionsSection) ==
|
|
||||||
OFFSET_OF_RETURNED_VALUE(RawInstructionsSection, data));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static intptr_t InstanceSize(intptr_t size) {
|
|
||||||
return Utils::RoundUp(HeaderSize() + size, kObjectAlignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
static intptr_t HeaderSize() {
|
|
||||||
return Utils::RoundUp(sizeof(RawInstructionsSection), kWordSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FINAL_HEAP_OBJECT_IMPLEMENTATION(InstructionsSection, Object);
|
|
||||||
friend class Class;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LocalVarDescriptors : public Object {
|
class LocalVarDescriptors : public Object {
|
||||||
public:
|
public:
|
||||||
intptr_t Length() const;
|
intptr_t Length() const;
|
||||||
|
@ -5580,6 +5555,11 @@ class Code : public Object {
|
||||||
return code->ptr()->instructions_;
|
return code->ptr()->instructions_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the entry point of [InstructionsOf(code)].
|
||||||
|
static uword EntryPointOf(const RawCode* code) {
|
||||||
|
return Instructions::EntryPoint(InstructionsOf(code));
|
||||||
|
}
|
||||||
|
|
||||||
static intptr_t saved_instructions_offset() {
|
static intptr_t saved_instructions_offset() {
|
||||||
return OFFSET_OF(RawCode, instructions_);
|
return OFFSET_OF(RawCode, instructions_);
|
||||||
}
|
}
|
||||||
|
@ -5629,38 +5609,12 @@ class Code : public Object {
|
||||||
bool is_alive() const { return AliveBit::decode(raw_ptr()->state_bits_); }
|
bool is_alive() const { return AliveBit::decode(raw_ptr()->state_bits_); }
|
||||||
void set_is_alive(bool value) const;
|
void set_is_alive(bool value) const;
|
||||||
|
|
||||||
bool HasMonomorphicEntry() const { return HasMonomorphicEntry(raw()); }
|
|
||||||
static bool HasMonomorphicEntry(const RawCode* code) {
|
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
|
||||||
return code->ptr()->entry_point_ != code->ptr()->monomorphic_entry_point_;
|
|
||||||
#else
|
|
||||||
return Instructions::HasMonomorphicEntry(InstructionsOf(code));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the payload start of [instructions()].
|
// Returns the payload start of [instructions()].
|
||||||
uword PayloadStart() const { return PayloadStartOf(raw()); }
|
uword PayloadStart() const {
|
||||||
static uword PayloadStartOf(const RawCode* code) {
|
return Instructions::PayloadStart(instructions());
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
|
||||||
const uword entry_offset = HasMonomorphicEntry(code)
|
|
||||||
? Instructions::kPolymorphicEntryOffsetAOT
|
|
||||||
: 0;
|
|
||||||
return EntryPointOf(code) - entry_offset;
|
|
||||||
#else
|
|
||||||
return Instructions::PayloadStart(InstructionsOf(code));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the entry point of [instructions()].
|
// Returns the entry point of [instructions()].
|
||||||
uword EntryPoint() const { return EntryPointOf(raw()); }
|
uword EntryPoint() const { return Instructions::EntryPoint(instructions()); }
|
||||||
static uword EntryPointOf(const RawCode* code) {
|
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
|
||||||
return code->ptr()->entry_point_;
|
|
||||||
#else
|
|
||||||
return Instructions::EntryPoint(InstructionsOf(code));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the unchecked entry point of [instructions()].
|
// Returns the unchecked entry point of [instructions()].
|
||||||
uword UncheckedEntryPoint() const {
|
uword UncheckedEntryPoint() const {
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||||
|
@ -5671,11 +5625,7 @@ class Code : public Object {
|
||||||
}
|
}
|
||||||
// Returns the monomorphic entry point of [instructions()].
|
// Returns the monomorphic entry point of [instructions()].
|
||||||
uword MonomorphicEntryPoint() const {
|
uword MonomorphicEntryPoint() const {
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
|
||||||
return raw_ptr()->monomorphic_entry_point_;
|
|
||||||
#else
|
|
||||||
return Instructions::MonomorphicEntryPoint(instructions());
|
return Instructions::MonomorphicEntryPoint(instructions());
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
// Returns the unchecked monomorphic entry point of [instructions()].
|
// Returns the unchecked monomorphic entry point of [instructions()].
|
||||||
uword MonomorphicUncheckedEntryPoint() const {
|
uword MonomorphicUncheckedEntryPoint() const {
|
||||||
|
@ -5685,16 +5635,8 @@ class Code : public Object {
|
||||||
return MonomorphicEntryPoint() + raw_ptr()->unchecked_offset_;
|
return MonomorphicEntryPoint() + raw_ptr()->unchecked_offset_;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the size of [instructions()].
|
// Returns the size of [instructions()].
|
||||||
intptr_t Size() const { return PayloadSizeOf(raw()); }
|
intptr_t Size() const { return Instructions::Size(instructions()); }
|
||||||
static intptr_t PayloadSizeOf(const RawCode* code) {
|
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
|
||||||
return code->ptr()->instructions_length_;
|
|
||||||
#else
|
|
||||||
return Instructions::Size(InstructionsOf(code));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
RawObjectPool* GetObjectPool() const;
|
RawObjectPool* GetObjectPool() const;
|
||||||
// Returns whether the given PC address is in [instructions()].
|
// Returns whether the given PC address is in [instructions()].
|
||||||
|
@ -5703,8 +5645,8 @@ class Code : public Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether the given PC address is in [InstructionsOf(code)].
|
// Returns whether the given PC address is in [InstructionsOf(code)].
|
||||||
static bool ContainsInstructionAt(const RawCode* code, uword pc) {
|
static bool ContainsInstructionAt(const RawCode* code, uword addr) {
|
||||||
return RawCode::ContainsPC(code, pc);
|
return Instructions::ContainsPc(InstructionsOf(code), addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if there is a debugger breakpoint set in this code object.
|
// Returns true if there is a debugger breakpoint set in this code object.
|
||||||
|
@ -6108,13 +6050,11 @@ class Code : public Object {
|
||||||
|
|
||||||
// Returns the unchecked entry point offset for [instructions_].
|
// Returns the unchecked entry point offset for [instructions_].
|
||||||
uint32_t UncheckedEntryPointOffset() const {
|
uint32_t UncheckedEntryPointOffset() const {
|
||||||
return UncheckedEntryPointOffsetOf(raw());
|
|
||||||
}
|
|
||||||
static uint32_t UncheckedEntryPointOffsetOf(RawCode* code) {
|
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
return raw_ptr()->unchecked_entry_point_ - raw_ptr()->entry_point_;
|
||||||
#else
|
#else
|
||||||
return code->ptr()->unchecked_offset_;
|
return raw_ptr()->unchecked_offset_;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6152,7 +6092,6 @@ class Code : public Object {
|
||||||
friend class FunctionSerializationCluster;
|
friend class FunctionSerializationCluster;
|
||||||
friend class CodeSerializationCluster;
|
friend class CodeSerializationCluster;
|
||||||
friend class CodeDeserializationCluster;
|
friend class CodeDeserializationCluster;
|
||||||
friend class Deserializer; // for InitializeCachedEntryPointsFrom
|
|
||||||
friend class StubCode; // for set_object_pool
|
friend class StubCode; // for set_object_pool
|
||||||
friend class MegamorphicCacheTable; // for set_object_pool
|
friend class MegamorphicCacheTable; // for set_object_pool
|
||||||
friend class CodePatcher; // for set_instructions
|
friend class CodePatcher; // for set_instructions
|
||||||
|
|
|
@ -667,10 +667,6 @@ void Instructions::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstructionsSection::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
|
||||||
Object::PrintJSONImpl(stream, ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ObjectPool::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
void ObjectPool::PrintJSONImpl(JSONStream* stream, bool ref) const {
|
||||||
JSONObject jsobj(stream);
|
JSONObject jsobj(stream);
|
||||||
AddCommonObjectProperties(&jsobj, "Object", ref);
|
AddCommonObjectProperties(&jsobj, "Object", ref);
|
||||||
|
|
|
@ -100,13 +100,6 @@ intptr_t RawObject::HeapSizeFromClass() const {
|
||||||
instance_size = Instructions::InstanceSize(instructions_size);
|
instance_size = Instructions::InstanceSize(instructions_size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kInstructionsSectionCid: {
|
|
||||||
const RawInstructionsSection* raw_section =
|
|
||||||
reinterpret_cast<const RawInstructionsSection*>(this);
|
|
||||||
intptr_t section_size = InstructionsSection::Size(raw_section);
|
|
||||||
instance_size = InstructionsSection::InstanceSize(section_size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case kContextCid: {
|
case kContextCid: {
|
||||||
const RawContext* raw_context = reinterpret_cast<const RawContext*>(this);
|
const RawContext* raw_context = reinterpret_cast<const RawContext*>(this);
|
||||||
intptr_t num_variables = raw_context->ptr()->num_variables_;
|
intptr_t num_variables = raw_context->ptr()->num_variables_;
|
||||||
|
@ -556,7 +549,6 @@ NULL_VISITOR(TransferableTypedData)
|
||||||
REGULAR_VISITOR(Pointer)
|
REGULAR_VISITOR(Pointer)
|
||||||
NULL_VISITOR(DynamicLibrary)
|
NULL_VISITOR(DynamicLibrary)
|
||||||
VARIABLE_NULL_VISITOR(Instructions, Instructions::Size(raw_obj))
|
VARIABLE_NULL_VISITOR(Instructions, Instructions::Size(raw_obj))
|
||||||
VARIABLE_NULL_VISITOR(InstructionsSection, InstructionsSection::Size(raw_obj))
|
|
||||||
VARIABLE_NULL_VISITOR(PcDescriptors, raw_obj->ptr()->length_)
|
VARIABLE_NULL_VISITOR(PcDescriptors, raw_obj->ptr()->length_)
|
||||||
VARIABLE_NULL_VISITOR(CodeSourceMap, raw_obj->ptr()->length_)
|
VARIABLE_NULL_VISITOR(CodeSourceMap, raw_obj->ptr()->length_)
|
||||||
VARIABLE_NULL_VISITOR(CompressedStackMaps, raw_obj->ptr()->payload_size())
|
VARIABLE_NULL_VISITOR(CompressedStackMaps, raw_obj->ptr()->payload_size())
|
||||||
|
@ -572,12 +564,12 @@ UNREACHABLE_VISITOR(String)
|
||||||
// Smi has no heap representation.
|
// Smi has no heap representation.
|
||||||
UNREACHABLE_VISITOR(Smi)
|
UNREACHABLE_VISITOR(Smi)
|
||||||
|
|
||||||
bool RawCode::ContainsPC(const RawObject* raw_obj, uword pc) {
|
bool RawCode::ContainsPC(RawObject* raw_obj, uword pc) {
|
||||||
if (!raw_obj->IsCode()) return false;
|
if (raw_obj->IsCode()) {
|
||||||
auto const raw_code = static_cast<const RawCode*>(raw_obj);
|
RawCode* raw_code = static_cast<RawCode*>(raw_obj);
|
||||||
const uword start = Code::PayloadStartOf(raw_code);
|
return RawInstructions::ContainsPC(raw_code->ptr()->instructions_, pc);
|
||||||
const uword size = Code::PayloadSizeOf(raw_code);
|
}
|
||||||
return (pc - start) <= size; // pc may point just past last instruction.
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t RawCode::VisitCodePointers(RawCode* raw_obj,
|
intptr_t RawCode::VisitCodePointers(RawCode* raw_obj,
|
||||||
|
@ -591,7 +583,8 @@ intptr_t RawCode::VisitCodePointers(RawCode* raw_obj,
|
||||||
// instructions. The variable portion of a Code object describes where to
|
// instructions. The variable portion of a Code object describes where to
|
||||||
// find those pointers for tracing.
|
// find those pointers for tracing.
|
||||||
if (Code::AliveBit::decode(obj->state_bits_)) {
|
if (Code::AliveBit::decode(obj->state_bits_)) {
|
||||||
uword entry_point = Code::PayloadStartOf(raw_obj);
|
uword entry_point = reinterpret_cast<uword>(obj->instructions_->ptr()) +
|
||||||
|
Instructions::HeaderSize();
|
||||||
for (intptr_t i = 0; i < length; i++) {
|
for (intptr_t i = 0; i < length; i++) {
|
||||||
int32_t offset = obj->data()[i];
|
int32_t offset = obj->data()[i];
|
||||||
visitor->VisitPointer(
|
visitor->VisitPointer(
|
||||||
|
@ -633,13 +626,12 @@ intptr_t RawObjectPool::VisitObjectPoolPointers(RawObjectPool* raw_obj,
|
||||||
return ObjectPool::InstanceSize(length);
|
return ObjectPool::InstanceSize(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RawInstructions::ContainsPC(const RawInstructions* raw_instr, uword pc) {
|
bool RawInstructions::ContainsPC(RawInstructions* raw_instr, uword pc) {
|
||||||
const uword start = Instructions::PayloadStart(raw_instr);
|
uword start_pc =
|
||||||
const uword size = Instructions::Size(raw_instr);
|
reinterpret_cast<uword>(raw_instr->ptr()) + Instructions::HeaderSize();
|
||||||
// We use <= instead of < here because the saved-pc can be outside the
|
uword end_pc = start_pc + Instructions::Size(raw_instr);
|
||||||
// instruction stream if the last instruction is a call we don't expect to
|
ASSERT(end_pc > start_pc);
|
||||||
// return (e.g. because it throws an exception).
|
return (pc >= start_pc) && (pc < end_pc);
|
||||||
return (pc - start) <= size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t RawInstance::VisitInstancePointers(RawInstance* raw_obj,
|
intptr_t RawInstance::VisitInstancePointers(RawInstance* raw_obj,
|
||||||
|
|
|
@ -1408,11 +1408,8 @@ class RawKernelProgramInfo : public RawObject {
|
||||||
class RawCode : public RawObject {
|
class RawCode : public RawObject {
|
||||||
RAW_HEAP_OBJECT_IMPLEMENTATION(Code);
|
RAW_HEAP_OBJECT_IMPLEMENTATION(Code);
|
||||||
|
|
||||||
// When in the precompiled runtime, there is no disabling of Code objects
|
// When in the precompiled runtime, there is no active_instructions_ field
|
||||||
// and thus no active_instructions_ field. Thus, the entry point caches are
|
// and the entry point caches should contain entry points for instructions_.
|
||||||
// only set once during deserialization. If not using bare instructions,
|
|
||||||
// the caches should match the entry points for instructions_.
|
|
||||||
//
|
|
||||||
// Otherwise, they should contain entry points for active_instructions_.
|
// Otherwise, they should contain entry points for active_instructions_.
|
||||||
|
|
||||||
uword entry_point_; // Accessed from generated code.
|
uword entry_point_; // Accessed from generated code.
|
||||||
|
@ -1500,14 +1497,12 @@ class RawCode : public RawObject {
|
||||||
// Caches the unchecked entry point offset for instructions_, in case we need
|
// Caches the unchecked entry point offset for instructions_, in case we need
|
||||||
// to reset the active_instructions_ to instructions_.
|
// to reset the active_instructions_ to instructions_.
|
||||||
NOT_IN_PRECOMPILED(uint32_t unchecked_offset_);
|
NOT_IN_PRECOMPILED(uint32_t unchecked_offset_);
|
||||||
// Stores the instructions length when not using RawInstructions objects.
|
|
||||||
ONLY_IN_PRECOMPILED(uint32_t instructions_length_);
|
|
||||||
|
|
||||||
// Variable length data follows here.
|
// Variable length data follows here.
|
||||||
int32_t* data() { OPEN_ARRAY_START(int32_t, int32_t); }
|
int32_t* data() { OPEN_ARRAY_START(int32_t, int32_t); }
|
||||||
const int32_t* data() const { OPEN_ARRAY_START(int32_t, int32_t); }
|
const int32_t* data() const { OPEN_ARRAY_START(int32_t, int32_t); }
|
||||||
|
|
||||||
static bool ContainsPC(const RawObject* raw_obj, uword pc);
|
static bool ContainsPC(RawObject* raw_obj, uword pc);
|
||||||
|
|
||||||
friend class Function;
|
friend class Function;
|
||||||
template <bool>
|
template <bool>
|
||||||
|
@ -1589,7 +1584,7 @@ class RawInstructions : public RawObject {
|
||||||
// Private helper function used while visiting stack frames. The
|
// Private helper function used while visiting stack frames. The
|
||||||
// code which iterates over dart frames is also called during GC and
|
// code which iterates over dart frames is also called during GC and
|
||||||
// is not allowed to create handles.
|
// is not allowed to create handles.
|
||||||
static bool ContainsPC(const RawInstructions* raw_instr, uword pc);
|
static bool ContainsPC(RawInstructions* raw_instr, uword pc);
|
||||||
|
|
||||||
friend class RawCode;
|
friend class RawCode;
|
||||||
friend class RawFunction;
|
friend class RawFunction;
|
||||||
|
@ -1604,19 +1599,6 @@ class RawInstructions : public RawObject {
|
||||||
friend class BlobImageWriter;
|
friend class BlobImageWriter;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Used only to provide memory accounting for the bare instruction payloads
|
|
||||||
// we serialize, since they are no longer part of RawInstructions objects.
|
|
||||||
class RawInstructionsSection : public RawObject {
|
|
||||||
RAW_HEAP_OBJECT_IMPLEMENTATION(InstructionsSection);
|
|
||||||
VISIT_NOTHING();
|
|
||||||
|
|
||||||
// Instructions section payload length in bytes.
|
|
||||||
uint32_t payload_length_;
|
|
||||||
|
|
||||||
// Variable length data follows here.
|
|
||||||
uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class RawPcDescriptors : public RawObject {
|
class RawPcDescriptors : public RawObject {
|
||||||
public:
|
public:
|
||||||
// The macro argument V is passed two arguments, the raw name of the enum value
|
// The macro argument V is passed two arguments, the raw name of the enum value
|
||||||
|
@ -2993,9 +2975,8 @@ inline bool RawObject::IsVariableSizeClassId(intptr_t index) {
|
||||||
RawObject::IsTwoByteStringClassId(index) ||
|
RawObject::IsTwoByteStringClassId(index) ||
|
||||||
RawObject::IsTypedDataClassId(index) || (index == kContextCid) ||
|
RawObject::IsTypedDataClassId(index) || (index == kContextCid) ||
|
||||||
(index == kTypeArgumentsCid) || (index == kInstructionsCid) ||
|
(index == kTypeArgumentsCid) || (index == kInstructionsCid) ||
|
||||||
(index == kInstructionsSectionCid) || (index == kObjectPoolCid) ||
|
(index == kObjectPoolCid) || (index == kPcDescriptorsCid) ||
|
||||||
(index == kPcDescriptorsCid) || (index == kCodeSourceMapCid) ||
|
(index == kCodeSourceMapCid) || (index == kCompressedStackMapsCid) ||
|
||||||
(index == kCompressedStackMapsCid) ||
|
|
||||||
(index == kLocalVarDescriptorsCid) ||
|
(index == kLocalVarDescriptorsCid) ||
|
||||||
(index == kExceptionHandlersCid) || (index == kCodeCid) ||
|
(index == kExceptionHandlersCid) || (index == kCodeCid) ||
|
||||||
(index == kContextScopeCid) || (index == kInstanceCid) ||
|
(index == kContextScopeCid) || (index == kInstanceCid) ||
|
||||||
|
|
|
@ -541,7 +541,6 @@ MESSAGE_SNAPSHOT_UNREACHABLE(Field);
|
||||||
MESSAGE_SNAPSHOT_UNREACHABLE(Function);
|
MESSAGE_SNAPSHOT_UNREACHABLE(Function);
|
||||||
MESSAGE_SNAPSHOT_UNREACHABLE(ICData);
|
MESSAGE_SNAPSHOT_UNREACHABLE(ICData);
|
||||||
MESSAGE_SNAPSHOT_UNREACHABLE(Instructions);
|
MESSAGE_SNAPSHOT_UNREACHABLE(Instructions);
|
||||||
MESSAGE_SNAPSHOT_UNREACHABLE(InstructionsSection);
|
|
||||||
MESSAGE_SNAPSHOT_UNREACHABLE(KernelProgramInfo);
|
MESSAGE_SNAPSHOT_UNREACHABLE(KernelProgramInfo);
|
||||||
MESSAGE_SNAPSHOT_UNREACHABLE(Library);
|
MESSAGE_SNAPSHOT_UNREACHABLE(Library);
|
||||||
MESSAGE_SNAPSHOT_UNREACHABLE(LibraryPrefix);
|
MESSAGE_SNAPSHOT_UNREACHABLE(LibraryPrefix);
|
||||||
|
|
|
@ -11,11 +11,13 @@ namespace dart {
|
||||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||||
|
|
||||||
static uword BeginPcFromCode(const RawCode* code) {
|
static uword BeginPcFromCode(const RawCode* code) {
|
||||||
return Code::PayloadStartOf(code);
|
auto instr = Code::InstructionsOf(code);
|
||||||
|
return Instructions::PayloadStart(instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uword EndPcFromCode(const RawCode* code) {
|
static uword EndPcFromCode(const RawCode* code) {
|
||||||
return Code::PayloadStartOf(code) + Code::PayloadSizeOf(code);
|
auto instr = Code::InstructionsOf(code);
|
||||||
|
return Instructions::PayloadStart(instr) + Instructions::Size(instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReversePcLookupCache::BuildAndAttachToIsolate(Isolate* isolate) {
|
void ReversePcLookupCache::BuildAndAttachToIsolate(Isolate* isolate) {
|
||||||
|
|
|
@ -66,11 +66,7 @@ class ReversePcLookupCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Looks up the [Code] object from a given [pc].
|
// Looks up the [Code] object from a given [pc].
|
||||||
//
|
inline RawCode* Lookup(uword pc) {
|
||||||
// If [is_return_address] is true, then the PC may be immediately after the
|
|
||||||
// payload, if the last instruction is a call that is guaranteed not to
|
|
||||||
// return. Otherwise, the PC must be within the payload.
|
|
||||||
inline RawCode* Lookup(uword pc, bool is_return_address = false) {
|
|
||||||
NoSafepointScope no_safepoint_scope;
|
NoSafepointScope no_safepoint_scope;
|
||||||
|
|
||||||
intptr_t left = 0;
|
intptr_t left = 0;
|
||||||
|
@ -85,14 +81,6 @@ class ReversePcLookupCache {
|
||||||
uword middle_pc = pc_array_[middle];
|
uword middle_pc = pc_array_[middle];
|
||||||
if (middle_pc < pc_offset) {
|
if (middle_pc < pc_offset) {
|
||||||
left = middle + 1;
|
left = middle + 1;
|
||||||
} else if (!is_return_address && middle_pc == pc_offset) {
|
|
||||||
// This case should only happen if we have bare instruction payloads.
|
|
||||||
// Otherwise, the instruction payloads of two RawInstructions objects
|
|
||||||
// will never be immediately adjacent in memory due to the header of
|
|
||||||
// the second object.
|
|
||||||
ASSERT(FLAG_use_bare_instructions);
|
|
||||||
left = middle + 1;
|
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
right = middle;
|
right = middle;
|
||||||
}
|
}
|
||||||
|
@ -128,9 +116,7 @@ class ReversePcLookupCache {
|
||||||
|
|
||||||
inline bool Contains(uword pc) { return false; }
|
inline bool Contains(uword pc) { return false; }
|
||||||
|
|
||||||
inline RawCode* Lookup(uword pc, bool is_return_address = false) {
|
inline RawCode* Lookup(uword pc) { UNREACHABLE(); }
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // defined(DART_PRECOMPILED_RUNTIME
|
#endif // defined(DART_PRECOMPILED_RUNTIME
|
||||||
|
|
|
@ -126,7 +126,7 @@ bool StackFrame::IsBareInstructionsDartFrame() const {
|
||||||
if (auto isolate = IsolateOfBareInstructionsFrame()) {
|
if (auto isolate = IsolateOfBareInstructionsFrame()) {
|
||||||
Code code;
|
Code code;
|
||||||
auto rct = isolate->reverse_pc_lookup_cache();
|
auto rct = isolate->reverse_pc_lookup_cache();
|
||||||
code = rct->Lookup(pc(), /*is_return_address=*/true);
|
code = rct->Lookup(pc());
|
||||||
|
|
||||||
const intptr_t cid = code.owner()->GetClassId();
|
const intptr_t cid = code.owner()->GetClassId();
|
||||||
ASSERT(cid == kNullCid || cid == kClassCid || cid == kFunctionCid);
|
ASSERT(cid == kNullCid || cid == kClassCid || cid == kFunctionCid);
|
||||||
|
@ -141,7 +141,7 @@ bool StackFrame::IsBareInstructionsStubFrame() const {
|
||||||
if (auto isolate = IsolateOfBareInstructionsFrame()) {
|
if (auto isolate = IsolateOfBareInstructionsFrame()) {
|
||||||
Code code;
|
Code code;
|
||||||
auto rct = isolate->reverse_pc_lookup_cache();
|
auto rct = isolate->reverse_pc_lookup_cache();
|
||||||
code = rct->Lookup(pc(), /*is_return_address=*/true);
|
code = rct->Lookup(pc());
|
||||||
|
|
||||||
const intptr_t cid = code.owner()->GetClassId();
|
const intptr_t cid = code.owner()->GetClassId();
|
||||||
ASSERT(cid == kNullCid || cid == kClassCid || cid == kFunctionCid);
|
ASSERT(cid == kNullCid || cid == kClassCid || cid == kFunctionCid);
|
||||||
|
@ -253,8 +253,7 @@ void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
|
||||||
Code code;
|
Code code;
|
||||||
|
|
||||||
if (auto isolate = IsolateOfBareInstructionsFrame()) {
|
if (auto isolate = IsolateOfBareInstructionsFrame()) {
|
||||||
auto const rct = isolate->reverse_pc_lookup_cache();
|
code = isolate->reverse_pc_lookup_cache()->Lookup(pc());
|
||||||
code = rct->Lookup(pc(), /*is_return_address=*/true);
|
|
||||||
} else {
|
} else {
|
||||||
RawObject* pc_marker = *(reinterpret_cast<RawObject**>(
|
RawObject* pc_marker = *(reinterpret_cast<RawObject**>(
|
||||||
fp() + ((is_interpreted() ? kKBCPcMarkerSlotFromFp
|
fp() + ((is_interpreted() ? kKBCPcMarkerSlotFromFp
|
||||||
|
@ -388,8 +387,7 @@ RawCode* StackFrame::LookupDartCode() const {
|
||||||
NoSafepointScope no_safepoint;
|
NoSafepointScope no_safepoint;
|
||||||
#endif
|
#endif
|
||||||
if (auto isolate = IsolateOfBareInstructionsFrame()) {
|
if (auto isolate = IsolateOfBareInstructionsFrame()) {
|
||||||
auto const rct = isolate->reverse_pc_lookup_cache();
|
return isolate->reverse_pc_lookup_cache()->Lookup(pc());
|
||||||
return rct->Lookup(pc(), /*is_return_address=*/true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RawCode* code = GetCodeObject();
|
RawCode* code = GetCodeObject();
|
||||||
|
@ -403,8 +401,7 @@ RawCode* StackFrame::LookupDartCode() const {
|
||||||
RawCode* StackFrame::GetCodeObject() const {
|
RawCode* StackFrame::GetCodeObject() const {
|
||||||
ASSERT(!is_interpreted());
|
ASSERT(!is_interpreted());
|
||||||
if (auto isolate = IsolateOfBareInstructionsFrame()) {
|
if (auto isolate = IsolateOfBareInstructionsFrame()) {
|
||||||
auto const rct = isolate->reverse_pc_lookup_cache();
|
return isolate->reverse_pc_lookup_cache()->Lookup(pc());
|
||||||
return rct->Lookup(pc(), /*is_return_address=*/true);
|
|
||||||
} else {
|
} else {
|
||||||
RawObject* pc_marker = *(reinterpret_cast<RawObject**>(
|
RawObject* pc_marker = *(reinterpret_cast<RawObject**>(
|
||||||
fp() + runtime_frame_layout.code_from_fp * kWordSize));
|
fp() + runtime_frame_layout.code_from_fp * kWordSize));
|
||||||
|
|
|
@ -178,7 +178,6 @@ class ObjectPointerVisitor;
|
||||||
V(IndexToken, "[]") \
|
V(IndexToken, "[]") \
|
||||||
V(InitPrefix, "init:") \
|
V(InitPrefix, "init:") \
|
||||||
V(Instructions, "Instructions") \
|
V(Instructions, "Instructions") \
|
||||||
V(InstructionsSection, "InstructionsSection") \
|
|
||||||
V(Int, "int") \
|
V(Int, "int") \
|
||||||
V(Int16List, "Int16List") \
|
V(Int16List, "Int16List") \
|
||||||
V(Int32List, "Int32List") \
|
V(Int32List, "Int32List") \
|
||||||
|
|
Loading…
Reference in a new issue