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