Skip to content

Commit 977997b

Browse files
sstricklcommit-bot@chromium.org
authored andcommitted
[vm/aot] Add Image objects to V8 snapshot profiles.
This avoids attributing the header and padding bytes in Image objects to the artificial root, instead making it clear why these bytes exist. It also ensures Instructions objects (in the non-bare-payload case) are never considered roots of the profile. Also unify semantics of text_offset in AssemblyImageWriter::WriteText() and BlobImageWriter::WriteText(). Originally the former was the offset from the start of the text section and the latter was the offset from the start of the instructions objects/payloads. Now they're both the offset in the text section. Bug: #41249 Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm_x64-try Change-Id: I617e76c9c390a93abb6bc37efc1355368c64691e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149286 Reviewed-by: Vyacheslav Egorov <[email protected]> Commit-Queue: Tess Strickland <[email protected]>
1 parent 9cca0f7 commit 977997b

File tree

1 file changed

+95
-67
lines changed

1 file changed

+95
-67
lines changed

runtime/vm/image_snapshot.cc

Lines changed: 95 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,12 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
649649
assembly_stream_.Print("%s:\n", instructions_symbol);
650650

651651
intptr_t text_offset = 0;
652+
#if defined(DART_PRECOMPILER)
653+
// Parent used for later profile objects. Starts off as the Image. When
654+
// writing bare instructions payloads, this is later updated with the
655+
// InstructionsSection object which contains all the bare payloads.
656+
V8SnapshotProfileWriter::ObjectId parent_id(offset_space_, text_offset);
657+
#endif
652658

653659
// This head also provides the gap to make the instructions snapshot
654660
// look like a OldPage.
@@ -668,18 +674,36 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
668674
ASSERT_EQUAL(text_offset, Image::kHeaderSize);
669675
#if defined(DART_PRECOMPILER)
670676
if (profile_writer_ != nullptr) {
671-
profile_writer_->AttributeBytesTo(
672-
V8SnapshotProfileWriter::ArtificialRootId(),
673-
(next_text_offset_ - image_size) + Image::kHeaderSize);
677+
profile_writer_->SetObjectTypeAndName(parent_id, "Image",
678+
instructions_symbol);
679+
// Assign post-instruction padding to the Image, unless we're writing bare
680+
// instruction payloads, in which case we'll assign it to the
681+
// InstructionsSection object.
682+
const intptr_t padding =
683+
bare_instruction_payloads ? 0 : image_size - next_text_offset_;
684+
profile_writer_->AttributeBytesTo(parent_id, Image::kHeaderSize + padding);
685+
profile_writer_->AddRoot(parent_id);
674686
}
675687
#endif
676688

