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';
test(
{String dillPath,
bool useAsm,
bool useBare,
bool stripFlag,
bool stripUtil}) async {
test({String dillPath, bool useAsm, bool stripFlag, bool stripUtil}) async {
// The assembler may add extra unnecessary information to the compiled
// snapshot whether or not we generate DWARF information in the assembly, so
// we force the use of a utility when generating assembly.
@ -28,7 +23,6 @@ test(
final tempDirPrefix = 'v8-snapshot-profile' +
(useAsm ? '-assembly' : '-elf') +
(useBare ? '-bare' : '-nonbare') +
(stripFlag ? '-intstrip' : '') +
(stripUtil ? '-extstrip' : '');
@ -38,7 +32,6 @@ test(
final snapshotPath = path.join(tempDir, 'test.snap');
final commonSnapshotArgs = [
if (stripFlag) '--strip',
useBare ? '--use-bare-instructions' : '--no-use-bare-instructions',
"--write-v8-snapshot-profile-to=$profilePath",
dillPath,
];
@ -78,7 +71,7 @@ test(
// graph (in some cases the shallow size can legitimately be 0, e.g. for
// "base objects").
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}");
}
@ -96,7 +89,6 @@ test(
final actual = await File(strippedPath).length();
final expected = profile.accountedBytes;
final bareUsed = useBare ? "bare" : "non-bare";
final fileType = useAsm ? "assembly" : "ELF";
String stripPrefix = "";
if (stripFlag && stripUtil) {
@ -108,7 +100,7 @@ test(
}
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.
await test(
dillPath: dillPath,
stripFlag: true,
stripUtil: false,
useAsm: false,
useBare: false);
await test(
dillPath: dillPath,
stripFlag: true,
stripUtil: false,
useAsm: false,
useBare: true);
dillPath: dillPath, stripFlag: true, stripUtil: false, useAsm: false);
// We neither generate assembly nor have a stripping utility on Windows.
if (Platform.isWindows) {
@ -246,17 +228,7 @@ main() async {
} else {
// Test unstripped ELF generation that is then stripped externally.
await test(
dillPath: dillPath,
stripFlag: false,
stripUtil: true,
useAsm: false,
useBare: false);
await test(
dillPath: dillPath,
stripFlag: false,
stripUtil: true,
useAsm: false,
useBare: true);
dillPath: dillPath, stripFlag: false, stripUtil: true, useAsm: false);
}
// 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.
await test(
dillPath: dillPath,
stripFlag: true,
stripUtil: true,
useAsm: true,
useBare: false);
await test(
dillPath: dillPath,
stripFlag: true,
stripUtil: true,
useAsm: true,
useBare: true);
dillPath: dillPath, stripFlag: true, stripUtil: true, useAsm: true);
// Test unstripped assembly generation that is then compiled and stripped.
await test(
dillPath: dillPath,
stripFlag: false,
stripUtil: true,
useAsm: true,
useBare: false);
await test(
dillPath: dillPath,
stripFlag: false,
stripUtil: true,
useAsm: true,
useBare: true);
dillPath: dillPath, stripFlag: false, stripUtil: true, useAsm: true);
});
}

View file

