diff --git a/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart b/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart index 0f1ff196157..9d23a87e9e3 100644 --- a/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart +++ b/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart @@ -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); }); } diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h index 52f8ef7b933..281c35dbbe5 100644 --- a/runtime/vm/class_id.h +++ b/runtime/vm/class_id.h @@ -28,7 +28,6 @@ namespace dart { V(Code) \ V(Bytecode) \ V(Instructions) \ - V(InstructionsSection) \ V(ObjectPool) \ V(PcDescriptors) \ V(CodeSourceMap) \ diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc index 719def8a5f3..4cb654f84b8 100644 --- a/runtime/vm/clustered_snapshot.cc +++ b/runtime/vm/clustered_snapshot.cc @@ -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(d->Ref(id)); + RawCode* code = reinterpret_cast(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(d->ReadRef()); @@ -1638,32 +1651,7 @@ class CodeDeserializationCluster : public DeserializationCluster { #endif code->ptr()->state_bits_ = d->Read(); -#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(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(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(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(); - 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(); - 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(); - 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(); + 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); } diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h index 9593645e3b2..15d53f7b6a9 100644 --- a/runtime/vm/clustered_snapshot.h +++ b/runtime/vm/clustered_snapshot.h @@ -358,9 +358,7 @@ class Serializer : public ThreadStackResource { Write(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(); } - ONLY_IN_PRECOMPILED(uword GetBareInstructionsEnd()); - void ReadInstructions(RawCode* code); + RawInstructions* ReadInstructions(); RawObject* GetObjectAt(uint32_t offset) const; void SkipHeader() { stream_.SetPosition(Snapshot::kHeaderSize); } diff --git a/runtime/vm/compiler/assembler/assembler.h b/runtime/vm/compiler/assembler/assembler.h index 07252cead89..96ed82e90f5 100644 --- a/runtime/vm/compiler/assembler/assembler.h +++ b/runtime/vm/compiler/assembler/assembler.h @@ -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; diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc index 9749e6eccb8..556af5073cf 100644 --- a/runtime/vm/compiler/assembler/assembler_arm.cc +++ b/runtime/vm/compiler/assembler/assembler_arm.cc @@ -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); } diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc index 9ef4fc82726..ea356c047d4 100644 --- a/runtime/vm/compiler/assembler/assembler_arm64.cc +++ b/runtime/vm/compiler/assembler/assembler_arm64.cc @@ -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); } diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc index 623af2fcd27..6c44032d970 100644 --- a/runtime/vm/compiler/assembler/assembler_ia32.cc +++ b/runtime/vm/compiler/assembler/assembler_ia32.cc @@ -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(); } diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc index 154d2e5b620..805ebcc4737 100644 --- a/runtime/vm/compiler/assembler/assembler_x64.cc +++ b/runtime/vm/compiler/assembler/assembler_x64.cc @@ -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(); } diff --git a/runtime/vm/compiler/assembler/disassembler.cc b/runtime/vm/compiler/assembler/disassembler.cc index 36f8cae859e..9564a4120d6 100644 --- a/runtime/vm/compiler/assembler/disassembler.cc +++ b/runtime/vm/compiler/assembler/disassembler.cc @@ -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) diff --git a/runtime/vm/compiler/relocation.cc b/runtime/vm/compiler/relocation.cc index 48bf5a7f9dd..2e39b42684e 100644 --- a/runtime/vm/compiler/relocation.cc +++ b/runtime/vm/compiler/relocation.cc @@ -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) diff --git a/runtime/vm/compiler/relocation.h b/runtime/vm/compiler/relocation.h index 2022f813352..50db3e1d7f3 100644 --- a/runtime/vm/compiler/relocation.h +++ b/runtime/vm/compiler/relocation.h @@ -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); diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc index a943fe1b5ae..d24699f8ccf 100644 --- a/runtime/vm/compiler/runtime_api.cc +++ b/runtime/vm/compiler/runtime_api.cc @@ -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; } diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h index 05f12c3874a..d427bb5e021 100644 --- a/runtime/vm/compiler/runtime_api.h +++ b/runtime/vm/compiler/runtime_api.h @@ -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; diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h index 08acc649e4c..f73ebd4ea5b 100644 --- a/runtime/vm/compiler/runtime_offsets_extracted.h +++ b/runtime/vm/compiler/runtime_offsets_extracted.h @@ -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 diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h index 955c36be324..c7bd6ae436c 100644 --- a/runtime/vm/compiler/runtime_offsets_list.h +++ b/runtime/vm/compiler/runtime_offsets_list.h @@ -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) \ diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h index 9b05b88b53a..d70d64e0c40 100644 --- a/runtime/vm/globals.h +++ b/runtime/vm/globals.h @@ -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 diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc index 4cfb084ea79..f3bae713cf3 100644 --- a/runtime/vm/image_snapshot.cc +++ b/runtime/vm/image_snapshot.cc @@ -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(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(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(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(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(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(start); - cursor < reinterpret_cast(end_of_words); - cursor++) { + for (auto* cursor = reinterpret_cast(start); + cursor < reinterpret_cast(end); cursor++) { WriteWordLiteralText(*cursor); } - if (end != end_of_words) { - auto start_of_rest = reinterpret_cast(end_of_words); - assembly_stream_.Print(".byte "); - for (auto cursor = start_of_rest; - cursor < reinterpret_cast(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(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(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(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( - 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( + insns.raw_ptr()->size_and_flags_); + payload_stream_start = instructions_blob_stream_.Position(); instructions_blob_stream_.WriteBytes( reinterpret_cast(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(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(instructions_image_) + offset; -} - -uword ImageReader::GetBareInstructionsEnd() const { - Image image(instructions_image_); - return reinterpret_cast(image.object_start()) + image.object_size(); -} -#endif - RawInstructions* ImageReader::GetInstructionsAt(uint32_t offset) const { ASSERT(Utils::IsAligned(offset, kObjectAlignment)); diff --git a/runtime/vm/image_snapshot.h b/runtime/vm/image_snapshot.h index 6c497b2b0ed..691f22c13db 100644 --- a/runtime/vm/image_snapshot.h +++ b/runtime/vm/image_snapshot.h @@ -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"; diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 3eb4ed92742..b6446a6972a 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -150,8 +150,6 @@ RawClass* Object::kernel_program_info_class_ = RawClass* Object::code_class_ = reinterpret_cast(RAW_NULL); RawClass* Object::bytecode_class_ = reinterpret_cast(RAW_NULL); RawClass* Object::instructions_class_ = reinterpret_cast(RAW_NULL); -RawClass* Object::instructions_section_class_ = - reinterpret_cast(RAW_NULL); RawClass* Object::object_pool_class_ = reinterpret_cast(RAW_NULL); RawClass* Object::pc_descriptors_class_ = reinterpret_cast(RAW_NULL); RawClass* Object::code_source_map_class_ = @@ -795,9 +793,6 @@ void Object::Init(Isolate* isolate) { cls = Class::New(isolate); instructions_class_ = cls.raw(); - cls = Class::New(isolate); - instructions_section_class_ = cls.raw(); - cls = Class::New(isolate); object_pool_class_ = cls.raw(); @@ -1226,7 +1221,6 @@ void Object::Cleanup() { code_class_ = reinterpret_cast(RAW_NULL); bytecode_class_ = reinterpret_cast(RAW_NULL); instructions_class_ = reinterpret_cast(RAW_NULL); - instructions_section_class_ = reinterpret_cast(RAW_NULL); object_pool_class_ = reinterpret_cast(RAW_NULL); pc_descriptors_class_ = reinterpret_cast(RAW_NULL); code_source_map_class_ = reinterpret_cast(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* 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(reloc); // The relocation is in its original unpatched form -- the addend // representing the target symbol itself. diff --git a/runtime/vm/object.h b/runtime/vm/object.h index 3caa8985644..6ab57cd46ee 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -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(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 diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc index a01e9e5542d..cf6b22f1044 100644 --- a/runtime/vm/object_service.cc +++ b/runtime/vm/object_service.cc @@ -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); diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc index a7a65f87dac..f858f65a394 100644 --- a/runtime/vm/raw_object.cc +++ b/runtime/vm/raw_object.cc @@ -100,13 +100,6 @@ intptr_t RawObject::HeapSizeFromClass() const { instance_size = Instructions::InstanceSize(instructions_size); break; } - case kInstructionsSectionCid: { - const RawInstructionsSection* raw_section = - reinterpret_cast(this); - intptr_t section_size = InstructionsSection::Size(raw_section); - instance_size = InstructionsSection::InstanceSize(section_size); - break; - } case kContextCid: { const RawContext* raw_context = reinterpret_cast(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(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(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(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(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, diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index 75b795ee45e..74dc6679310 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h @@ -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 @@ -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) || diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc index cfb4ab21a9a..31e4ed5c5c5 100644 --- a/runtime/vm/raw_object_snapshot.cc +++ b/runtime/vm/raw_object_snapshot.cc @@ -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); diff --git a/runtime/vm/reverse_pc_lookup_cache.cc b/runtime/vm/reverse_pc_lookup_cache.cc index 4757d244f0f..325d98f4986 100644 --- a/runtime/vm/reverse_pc_lookup_cache.cc +++ b/runtime/vm/reverse_pc_lookup_cache.cc @@ -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) { diff --git a/runtime/vm/reverse_pc_lookup_cache.h b/runtime/vm/reverse_pc_lookup_cache.h index 7de0bff1dac..8300b622b2c 100644 --- a/runtime/vm/reverse_pc_lookup_cache.h +++ b/runtime/vm/reverse_pc_lookup_cache.h @@ -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 diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc index 564d610c23e..ff5ac182bee 100644 --- a/runtime/vm/stack_frame.cc +++ b/runtime/vm/stack_frame.cc @@ -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( 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( fp() + runtime_frame_layout.code_from_fp * kWordSize)); diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h index 5316ec2f2ce..e8b5a14005b 100644 --- a/runtime/vm/symbols.h +++ b/runtime/vm/symbols.h @@ -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") \