677-
// Only valid if bare_instruction_payloads is true.
678-
V8SnapshotProfileWriter::ObjectId instructions_section_id(offset_space_, -1);
679-
680689
if (bare_instruction_payloads) {
681-
const intptr_t instructions_section_start = text_offset;
682-
const intptr_t section_size = image_size - instructions_section_start;
690+
#if defined(DART_PRECOMPILER)
691+
if (profile_writer_ != nullptr) {
692+
const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
693+
profile_writer_->SetObjectTypeAndName(id, instructions_section_type_,
694+
instructions_symbol);
695+
const intptr_t padding = image_size - next_text_offset_;
696+
profile_writer_->AttributeBytesTo(
697+
id, compiler::target::InstructionsSection::HeaderSize() + padding);
698+
const intptr_t element_offset = id.second - parent_id.second;
699+
profile_writer_->AttributeReferenceTo(
700+
parent_id,
701+
{id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
702+
// Later objects will have the InstructionsSection as a parent.
703+
parent_id = id;
704+
}
705+
#endif
706+
const intptr_t section_size = image_size - text_offset;
683707
// Add the RawInstructionsSection header.
684708
const compiler::target::uword marked_tags =
685709
ObjectLayout::OldBit::encode(true) |
@@ -694,22 +718,8 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
694718
const intptr_t instructions_length =
695719
next_text_offset_ - (text_offset + compiler::target::kWordSize);
696720
text_offset += WriteWordLiteralText(instructions_length);
697-
698-
if (profile_writer_ != nullptr) {
699-
instructions_section_id = {offset_space_, instructions_section_start};
700-
const intptr_t non_instruction_bytes =
701-
compiler::target::InstructionsSection::HeaderSize();
702-
profile_writer_->SetObjectTypeAndName(instructions_section_id,
703-
instructions_section_type_,
704-
instructions_symbol);
705-
profile_writer_->AttributeBytesTo(instructions_section_id,
706-
non_instruction_bytes);
707-
profile_writer_->AddRoot(instructions_section_id);
708-
}
709721
}
710722

711-
const intptr_t instructions_start = text_offset;
712-
713723
FrameUnwindPrologue();
714724

715725
PcDescriptors& descriptors = PcDescriptors::Handle(zone);
@@ -730,22 +740,20 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
730740

731741
const auto object_name = namer.SnapshotNameFor(dwarf_index, data);
732742

743+
#if defined(DART_PRECOMPILER)
733744
if (profile_writer_ != nullptr) {
734745
const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
735746
auto const type = is_trampoline ? trampoline_type_ : instructions_type_;
736747
const intptr_t size = is_trampoline ? data.trampoline_length
737748
: SizeInSnapshot(data.insns_->raw());
738749
profile_writer_->SetObjectTypeAndName(id, type, object_name);
739750
profile_writer_->AttributeBytesTo(id, size);
740-
// If the object is wrapped in an InstructionSection, then add an
741-
// element reference.
742-
if (bare_instruction_payloads) {
743-
const intptr_t element_offset = text_offset - instructions_start;
744-
profile_writer_->AttributeReferenceTo(
745-
instructions_section_id,
746-
{id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
747-
}
751+
const intptr_t element_offset = id.second - parent_id.second;
752+
profile_writer_->AttributeReferenceTo(
753+
parent_id,
754+
{id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
748755
}
756+
#endif
749757

750758
if (is_trampoline) {
751759
const auto start = reinterpret_cast<uword>(data.trampoline_bytes);
@@ -1082,11 +1090,11 @@ intptr_t BlobImageWriter::WriteByteSequence(uword start, uword end) {
10821090
void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
10831091
const bool bare_instruction_payloads =
10841092
FLAG_precompiled_mode && FLAG_use_bare_instructions;
1085-
const char* instructions_symbol = vm ? kVmSnapshotInstructionsAsmSymbol
1086-
: kIsolateSnapshotInstructionsAsmSymbol;
10871093
auto const zone = Thread::Current()->zone();
10881094

10891095
#if defined(DART_PRECOMPILER)
1096+
auto const instructions_symbol = vm ? kVmSnapshotInstructionsAsmSymbol
1097+
: kIsolateSnapshotInstructionsAsmSymbol;
10901098
intptr_t segment_base = 0;
10911099
if (elf_ != nullptr) {
10921100
segment_base = elf_->NextMemoryOffset();
@@ -1100,6 +1108,14 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
11001108
}
11011109
#endif
11021110

1111+
intptr_t text_offset = 0;
1112+
#if defined(DART_PRECOMPILER)
1113+
// Parent used for later profile objects. Starts off as the Image. When
1114+
// writing bare instructions payloads, this is later updated with the
1115+
// InstructionsSection object which contains all the bare payloads.
1116+
V8SnapshotProfileWriter::ObjectId parent_id(offset_space_, text_offset);
1117+
#endif
1118+
11031119
// This header provides the gap to make the instructions snapshot look like a
11041120
// OldPage.
11051121
const intptr_t image_size = Utils::RoundUp(
@@ -1118,19 +1134,38 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
11181134
#endif
11191135
instructions_blob_stream_.Align(kMaxObjectAlignment);
11201136
ASSERT_EQUAL(instructions_blob_stream_.Position(), Image::kHeaderSize);
1137+
text_offset += Image::kHeaderSize;
11211138
#if defined(DART_PRECOMPILER)
11221139
if (profile_writer_ != nullptr) {
1123-
profile_writer_->AttributeBytesTo(
1124-
V8SnapshotProfileWriter::ArtificialRootId(),
1125-
(image_size - next_text_offset_) + Image::kHeaderSize);
1140+
profile_writer_->SetObjectTypeAndName(parent_id, "Image",
1141+
instructions_symbol);
1142+
// Assign post-instruction padding to the Image, unless we're writing bare
1143+
// instruction payloads, in which case we'll assign it to the
1144+
// InstructionsSection object.
1145+
const intptr_t padding =
1146+
bare_instruction_payloads ? 0 : image_size - next_text_offset_;
1147+
profile_writer_->AttributeBytesTo(parent_id, Image::kHeaderSize + padding);
1148+
profile_writer_->AddRoot(parent_id);
11261149
}
11271150
#endif
11281151

1129-
// Only valid when bare_instructions_payloads is true.
1130-
const V8SnapshotProfileWriter::ObjectId instructions_section_id(
1131-
offset_space_, bare_instruction_payloads ? Image::kHeaderSize : -1);
1132-
11331152
if (bare_instruction_payloads) {
1153+
#if defined(DART_PRECOMPILER)
1154+
if (profile_writer_ != nullptr) {
1155+
const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
1156+
profile_writer_->SetObjectTypeAndName(id, instructions_section_type_,
1157+
instructions_symbol);
1158+
const intptr_t padding = image_size - next_text_offset_;
1159+
profile_writer_->AttributeBytesTo(
1160+
id, compiler::target::InstructionsSection::HeaderSize() + padding);
1161+
const intptr_t element_offset = id.second - parent_id.second;
1162+
profile_writer_->AttributeReferenceTo(
1163+
parent_id,
1164+
{id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
1165+
// Later objects will have the InstructionsSection as a parent.
1166+
parent_id = id;
1167+
}
1168+
#endif
11341169
const intptr_t section_size = image_size - Image::kHeaderSize;
11351170
// Add the RawInstructionsSection header.
11361171
const compiler::target::uword marked_tags =
@@ -1146,20 +1181,12 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
11461181
next_text_offset_ - Image::kHeaderSize -
11471182
compiler::target::InstructionsSection::HeaderSize();
11481183
instructions_blob_stream_.WriteTargetWord(instructions_length);
1149-
1150-
if (profile_writer_ != nullptr) {
1151-
const intptr_t non_instruction_bytes =
1152-
compiler::target::InstructionsSection::HeaderSize();
1153-
profile_writer_->SetObjectTypeAndName(instructions_section_id,
1154-
instructions_section_type_,
1155-
instructions_symbol);
1156-
profile_writer_->AttributeBytesTo(instructions_section_id,
1157-
non_instruction_bytes);
1158-
profile_writer_->AddRoot(instructions_section_id);
1159-
}
1184+
ASSERT_EQUAL(instructions_blob_stream_.Position() - text_offset,
1185+
compiler::target::InstructionsSection::HeaderSize());
1186+
text_offset += compiler::target::InstructionsSection::HeaderSize();
11601187
}
11611188

1162-
intptr_t text_offset = 0;
1189+
ASSERT_EQUAL(text_offset, instructions_blob_stream_.Position());
11631190

11641191
#if defined(DART_PRECOMPILER)
11651192
auto& descriptors = PcDescriptors::Handle(zone);
@@ -1170,27 +1197,25 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
11701197
for (intptr_t i = 0; i < instructions_.length(); i++) {
11711198
auto& data = instructions_[i];
11721199
const bool is_trampoline = data.trampoline_bytes != nullptr;
1173-
ASSERT((data.text_offset_ - instructions_[0].text_offset_) == text_offset);
1200+
ASSERT(data.text_offset_ == text_offset);
11741201

1202+
#if defined(DART_PRECOMPILER)
11751203
const auto object_name = namer.SnapshotNameFor(i, data);
1176-
11771204
if (profile_writer_ != nullptr) {
1178-
const V8SnapshotProfileWriter::ObjectId object_id(
1179-
offset_space_, instructions_blob_stream_.Position());
1205+
const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
11801206
auto const type = is_trampoline ? trampoline_type_ : instructions_type_;
11811207
const intptr_t size = is_trampoline ? data.trampoline_length
11821208
: SizeInSnapshot(data.insns_->raw());
1183-
profile_writer_->SetObjectTypeAndName(object_id, type, object_name);
1184-
profile_writer_->AttributeBytesTo(object_id, size);
1209+
profile_writer_->SetObjectTypeAndName(id, type, object_name);
1210+
profile_writer_->AttributeBytesTo(id, size);
11851211
// If the object is wrapped in an InstructionSection, then add an
11861212
// element reference.
1187-
if (bare_instruction_payloads) {
1188-
profile_writer_->AttributeReferenceTo(
1189-
instructions_section_id,
1190-
{object_id, V8SnapshotProfileWriter::Reference::kElement,
1191-
text_offset});
1192-
}
1213+
const intptr_t element_offset = id.second - parent_id.second;
1214+
profile_writer_->AttributeReferenceTo(
1215+
parent_id,
1216+
{id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
11931217
}
1218+
#endif
11941219

11951220
if (is_trampoline) {
11961221
const auto start = reinterpret_cast<uword>(data.trampoline_bytes);
@@ -1300,10 +1325,10 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
13001325
// Overwrite the relocation position in the instruction stream with the
13011326
// offset of the BSS segment from the relocation position plus the
13021327
// addend in the relocation.
1303-
auto const text_offset = payload_offset + reloc_offset;
1304-
instructions_blob_stream_.SetPosition(text_offset);
1328+
auto const reloc_pos = payload_offset + reloc_offset;
1329+
instructions_blob_stream_.SetPosition(reloc_pos);
13051330

1306-
const compiler::target::word offset = bss_offset - text_offset + addend;
1331+
const compiler::target::word offset = bss_offset - reloc_pos + addend;
13071332
instructions_blob_stream_.WriteTargetWord(offset);
13081333
}
13091334

@@ -1323,8 +1348,11 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
13231348
// should match the alignment used in image_size above.
13241349
instructions_blob_stream_.Align(
13251350
compiler::target::ObjectAlignment::kObjectAlignment);
1351+
text_offset = Utils::RoundUp(
1352+
text_offset, compiler::target::ObjectAlignment::kObjectAlignment);
13261353

1327-
ASSERT_EQUAL(instructions_blob_stream_.bytes_written(), image_size);
1354+
ASSERT_EQUAL(text_offset, instructions_blob_stream_.bytes_written());
1355+
ASSERT_EQUAL(text_offset, image_size);
13281356

13291357
#ifdef DART_PRECOMPILER
13301358
if (elf_ != nullptr) {

0 commit comments

Comments
 (0)