@ -28,7 +28,6 @@ namespace dart {
V(Code) \
V(Bytecode) \
V(Instructions) \
V(InstructionsSection) \
V(ObjectPool) \
V(PcDescriptors) \
V(CodeSourceMap) \

View file

@ -1509,16 +1509,15 @@ class CodeSerializationCluster : public SerializationCluster {
s->UnexpectedObject(code, "Disabled code");
}
s->WriteInstructions(code->ptr()->instructions_,
code->ptr()->unchecked_offset_, code);
s->WriteInstructions(code->ptr()->instructions_, code);
s->WriteUnsigned(code->ptr()->unchecked_offset_);
if (kind == Snapshot::kFullJIT) {
// TODO(rmacnak): Fix references to disabled code before serializing.
// For now, we may write the FixCallersTarget or equivalent stub. This
// will cause a fixup if this code is called.
const uint32_t active_unchecked_offset =
code->ptr()->unchecked_entry_point_ - code->ptr()->entry_point_;
s->WriteInstructions(code->ptr()->active_instructions_,
active_unchecked_offset, code);
s->WriteInstructions(code->ptr()->active_instructions_, code);
s->WriteUnsigned(code->ptr()->unchecked_entry_point_ -
code->ptr()->entry_point_);
}
WriteField(code, object_pool_);
@ -1599,10 +1598,24 @@ class CodeDeserializationCluster : public DeserializationCluster {
void ReadFill(Deserializer* d) {
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));
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_ =
reinterpret_cast<RawObjectPool*>(d->ReadRef());
@ -1638,32 +1651,7 @@ class CodeDeserializationCluster : public DeserializationCluster {
#endif
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)
@ -4687,9 +4675,7 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) {
}
#if !defined(DART_PRECOMPILED_RUNTIME)
void Serializer::WriteInstructions(RawInstructions* instr,
uint32_t unchecked_offset,
RawCode* code) {
void Serializer::WriteInstructions(RawInstructions* instr, RawCode* code) {
ASSERT(code != Code::null());
const intptr_t offset = image_writer_->GetTextOffsetFor(instr, code);
@ -4698,17 +4684,6 @@ void Serializer::WriteInstructions(RawInstructions* instr,
UnexpectedObject(code, "Expected instructions to reuse");
}
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
// 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);
}
void Deserializer::ReadInstructions(RawCode* code) {
#if defined(DART_PRECOMPILED_RUNTIME)
if (FLAG_use_bare_instructions) {
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);
RawInstructions* Deserializer::ReadInstructions() {
uint32_t offset = Read<uint32_t>();
return image_reader_->GetInstructionsAt(offset);
}
#if defined(DART_PRECOMPILED_RUNTIME)
uword Deserializer::GetBareInstructionsEnd() {
return image_reader_->GetBareInstructionsEnd();
}
#endif
RawObject* Deserializer::GetObjectAt(uint32_t offset) const {
return image_reader_->GetObjectAt(offset);
}

View file

@ -358,9 +358,7 @@ class Serializer : public ThreadStackResource {
Write<int32_t>(cid);
}
void WriteInstructions(RawInstructions* instr,
uint32_t unchecked_offset,
RawCode* code);
void WriteInstructions(RawInstructions* instr, RawCode* code);
uint32_t GetDataOffset(RawObject* object) const;
void TraceDataOffset(uint32_t offset);
intptr_t GetDataSize() const;
@ -561,8 +559,7 @@ class Deserializer : public ThreadStackResource {
return Read<int32_t>();
}
ONLY_IN_PRECOMPILED(uword GetBareInstructionsEnd());
void ReadInstructions(RawCode* code);
RawInstructions* ReadInstructions();
RawObject* GetObjectAt(uint32_t offset) const;
void SkipHeader() { stream_.SetPosition(Snapshot::kHeaderSize); }

View file

@ -303,7 +303,7 @@ class AssemblerBase : public StackResource {
explicit AssemblerBase(ObjectPoolBuilder* object_pool_builder)
: StackResource(ThreadState::Current()),
prologue_offset_(-1),
has_monomorphic_entry_(false),
has_single_entry_point_(true),
object_pool_builder_(object_pool_builder) {}
virtual ~AssemblerBase();
@ -315,7 +315,7 @@ class AssemblerBase : public StackResource {
ObjectPoolBuilder& object_pool_builder() { return *object_pool_builder_; }
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);
static bool EmittingComments();
@ -370,7 +370,7 @@ class AssemblerBase : public StackResource {
protected:
AssemblerBuffer buffer_; // Contains position independent code.
int32_t prologue_offset_;
bool has_monomorphic_entry_;
bool has_single_entry_point_;
intptr_t unchecked_entry_offset_ = 0;

View file

@ -3437,7 +3437,7 @@ void Assembler::LeaveStubFrame() {
// R0 receiver, R9 ICData entries array
// Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
void Assembler::MonomorphicCheckedEntryJIT() {
has_monomorphic_entry_ = true;
has_single_entry_point_ = false;
#if defined(TESTING) || defined(DEBUG)
bool saved_use_far_branches = use_far_branches();
set_use_far_branches(false);
@ -3473,7 +3473,7 @@ void Assembler::MonomorphicCheckedEntryJIT() {
// R0 receiver, R9 guarded cid as Smi.
// Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
void Assembler::MonomorphicCheckedEntryAOT() {
has_monomorphic_entry_ = true;
has_single_entry_point_ = false;
#if defined(TESTING) || defined(DEBUG)
bool saved_use_far_branches = use_far_branches();
set_use_far_branches(false);
@ -3498,7 +3498,7 @@ void Assembler::MonomorphicCheckedEntryAOT() {
}
void Assembler::BranchOnMonomorphicCheckedEntryJIT(Label* label) {
has_monomorphic_entry_ = true;
has_single_entry_point_ = false;
while (CodeSize() < target::Instructions::kMonomorphicEntryOffsetJIT) {
bkpt(0);
}

View file

@ -1532,7 +1532,7 @@ void Assembler::LeaveStubFrame() {
// R0 receiver, R5 ICData entries array
// Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
void Assembler::MonomorphicCheckedEntryJIT() {
has_monomorphic_entry_ = true;
has_single_entry_point_ = false;
const bool saved_use_far_branches = use_far_branches();
set_use_far_branches(false);
const intptr_t start = CodeSize();
@ -1569,7 +1569,7 @@ void Assembler::MonomorphicCheckedEntryJIT() {
// R0 receiver, R5 guarded cid as Smi.
// Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
void Assembler::MonomorphicCheckedEntryAOT() {
has_monomorphic_entry_ = true;
has_single_entry_point_ = false;
bool saved_use_far_branches = use_far_branches();
set_use_far_branches(false);
@ -1595,7 +1595,7 @@ void Assembler::MonomorphicCheckedEntryAOT() {
}
void Assembler::BranchOnMonomorphicCheckedEntryJIT(Label* label) {
has_monomorphic_entry_ = true;
has_single_entry_point_ = false;
while (CodeSize() < target::Instructions::kMonomorphicEntryOffsetJIT) {
brk(0);
}

View file

@ -2117,7 +2117,7 @@ void Assembler::EmitEntryFrameVerification() {
// EBX receiver, ECX ICData entries array
// Preserve EDX (ARGS_DESC_REG), not required today, but maybe later.
void Assembler::MonomorphicCheckedEntryJIT() {
has_monomorphic_entry_ = true;
has_single_entry_point_ = false;
intptr_t start = CodeSize();
Label have_cid, miss;
Bind(&miss);
@ -2156,7 +2156,7 @@ void Assembler::MonomorphicCheckedEntryAOT() {
}
void Assembler::BranchOnMonomorphicCheckedEntryJIT(Label* label) {
has_monomorphic_entry_ = true;
has_single_entry_point_ = false;
while (CodeSize() < target::Instructions::kMonomorphicEntryOffsetJIT) {
int3();
}

View file

@ -1798,7 +1798,7 @@ void Assembler::LeaveStubFrame() {
// RDX receiver, RBX ICData entries array
// Preserve R10 (ARGS_DESC_REG), not required today, but maybe later.
void Assembler::MonomorphicCheckedEntryJIT() {
has_monomorphic_entry_ = true;
has_single_entry_point_ = false;
intptr_t start = CodeSize();
Label have_cid, miss;
Bind(&miss);
@ -1831,7 +1831,7 @@ void Assembler::MonomorphicCheckedEntryJIT() {
}
void Assembler::MonomorphicCheckedEntryAOT() {
has_monomorphic_entry_ = true;
has_single_entry_point_ = false;
intptr_t start = CodeSize();
Label have_cid, miss;
Bind(&miss);
@ -1862,7 +1862,7 @@ void Assembler::MonomorphicCheckedEntryAOT() {
}
void Assembler::BranchOnMonomorphicCheckedEntryJIT(Label* label) {
has_monomorphic_entry_ = true;
has_single_entry_point_ = false;
while (CodeSize() < target::Instructions::kMonomorphicEntryOffsetJIT) {
int3();
}

View file

@ -258,7 +258,8 @@ void Disassembler::DisassembleCodeHelper(const char* function_fullname,
PcDescriptors::Handle(zone, code.pc_descriptors());
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;
#if !defined(DART_PRECOMPILED_RUNTIME)

View file

@ -157,7 +157,8 @@ void CodeRelocator::FindInstructionAndCallLimits() {
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
? destination_.UncheckedEntryPoint()
: destination_.EntryPoint();
@ -271,16 +272,17 @@ void CodeRelocator::ScanCallTargets(const Code& code,
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
? destination_.UncheckedEntryPoint()
: destination_.EntryPoint();
offset_into_target += (entry_point - destination_payload);
const intptr_t text_offset =
code_text_offset + AdjustPayloadOffset(call_instruction_offset);
const intptr_t text_offset = code_text_offset +
compiler::target::Instructions::HeaderSize() +
call_instruction_offset;
UnresolvedCall unresolved_call(code.raw(), call_instruction_offset,
text_offset, destination_.raw(),
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_offset = unresolved_call->call_offset;
auto caller = Code::InstructionsOf(unresolved_call->caller);
const int32_t distance = destination_text - call_text_offset;
{
auto const caller = unresolved_call->caller;
uword addr = Code::PayloadStartOf(caller) + call_offset;
uword addr = Instructions::PayloadStart(caller) + call_offset;
if (FLAG_write_protect_code) {
addr -= HeapPage::Of(Code::InstructionsOf(caller))->AliasOffset();
addr -= HeapPage::Of(caller)->AliasOffset();
}
PcRelativeCallPattern call(addr);
ASSERT(call.IsValid());
@ -508,15 +510,9 @@ void CodeRelocator::BuildTrampolinesForAlmostOutOfRangeCalls() {
intptr_t CodeRelocator::FindDestinationInText(
const RawInstructions* destination,
intptr_t offset_into_target) {
auto const destination_offset = text_offsets_.LookupValue(destination);
return destination_offset + AdjustPayloadOffset(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;
auto destination_offset = text_offsets_.LookupValue(destination);
return destination_offset + compiler::target::Instructions::HeaderSize() +
offset_into_target;
}
#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 offset_into_target);
static intptr_t AdjustPayloadOffset(intptr_t payload_offset);
bool IsTargetInRangeFor(UnresolvedCall* unresolved_call,
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;
word InstructionsSection::HeaderSize() {
return Utils::RoundUp(InstructionsSection::UnalignedHeaderSize(),
target::kWordSize);
}
word Instructions::HeaderSize() {
return Utils::RoundUp(Instructions::UnalignedHeaderSize(), target::kWordSize);
}
@ -916,10 +911,6 @@ word MonomorphicSmiableCall::NextFieldOffset() {
return -kWordSize;
}
word InstructionsSection::NextFieldOffset() {
return -kWordSize;
}
word Instructions::NextFieldOffset() {
return -kWordSize;
}

View file

@ -1063,14 +1063,6 @@ class ClassTable : public AllStatic {
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 {
public:
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_UnalignedHeaderSize =
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 Integer_InstanceSize = 4;
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_UnalignedHeaderSize =
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 Integer_InstanceSize = 8;
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_UnalignedHeaderSize =
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 Integer_InstanceSize = 4;
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_UnalignedHeaderSize =
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 Integer_InstanceSize = 8;
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_UnalignedHeaderSize =
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 Integer_InstanceSize = 4;
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_UnalignedHeaderSize =
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 Integer_InstanceSize = 8;
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_UnalignedHeaderSize =
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 Integer_InstanceSize = 4;
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_UnalignedHeaderSize =
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 Integer_InstanceSize = 8;
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_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_Integer_InstanceSize = 4;
static constexpr dart::compiler::target::word
@ -4617,10 +4581,6 @@ static constexpr dart::compiler::target::word AOT_Instructions_InstanceSize =
12;
static constexpr dart::compiler::target::word
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_Integer_InstanceSize = 8;
static constexpr dart::compiler::target::word
@ -5127,10 +5087,6 @@ static constexpr dart::compiler::target::word AOT_Instructions_InstanceSize =
12;
static constexpr dart::compiler::target::word
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_Integer_InstanceSize = 8;
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_Closure_InstanceSize = 28;
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 =
8;
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_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_Integer_InstanceSize = 4;
static constexpr dart::compiler::target::word
@ -6125,10 +6077,6 @@ static constexpr dart::compiler::target::word AOT_Instructions_InstanceSize =
12;
static constexpr dart::compiler::target::word
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_Integer_InstanceSize = 8;
static constexpr dart::compiler::target::word
@ -6628,10 +6576,6 @@ static constexpr dart::compiler::target::word AOT_Instructions_InstanceSize =
12;
static constexpr dart::compiler::target::word
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_Integer_InstanceSize = 8;
static constexpr dart::compiler::target::word

View file

@ -286,8 +286,6 @@
SIZEOF(Instance, InstanceSize, RawInstance) \
SIZEOF(Instructions, InstanceSize, RawInstructions) \
SIZEOF(Instructions, UnalignedHeaderSize, RawInstructions) \
SIZEOF(InstructionsSection, InstanceSize, RawInstructionsSection) \
SIZEOF(InstructionsSection, UnalignedHeaderSize, RawInstructionsSection) \
SIZEOF(Int32x4, InstanceSize, RawInt32x4) \
SIZEOF(Integer, InstanceSize, RawInteger) \
SIZEOF(KernelProgramInfo, InstanceSize, RawKernelProgramInfo) \

View file

@ -78,12 +78,6 @@ const intptr_t kDefaultMaxOldGenHeapSize = (kWordSize <= 4) ? 1536 : 30720;
#define NOT_IN_PRECOMPILED(code) code
#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) || \
defined(TARGET_ARCH_X64)
#define ONLY_IN_ARM_ARM64_X64(code) code

View file

@ -5,7 +5,6 @@
#include "vm/image_snapshot.h"
#include "platform/assert.h"
#include "vm/class_id.h"
#include "vm/compiler/backend/code_statistics.h"
#include "vm/compiler/runtime_api.h"
#include "vm/dwarf.h"
@ -136,25 +135,6 @@ int32_t ImageWriter::GetTextOffsetFor(RawInstructions* instructions,
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)
static intptr_t CompressedStackMapsSizeInSnapshot(intptr_t payload_size) {
// 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);
}
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) {
const classid_t cid = raw_object->GetClassId();
@ -216,7 +201,7 @@ intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
}
case kInstructionsCid: {
RawInstructions* raw_insns = static_cast<RawInstructions*>(raw_object);
return InstructionsSizeInSnapshot(raw_insns);
return InstructionsSizeInSnapshot(Instructions::Size(raw_insns));
}
default: {
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)
intptr_t ImageWriter::SizeInSnapshot(RawObject* raw) {
switch (raw->GetClassId()) {
case kInstructionsCid:
return InstructionsSizeInSnapshot(static_cast<RawInstructions*>(raw));
default:
return raw->HeapSize();
}
intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
return raw_object->HeapSize();
}
#endif // defined(IS_SIMARM_X64)
@ -576,9 +556,6 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
#else
Zone* zone = Thread::Current()->zone();
const bool bare_instruction_payloads =
FLAG_precompiled_mode && FLAG_use_bare_instructions;
#if defined(DART_PRECOMPILER)
const char* bss_symbol =
vm ? "_kDartVmSnapshotBss" : "_kDartIsolateSnapshotBss";
@ -595,14 +572,13 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
// Start snapshot at page boundary.
ASSERT(VirtualMemory::PageSize() >= kMaxObjectAlignment);
Align(VirtualMemory::PageSize());
assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize());
assembly_stream_.Print("%s:\n", instructions_symbol);
// This head also provides the gap to make the instructions snapshot
// look like a HeapPage.
const intptr_t image_size = Utils::RoundUp(
next_text_offset_, compiler::target::ObjectAlignment::kObjectAlignment);
WriteWordLiteralText(image_size);
intptr_t instructions_length = next_text_offset_;
WriteWordLiteralText(instructions_length);
#if defined(DART_PRECOMPILER)
assembly_stream_.Print("%s %s - %s\n", kLiteralPrefix, bss_symbol,
@ -616,43 +592,6 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
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();
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;
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 (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},
"Trampolines",
/*name=*/nullptr);
@ -700,7 +629,7 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
descriptors = data.code_->pc_descriptors();
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},
"Instructions",
/*name=*/nullptr);
@ -708,12 +637,9 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
SizeInSnapshot(insns.raw()));
}
const uword payload_start = insns.PayloadStart();
// 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
// bare instructions.
if (!bare_instruction_payloads) {
// object header and the fixed fields.
{
NoSafepointScope no_safepoint;
// Write Instructions with the mark and read-only bits set.
@ -730,7 +656,7 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
#endif
#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);
WriteWordLiteralText(marked_tags);
text_offset += sizeof(compiler::target::uword);
@ -738,6 +664,7 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
text_offset += sizeof(compiler::target::uword);
#else // defined(IS_SIMARM_X64)
uword object_start = reinterpret_cast<uword>(insns.raw_ptr());
uword payload_start = insns.PayloadStart();
WriteWordLiteralText(marked_tags);
object_start += sizeof(uword);
text_offset += sizeof(uword);
@ -756,7 +683,7 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
}
if (debug_dwarf_ != nullptr) {
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);
}
#endif
@ -765,29 +692,19 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
assembly_stream_.Print("%s:\n", namer.AssemblyNameFor(dwarf_index, code));
{
// 3. Write from the payload start to payload end. For AOT snapshots
// with bare instructions, this is the only part serialized.
// 3. Write from the payload start to payload end.
NoSafepointScope no_safepoint;
assert(kBareInstructionsAlignment <=
compiler::target::ObjectAlignment::kObjectAlignment);
const auto payload_align = bare_instruction_payloads
? kBareInstructionsAlignment
: sizeof(compiler::target::uword);
const uword payload_size = Utils::RoundUp(insns.Size(), payload_align);
const uword payload_start = insns.PayloadStart();
const uword payload_size =
Utils::RoundUp(insns.Size(), sizeof(compiler::target::uword));
const uword payload_end = payload_start + payload_size;
ASSERT(Utils::IsAligned(text_offset, payload_align));
#if defined(DART_PRECOMPILER)
PcDescriptors::Iterator iterator(descriptors,
RawPcDescriptors::kBSSRelocation);
uword next_reloc_offset = iterator.MoveNext() ? iterator.PcOffset() : -1;
// We only generate BSS relocations that are word-sized and at
// 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;
for (uword cursor = payload_start; cursor < payload_end;
cursor += sizeof(compiler::target::uword)) {
compiler::target::uword data =
*reinterpret_cast<compiler::target::uword*>(cursor);
@ -799,8 +716,6 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
WriteWordLiteralText(data);
}
}
assert(next_reloc_offset != (possible_relocations_end - payload_start));
WriteByteSequence(possible_relocations_end, payload_end);
text_offset += payload_size;
#else
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
// 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
// snapshots using bare instructions.
if (!bare_instruction_payloads) {
uword unaligned_size =
compiler::target::Instructions::HeaderSize() + payload_size;
uword alignment_size =
Utils::RoundUp(
unaligned_size,
compiler::target::ObjectAlignment::kObjectAlignment) -
unaligned_size;
while (alignment_size > 0) {
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());
// than the target object in the cross-word case.
uword unaligned_size =
compiler::target::Instructions::HeaderSize() + payload_size;
uword alignment_size =
Utils::RoundUp(unaligned_size,
compiler::target::ObjectAlignment::kObjectAlignment) -
unaligned_size;
while (alignment_size > 0) {
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((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();
#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.
auto const debug_segment_base2 =
debug_dwarf_->elf()->AddText(instructions_symbol, /*bytes=*/nullptr,
section_headers_size + text_offset);
Image::kHeaderSize + text_offset);
ASSERT(debug_segment_base2 == debug_segment_base);
}
@ -890,7 +788,7 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
const char* data_symbol =
vm ? "_kDartVmSnapshotData" : "_kDartIsolateSnapshotData";
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);
uword buffer = reinterpret_cast<uword>(clustered_stream->buffer());
intptr_t length = clustered_stream->bytes_written();
@ -976,33 +874,13 @@ void AssemblyImageWriter::FrameUnwindEpilogue() {
}
intptr_t AssemblyImageWriter::WriteByteSequence(uword start, uword end) {
assert(end >= start);
auto const end_of_words =
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++) {
for (auto* cursor = reinterpret_cast<compiler::target::uword*>(start);
cursor < reinterpret_cast<compiler::target::uword*>(end); 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;
}
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,
uint8_t** instructions_blob_buffer,
ReAlloc alloc,
@ -1034,9 +912,7 @@ intptr_t BlobImageWriter::WriteByteSequence(uword start, uword end) {
}
void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
const bool bare_instruction_payloads =
FLAG_precompiled_mode && FLAG_use_bare_instructions;
const intptr_t instructions_length = next_text_offset_;
#ifdef DART_PRECOMPILER
intptr_t segment_base = 0;
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
// HeapPage.
const intptr_t image_size = Utils::RoundUp(
next_text_offset_, compiler::target::ObjectAlignment::kObjectAlignment);
instructions_blob_stream_.WriteTargetWord(image_size);
instructions_blob_stream_.WriteTargetWord(instructions_length);
#if defined(DART_PRECOMPILER)
instructions_blob_stream_.WriteTargetWord(
elf_ != nullptr ? bss_base_ - segment_base : 0);
@ -1065,36 +939,6 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
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;
#if defined(DART_PRECOMPILER)
@ -1108,15 +952,6 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
const bool is_trampoline = data.trampoline_bytes != nullptr;
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) {
const auto start = reinterpret_cast<uword>(data.trampoline_bytes);
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_;
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.
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;
#endif
intptr_t payload_stream_start = 0;
#if defined(IS_SIMARM_X64)
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);
if (!bare_instruction_payloads) {
instructions_blob_stream_.WriteTargetWord(marked_tags);
instructions_blob_stream_.WriteFixed<uint32_t>(
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_.WriteTargetWord(marked_tags);
instructions_blob_stream_.WriteFixed<uint32_t>(
insns.raw_ptr()->size_and_flags_);
payload_stream_start = instructions_blob_stream_.Position();
instructions_blob_stream_.WriteBytes(
reinterpret_cast<const void*>(insns.PayloadStart()), insns.Size());
const intptr_t alignment =
bare_instruction_payloads
? kBareInstructionsAlignment
: compiler::target::ObjectAlignment::kObjectAlignment;
instructions_blob_stream_.Align(alignment);
instructions_blob_stream_.Align(
compiler::target::ObjectAlignment::kObjectAlignment);
const intptr_t end_offset = instructions_blob_stream_.bytes_written();
text_offset += (end_offset - start_offset);
USE(object_start);
USE(object_end);
#else // defined(IS_SIMARM_X64)
// Only payload is output in AOT snapshots.
const uword header_size =
bare_instruction_payloads
? 0
: compiler::target::Instructions::HeaderSize();
const uword payload_size = SizeInSnapshot(insns.raw()) - header_size;
const uword object_end = payload_start + payload_size;
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);
payload_stream_start = instructions_blob_stream_.Position() +
(insns.PayloadStart() - object_start);
instructions_blob_stream_.WriteWord(marked_tags);
text_offset += sizeof(uword);
object_start += sizeof(uword);
text_offset += WriteByteSequence(object_start, object_end);
#endif
#if defined(DART_PRECOMPILER)
@ -1250,12 +1076,7 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
ImageWriter::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.
instructions_blob_stream_.Align(
compiler::target::ObjectAlignment::kObjectAlignment);
ASSERT(instructions_blob_stream_.bytes_written() == image_size);
ASSERT(instructions_blob_stream_.bytes_written() == instructions_length);
#ifdef DART_PRECOMPILER
const char* instructions_symbol =
@ -1293,18 +1114,6 @@ RawApiError* ImageReader::VerifyAlignment() const {
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 {
ASSERT(Utils::IsAligned(offset, kObjectAlignment));

View file

@ -69,8 +69,6 @@ class ImageReader : public ZoneAllocated {
RawApiError* VerifyAlignment() const;
ONLY_IN_PRECOMPILED(uword GetBareInstructionsAt(uint32_t offset) const);
ONLY_IN_PRECOMPILED(uword GetBareInstructionsEnd() const);
RawInstructions* GetInstructionsAt(uint32_t offset) const;
RawObject* GetObjectAt(uint32_t offset) const;
@ -155,9 +153,6 @@ class ImageWriter : public ValueObject {
void ResetOffsets() {
next_data_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();
instructions_.Clear();
}
@ -184,7 +179,6 @@ class ImageWriter : public ValueObject {
void TraceInstructions(const Instructions& instructions);
static intptr_t SizeInSnapshot(RawObject* object);
static const intptr_t kBareInstructionsAlignment = 4;
protected:
void WriteROData(WriteStream* stream);
@ -335,7 +329,6 @@ class AssemblyImageWriter : public ImageWriter {
void FrameUnwindPrologue();
void FrameUnwindEpilogue();
intptr_t WriteByteSequence(uword start, uword end);
intptr_t Align(intptr_t alignment, uword position = 0);
#if defined(TARGET_ARCH_IS_64_BIT)
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::bytecode_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::pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
RawClass* Object::code_source_map_class_ =
@ -795,9 +793,6 @@ void Object::Init(Isolate* isolate) {
cls = Class::New<Instructions, RTN::Instructions>(isolate);
instructions_class_ = cls.raw();
cls = Class::New<InstructionsSection, RTN::InstructionsSection>(isolate);
instructions_section_class_ = cls.raw();
cls = Class::New<ObjectPool, RTN::ObjectPool>(isolate);
object_pool_class_ = cls.raw();
@ -1226,7 +1221,6 @@ void Object::Cleanup() {
code_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
bytecode_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);
pc_descriptors_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(bytecode, Bytecode);
SET_CLASS_NAME(instructions, Instructions);
SET_CLASS_NAME(instructions_section, InstructionsSection);
SET_CLASS_NAME(object_pool, ObjectPool);
SET_CLASS_NAME(code_source_map, CodeSourceMap);
SET_CLASS_NAME(pc_descriptors, PcDescriptors);
@ -4543,8 +4536,6 @@ const char* Class::GenerateUserVisibleName() const {
return Symbols::Bytecode().ToCString();
case kInstructionsCid:
return Symbols::Instructions().ToCString();
case kInstructionsSectionCid:
return Symbols::InstructionsSection().ToCString();
case kObjectPoolCid:
return Symbols::ObjectPool().ToCString();
case kCodeSourceMapCid:
@ -13117,7 +13108,7 @@ void Library::CheckFunctionFingerprints() {
}
#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(Object::instructions_class() != Class::null());
if (size < 0 || size > kMaxElements) {
@ -13132,7 +13123,7 @@ RawInstructions* Instructions::New(intptr_t size, bool has_monomorphic_entry) {
NoSafepointScope no_safepoint;
result ^= raw;
result.SetSize(size);
result.SetHasMonomorphicEntry(has_monomorphic_entry);
result.SetHasSingleEntryPoint(has_single_entry_point);
result.set_stats(nullptr);
}
return result.raw();
@ -13157,10 +13148,6 @@ void Instructions::set_stats(CodeStatistics* stats) const {
#endif
}
const char* InstructionsSection::ToCString() const {
return "InstructionsSection";
}
// Encode integer |value| in SLEB128 format and store into |data|.
static void EncodeSLEB128(GrowableArray<uint8_t>* data, intptr_t value) {
bool is_last_part = false;
@ -15338,11 +15325,12 @@ void Code::Disassemble(DisassemblyFormatter* formatter) const {
if (!FLAG_support_disassembler) {
return;
}
const uword start = PayloadStart();
const Instructions& instr = Instructions::Handle(instructions());
uword start = instr.PayloadStart();
if (formatter == NULL) {
Disassembler::Disassemble(start, start + Size(), *this);
Disassembler::Disassemble(start, start + instr.Size(), *this);
} else {
Disassembler::Disassemble(start, start + Size(), formatter, *this);
Disassembler::Disassemble(start, start + instr.Size(), formatter, *this);
}
#endif // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
}
@ -15482,7 +15470,7 @@ RawCode* Code::FinalizeCode(FlowGraphCompiler* compiler,
assembler->GetSelfHandle() = code.raw();
#endif
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
@ -15883,10 +15871,11 @@ void Code::DumpSourcePositions(bool relative_addresses) const {
bool Code::VerifyBSSRelocations() const {
const auto& descriptors = PcDescriptors::Handle(pc_descriptors());
const auto& insns = Instructions::Handle(instructions());
PcDescriptors::Iterator iterator(descriptors,
RawPcDescriptors::kBSSRelocation);
while (iterator.MoveNext()) {
const uword reloc = PayloadStart() + iterator.PcOffset();
const uword reloc = insns.PayloadStart() + iterator.PcOffset();
const word target = *reinterpret_cast<word*>(reloc);
// The relocation is in its original unpatched form -- the addend
// representing the target symbol itself.

View file

@ -482,9 +482,6 @@ class Object {
static RawClass* code_class() { return code_class_; }
static RawClass* bytecode_class() { return bytecode_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* pc_descriptors_class() { return pc_descriptors_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* bytecode_class_; // Class of the Bytecode 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* pc_descriptors_class_; // Class of PcDescriptors 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_);
}
bool HasMonomorphicEntry() const {
bool HasSingleEntryPoint() const {
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_);
}
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 MonomorphicEntryPoint() const { return MonomorphicEntryPoint(raw()); }
uword EntryPoint() const { return EntryPoint(raw()); }
@ -5099,7 +5102,7 @@ class Instructions : public Object {
static uword MonomorphicEntryPoint(const RawInstructions* instr) {
uword entry = PayloadStart(instr);
if (HasMonomorphicEntry(instr)) {
if (!HasSingleEntryPoint(instr)) {
entry += !FLAG_precompiled_mode ? kMonomorphicEntryOffsetJIT
: kMonomorphicEntryOffsetAOT;
}
@ -5108,7 +5111,7 @@ class Instructions : public Object {
static uword EntryPoint(const RawInstructions* instr) {
uword entry = PayloadStart(instr);
if (HasMonomorphicEntry(instr)) {
if (!HasSingleEntryPoint(instr)) {
entry += !FLAG_precompiled_mode ? kPolymorphicEntryOffsetJIT
: kPolymorphicEntryOffsetAOT;
}
@ -5158,7 +5161,7 @@ class Instructions : public Object {
SizeBits::update(value, raw_ptr()->size_and_flags_));
}
void SetHasMonomorphicEntry(bool value) const {
void SetHasSingleEntryPoint(bool value) const {
StoreNonPointer(&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
// the RawInstruction and RawCode objects, sets up the pointer offsets
// 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);
friend class Class;
@ -5177,34 +5180,6 @@ class Instructions : public Object {
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 {
public:
intptr_t Length() const;
@ -5580,6 +5555,11 @@ class Code : public Object {
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() {
return OFFSET_OF(RawCode, instructions_);
}
@ -5629,38 +5609,12 @@ class Code : public Object {
bool is_alive() const { return AliveBit::decode(raw_ptr()->state_bits_); }
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()].
uword PayloadStart() const { return PayloadStartOf(raw()); }
static uword PayloadStartOf(const RawCode* code) {
#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
uword PayloadStart() const {
return Instructions::PayloadStart(instructions());
}
// Returns the entry point of [instructions()].
uword EntryPoint() const { return EntryPointOf(raw()); }
static uword EntryPointOf(const RawCode* code) {
#if defined(DART_PRECOMPILED_RUNTIME)
return code->ptr()->entry_point_;
#else
return Instructions::EntryPoint(InstructionsOf(code));
#endif
}
uword EntryPoint() const { return Instructions::EntryPoint(instructions()); }
// Returns the unchecked entry point of [instructions()].
uword UncheckedEntryPoint() const {
#if defined(DART_PRECOMPILED_RUNTIME)
@ -5671,11 +5625,7 @@ class Code : public Object {
}
// Returns the monomorphic entry point of [instructions()].
uword MonomorphicEntryPoint() const {
#if defined(DART_PRECOMPILED_RUNTIME)
return raw_ptr()->monomorphic_entry_point_;
#else
return Instructions::MonomorphicEntryPoint(instructions());
#endif
}
// Returns the unchecked monomorphic entry point of [instructions()].
uword MonomorphicUncheckedEntryPoint() const {
@ -5685,16 +5635,8 @@ class Code : public Object {
return MonomorphicEntryPoint() + raw_ptr()->unchecked_offset_;
#endif
}
// Returns the size of [instructions()].
intptr_t Size() const { return PayloadSizeOf(raw()); }
static intptr_t PayloadSizeOf(const RawCode* code) {
#if defined(DART_PRECOMPILED_RUNTIME)
return code->ptr()->instructions_length_;
#else
return Instructions::Size(InstructionsOf(code));
#endif
}
intptr_t Size() const { return Instructions::Size(instructions()); }
RawObjectPool* GetObjectPool() const;
// 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)].
static bool ContainsInstructionAt(const RawCode* code, uword pc) {
return RawCode::ContainsPC(code, pc);
static bool ContainsInstructionAt(const RawCode* code, uword addr) {
return Instructions::ContainsPc(InstructionsOf(code), addr);
}
// 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_].
uint32_t UncheckedEntryPointOffset() const {
return UncheckedEntryPointOffsetOf(raw());
}
static uint32_t UncheckedEntryPointOffsetOf(RawCode* code) {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
return raw_ptr()->unchecked_entry_point_ - raw_ptr()->entry_point_;
#else
return code->ptr()->unchecked_offset_;
return raw_ptr()->unchecked_offset_;
#endif
}
@ -6152,7 +6092,6 @@ class Code : public Object {
friend class FunctionSerializationCluster;
friend class CodeSerializationCluster;
friend class CodeDeserializationCluster;
friend class Deserializer; // for InitializeCachedEntryPointsFrom
friend class StubCode; // for set_object_pool
friend class MegamorphicCacheTable; // for set_object_pool
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 {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);

View file

@ -100,13 +100,6 @@ intptr_t RawObject::HeapSizeFromClass() const {
instance_size = Instructions::InstanceSize(instructions_size);
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: {
const RawContext* raw_context = reinterpret_cast<const RawContext*>(this);
intptr_t num_variables = raw_context->ptr()->num_variables_;
@ -556,7 +549,6 @@ NULL_VISITOR(TransferableTypedData)
REGULAR_VISITOR(Pointer)
NULL_VISITOR(DynamicLibrary)
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(CodeSourceMap, raw_obj->ptr()->length_)
VARIABLE_NULL_VISITOR(CompressedStackMaps, raw_obj->ptr()->payload_size())
@ -572,12 +564,12 @@ UNREACHABLE_VISITOR(String)
// Smi has no heap representation.
UNREACHABLE_VISITOR(Smi)
bool RawCode::ContainsPC(const RawObject* raw_obj, uword pc) {
if (!raw_obj->IsCode()) return false;
auto const raw_code = static_cast<const RawCode*>(raw_obj);
const uword start = Code::PayloadStartOf(raw_code);
const uword size = Code::PayloadSizeOf(raw_code);
return (pc - start) <= size; // pc may point just past last instruction.
bool RawCode::ContainsPC(RawObject* raw_obj, uword pc) {
if (raw_obj->IsCode()) {
RawCode* raw_code = static_cast<RawCode*>(raw_obj);
return RawInstructions::ContainsPC(raw_code->ptr()->instructions_, pc);
}
return false;
}
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
// find those pointers for tracing.
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++) {
int32_t offset = obj->data()[i];
visitor->VisitPointer(
@ -633,13 +626,12 @@ intptr_t RawObjectPool::VisitObjectPoolPointers(RawObjectPool* raw_obj,
return ObjectPool::InstanceSize(length);
}
bool RawInstructions::ContainsPC(const RawInstructions* raw_instr, uword pc) {
const uword start = Instructions::PayloadStart(raw_instr);
const uword size = Instructions::Size(raw_instr);
// 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 (pc - start) <= size;
bool RawInstructions::ContainsPC(RawInstructions* raw_instr, uword pc) {
uword start_pc =
reinterpret_cast<uword>(raw_instr->ptr()) + Instructions::HeaderSize();
uword end_pc = start_pc + Instructions::Size(raw_instr);
ASSERT(end_pc > start_pc);
return (pc >= start_pc) && (pc < end_pc);
}
intptr_t RawInstance::VisitInstancePointers(RawInstance* raw_obj,

View file

@ -1408,11 +1408,8 @@ class RawKernelProgramInfo : public RawObject {
class RawCode : public RawObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(Code);
// When in the precompiled runtime, there is no disabling of Code objects
// and thus no active_instructions_ field. Thus, the entry point caches are
// only set once during deserialization. If not using bare instructions,
// the caches should match the entry points for instructions_.
//
// When in the precompiled runtime, there is no active_instructions_ field
// and the entry point caches should contain entry points for instructions_.
// Otherwise, they should contain entry points for active_instructions_.
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
// to reset the active_instructions_ to instructions_.
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.
int32_t* data() { 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;
template <bool>
@ -1589,7 +1584,7 @@ class RawInstructions : public RawObject {
// Private helper function used while visiting stack frames. The
// code which iterates over dart frames is also called during GC and
// 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 RawFunction;
@ -1604,19 +1599,6 @@ class RawInstructions : public RawObject {
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 {
public:
// 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::IsTypedDataClassId(index) || (index == kContextCid) ||
(index == kTypeArgumentsCid) || (index == kInstructionsCid) ||
(index == kInstructionsSectionCid) || (index == kObjectPoolCid) ||
(index == kPcDescriptorsCid) || (index == kCodeSourceMapCid) ||
(index == kCompressedStackMapsCid) ||
(index == kObjectPoolCid) || (index == kPcDescriptorsCid) ||
(index == kCodeSourceMapCid) || (index == kCompressedStackMapsCid) ||
(index == kLocalVarDescriptorsCid) ||
(index == kExceptionHandlersCid) || (index == kCodeCid) ||
(index == kContextScopeCid) || (index == kInstanceCid) ||

View file

@ -541,7 +541,6 @@ MESSAGE_SNAPSHOT_UNREACHABLE(Field);
MESSAGE_SNAPSHOT_UNREACHABLE(Function);
MESSAGE_SNAPSHOT_UNREACHABLE(ICData);
MESSAGE_SNAPSHOT_UNREACHABLE(Instructions);
MESSAGE_SNAPSHOT_UNREACHABLE(InstructionsSection);
MESSAGE_SNAPSHOT_UNREACHABLE(KernelProgramInfo);
MESSAGE_SNAPSHOT_UNREACHABLE(Library);
MESSAGE_SNAPSHOT_UNREACHABLE(LibraryPrefix);

View file

@ -11,11 +11,13 @@ namespace dart {
#if defined(DART_PRECOMPILED_RUNTIME)
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) {
return Code::PayloadStartOf(code) + Code::PayloadSizeOf(code);
auto instr = Code::InstructionsOf(code);
return Instructions::PayloadStart(instr) + Instructions::Size(instr);
}
void ReversePcLookupCache::BuildAndAttachToIsolate(Isolate* isolate) {

View file

@ -66,11 +66,7 @@ class ReversePcLookupCache {
}
// Looks up the [Code] object from a given [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) {
inline RawCode* Lookup(uword pc) {
NoSafepointScope no_safepoint_scope;
intptr_t left = 0;
@ -85,14 +81,6 @@ class ReversePcLookupCache {
uword middle_pc = pc_array_[middle];
if (middle_pc < pc_offset) {
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 {
right = middle;
}
@ -128,9 +116,7 @@ class ReversePcLookupCache {
inline bool Contains(uword pc) { return false; }
inline RawCode* Lookup(uword pc, bool is_return_address = false) {
UNREACHABLE();
}
inline RawCode* Lookup(uword pc) { UNREACHABLE(); }
};
#endif // defined(DART_PRECOMPILED_RUNTIME

View file

@ -126,7 +126,7 @@ bool StackFrame::IsBareInstructionsDartFrame() const {
if (auto isolate = IsolateOfBareInstructionsFrame()) {
Code code;
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();
ASSERT(cid == kNullCid || cid == kClassCid || cid == kFunctionCid);
@ -141,7 +141,7 @@ bool StackFrame::IsBareInstructionsStubFrame() const {
if (auto isolate = IsolateOfBareInstructionsFrame()) {
Code code;
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();
ASSERT(cid == kNullCid || cid == kClassCid || cid == kFunctionCid);
@ -253,8 +253,7 @@ void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
Code code;
if (auto isolate = IsolateOfBareInstructionsFrame()) {
auto const rct = isolate->reverse_pc_lookup_cache();
code = rct->Lookup(pc(), /*is_return_address=*/true);
code = isolate->reverse_pc_lookup_cache()->Lookup(pc());
} else {
RawObject* pc_marker = *(reinterpret_cast<RawObject**>(
fp() + ((is_interpreted() ? kKBCPcMarkerSlotFromFp
@ -388,8 +387,7 @@ RawCode* StackFrame::LookupDartCode() const {
NoSafepointScope no_safepoint;
#endif
if (auto isolate = IsolateOfBareInstructionsFrame()) {
auto const rct = isolate->reverse_pc_lookup_cache();
return rct->Lookup(pc(), /*is_return_address=*/true);
return isolate->reverse_pc_lookup_cache()->Lookup(pc());
}
RawCode* code = GetCodeObject();
@ -403,8 +401,7 @@ RawCode* StackFrame::LookupDartCode() const {
RawCode* StackFrame::GetCodeObject() const {
ASSERT(!is_interpreted());
if (auto isolate = IsolateOfBareInstructionsFrame()) {
auto const rct = isolate->reverse_pc_lookup_cache();
return rct->Lookup(pc(), /*is_return_address=*/true);
return isolate->reverse_pc_lookup_cache()->Lookup(pc());
} else {
RawObject* pc_marker = *(reinterpret_cast<RawObject**>(
fp() + runtime_frame_layout.code_from_fp * kWordSize));

View file

@ -178,7 +178,6 @@ class ObjectPointerVisitor;
V(IndexToken, "[]") \
V(InitPrefix, "init:") \
V(Instructions, "Instructions") \
V(InstructionsSection, "InstructionsSection") \
V(Int, "int") \
V(Int16List, "Int16List") \
V(Int32List, "Int32List") \