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:
Teagan Strickland 2020-02-04 17:32:28 +00:00 committed by commit-bot@chromium.org
parent 592e59691b
commit bb24f98616
29 changed files with 203 additions and 747 deletions

View file

@ -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);
}); });
} }

View file

@ -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) \

View file

@ -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);
} }

View file

@ -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); }

View file

@ -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;

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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();
} }

View file

@ -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();
} }

View file

@ -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)

View file

@ -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)

View file

@ -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);

View file

@ -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;
} }

View file

@ -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;

View file

@ -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

View file

@ -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) \

View file

@ -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

View file

@ -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));

View file

@ -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";

View file

@ -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.

View file

@ -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

View file

@ -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);

View file

@ -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,

View file

@ -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) ||

View file

@ -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);

View file

@ -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) {

View file

@ -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

View file

@ -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));

View file

@ -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") \