Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Friends | List of all members
dart::ImageWriter Class Referenceabstract

#include <image_snapshot.h>

Inheritance diagram for dart::ImageWriter:
dart::ValueObject dart::BlobImageWriter

Classes

struct  InstructionsData
 
struct  ObjectData
 

Public Types

enum class  ProgramSection { Text , Data , Bss , BuildId }
 

Public Member Functions

 ImageWriter (Thread *thread, bool generates_assembly)
 
virtual ~ImageWriter ()
 
void ResetOffsets ()
 
void PrepareForSerialization (GrowableArray< ImageWriterCommand > *commands)
 
bool IsROSpace () const
 
int32_t GetTextOffsetFor (InstructionsPtr instructions, CodePtr code)
 
uint32_t GetDataOffsetFor (ObjectPtr raw_object)
 
uint32_t AddBytesToData (uint8_t *bytes, intptr_t length)
 
void Write (NonStreamingWriteStream *clustered_stream, bool vm)
 
intptr_t data_size () const
 
intptr_t text_size () const
 
intptr_t GetTextObjectCount () const
 
void GetTrampolineInfo (intptr_t *count, intptr_t *size) const
 
void DumpStatistics ()
 
void SetProfileWriter (V8SnapshotProfileWriter *profile_writer)
 
void ClearProfileWriter ()
 
void TraceInstructions (const Instructions &instructions)
 
const char * ObjectTypeForProfile (const Object &object) const
 
- Public Member Functions inherited from dart::ValueObject
 ValueObject ()
 
 ~ValueObject ()
 

Static Public Member Functions

static intptr_t SizeInSnapshot (ObjectPtr object)
 
static intptr_t SizeInSnapshot (const Object &object)
 
static const char * TagObjectTypeAsReadOnly (Zone *zone, const char *type)
 

Static Public Attributes

static constexpr intptr_t kBssAlignment = compiler::target::kWordSize
 
static constexpr intptr_t kRODataAlignment = kObjectStartAlignment
 
static constexpr intptr_t kTextAlignment = kObjectStartAlignment
 
static constexpr intptr_t kNumProgramSections
 

Protected Member Functions

virtual void WriteBss (bool vm)=0
 
virtual void WriteROData (NonStreamingWriteStream *clustered_stream, bool vm)
 
void WriteText (bool vm)
 
void DumpInstructionStats ()
 
void DumpInstructionsSizes ()
 
virtual bool EnterSection (ProgramSection name, bool vm, intptr_t alignment, intptr_t *alignment_padding=nullptr)=0
 
virtual void ExitSection (ProgramSection name, bool vm, intptr_t size)=0
 
virtual void FrameUnwindPrologue ()=0
 
virtual void FrameUnwindEpilogue ()=0
 
virtual intptr_t WriteTargetWord (word value)=0
 
virtual intptr_t WriteBytes (const void *bytes, intptr_t size)=0
 
virtual intptr_t Align (intptr_t alignment, intptr_t offset, intptr_t position)=0
 
template<typename T >
intptr_t WriteFixed (T value)
 
intptr_t AlignWithBreakInstructions (intptr_t alignment, intptr_t offset)
 

Static Protected Member Functions

static const char * SectionSymbol (ProgramSection section, bool vm)
 
static uword GetMarkedTags (classid_t cid, intptr_t size, bool is_canonical=false)
 
static uword GetMarkedTags (const Object &obj)
 

Protected Attributes

Thread *const thread_
 
Zone *const zone_
 
intptr_t next_data_offset_
 
intptr_t next_text_offset_
 
GrowableArray< ObjectDataobjects_
 
GrowableArray< InstructionsDatainstructions_
 
IdSpace offset_space_ = IdSpace::kSnapshot
 
V8SnapshotProfileWriterprofile_writer_ = nullptr
 
const char *const image_type_
 
const char *const instructions_section_type_
 
const char *const instructions_type_
 
const char *const trampoline_type_
 
const char *const padding_type_
 

Friends

template<class T >
class TraceImageObjectScope
 

Detailed Description

Definition at line 366 of file image_snapshot.h.

Member Enumeration Documentation

◆ ProgramSection

Enumerator
Text 
Data 
Bss 
BuildId 

Definition at line 446 of file image_snapshot.h.

446 {
447 Text, // Instructions.
448 Data, // Read-only data.
449 Bss, // Statically allocated variables initialized at load.
450 BuildId, // GNU build ID (when applicable)
451 // Adjust kNumProgramSections below to use last enum value added.
452 };

Constructor & Destructor Documentation

◆ ImageWriter()

dart::ImageWriter::ImageWriter ( Thread thread,
bool  generates_assembly 
)

Definition at line 174 of file image_snapshot.cc.

177 zone_(t->zone()),
180 objects_(),
182#if defined(DART_PRECOMPILER)
183 namer_(t->zone(),
184 deobfuscation_trie,
185 /*for_assembly=*/generates_assembly),
186#endif
189 TagObjectTypeAsReadOnly(zone_, "InstructionsSection")),
193 ResetOffsets();
194}
#define ASSERT_NOTNULL(ptr)
Definition assert.h:323
const char *const instructions_type_
GrowableArray< ObjectData > objects_
GrowableArray< InstructionsData > instructions_
const char *const padding_type_
static const char * TagObjectTypeAsReadOnly(Zone *zone, const char *type)
const char *const image_type_
const char *const instructions_section_type_
Thread *const thread_
const char *const trampoline_type_

◆ ~ImageWriter()

virtual dart::ImageWriter::~ImageWriter ( )
inlinevirtual

Definition at line 375 of file image_snapshot.h.

375{}

Member Function Documentation

◆ AddBytesToData()

uint32_t dart::ImageWriter::AddBytesToData ( uint8_t *  bytes,
intptr_t  length 
)

Definition at line 319 of file image_snapshot.cc.

319 {
320 const intptr_t snap_size = SizeInSnapshotForBytes(length);
321 const intptr_t offset = next_data_offset_;
322 next_data_offset_ += snap_size;
323 objects_.Add(ObjectData(bytes, length));
324 return offset;
325}
size_t length
Point offset

◆ Align()

virtual intptr_t dart::ImageWriter::Align ( intptr_t  alignment,
intptr_t  offset,
intptr_t  position 
)
protectedpure virtual

Implemented in dart::BlobImageWriter.

◆ AlignWithBreakInstructions()

intptr_t dart::ImageWriter::AlignWithBreakInstructions ( intptr_t  alignment,
intptr_t  offset 
)
protected

Definition at line 965 of file image_snapshot.cc.

966 {
967 intptr_t bytes_written = 0;
968 uword remaining;
969 for (remaining = Utils::RoundUp(offset, alignment) - offset;
970 remaining >= compiler::target::kWordSize;
971 remaining -= compiler::target::kWordSize) {
973 }
974 // clang-format off
975#if defined(TARGET_ARCH_ARM)
976 // All instructions are 4 bytes long on ARM architectures, so on 32-bit ARM
977 // there won't be any padding.
978 ASSERT_EQUAL(remaining, 0);
979#elif defined(TARGET_ARCH_ARM64)
980 // All instructions are 4 bytes long on ARM architectures, so on 64-bit ARM
981 // there is only 0 or 4 bytes of padding.
982 if (remaining != 0) {
983 ASSERT_EQUAL(remaining, 4);
984 bytes_written += WriteBytes(&kBreakInstructionFiller, remaining);
985 }
986#elif defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32) || \
987 defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
988 // The break instruction is a single byte, repeated to fill a word.
989 bytes_written += WriteBytes(&kBreakInstructionFiller, remaining);
990#else
991#error Unexpected architecture.
992#endif
993 // clang-format on
994 ASSERT_EQUAL(bytes_written, Utils::RoundUp(offset, alignment) - offset);
995 return bytes_written;
996}
#define ASSERT_EQUAL(expected, actual)
Definition assert.h:309
virtual intptr_t WriteBytes(const void *bytes, intptr_t size)=0
virtual intptr_t WriteTargetWord(word value)=0
static constexpr T RoundUp(T x, uintptr_t alignment, uintptr_t offset=0)
Definition utils.h:105
uintptr_t uword
Definition globals.h:501
constexpr uword kBreakInstructionFiller

◆ ClearProfileWriter()

void dart::ImageWriter::ClearProfileWriter ( )
inline

Definition at line 433 of file image_snapshot.h.

433{ profile_writer_ = nullptr; }
V8SnapshotProfileWriter * profile_writer_

◆ data_size()

intptr_t dart::ImageWriter::data_size ( ) const
inline

Definition at line 422 of file image_snapshot.h.

422{ return next_data_offset_; }

◆ DumpInstructionsSizes()

void dart::ImageWriter::DumpInstructionsSizes ( )
protected

◆ DumpInstructionStats()

void dart::ImageWriter::DumpInstructionStats ( )
protected

◆ DumpStatistics()

void dart::ImageWriter::DumpStatistics ( )

◆ EnterSection()

virtual bool dart::ImageWriter::EnterSection ( ProgramSection  name,
bool  vm,
intptr_t  alignment,
intptr_t *  alignment_padding = nullptr 
)
protectedpure virtual

Implemented in dart::BlobImageWriter.

◆ ExitSection()

virtual void dart::ImageWriter::ExitSection ( ProgramSection  name,
bool  vm,
intptr_t  size 
)
protectedpure virtual

Implemented in dart::BlobImageWriter.

◆ FrameUnwindEpilogue()

virtual void dart::ImageWriter::FrameUnwindEpilogue ( )
protectedpure virtual

Implemented in dart::BlobImageWriter.

◆ FrameUnwindPrologue()

virtual void dart::ImageWriter::FrameUnwindPrologue ( )
protectedpure virtual

Implemented in dart::BlobImageWriter.

◆ GetDataOffsetFor()

uint32_t dart::ImageWriter::GetDataOffsetFor ( ObjectPtr  raw_object)

Definition at line 306 of file image_snapshot.cc.

306 {
307#endif
308 const intptr_t snap_size = SizeInSnapshot(raw_object);
309 const intptr_t offset = next_data_offset_;
310 next_data_offset_ += snap_size;
311#if defined(SNAPSHOT_BACKTRACE)
312 objects_.Add(ObjectData(raw_object, raw_parent));
313#else
314 objects_.Add(ObjectData(raw_object));
315#endif
316 return offset;
317}
static intptr_t SizeInSnapshot(ObjectPtr object)

◆ GetMarkedTags() [1/2]

uword dart::ImageWriter::GetMarkedTags ( classid_t  cid,
intptr_t  size,
bool  is_canonical = false 
)
staticprotected

Definition at line 606 of file image_snapshot.cc.

608 {
609 // UntaggedObject::SizeTag expects a size divisible by kObjectAlignment and
610 // checks this in debug mode, but the size on the target machine may not be
611 // divisible by the host machine's object alignment if they differ.
612 //
613 // We define [adjusted_size] as [size] * m, where m is the host alignment
614 // divided by the target alignment. This means [adjusted_size] encodes on the
615 // host machine to the same bits that decode to [size] on the target machine.
616 // That is,
617 // [adjusted_size] / host align ==
618 // [size] * (host align / target align) / host align ==
619 // [size] / target align
620 //
621 // Since alignments are always powers of 2, we use shifts and logs.
622 const intptr_t adjusted_size =
625
627 UntaggedObject::SizeTag::encode(adjusted_size) |
629}
static constexpr uword encode(intptr_t size)
Definition raw_object.h:201
static constexpr uword kReadOnlyGCBits
const intptr_t cid
static constexpr intptr_t kObjectAlignmentLog2
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259
static constexpr intptr_t kObjectAlignmentLog2

◆ GetMarkedTags() [2/2]

uword dart::ImageWriter::GetMarkedTags ( const Object obj)
staticprotected

Definition at line 631 of file image_snapshot.cc.

631 {
632 uword tags = GetMarkedTags(obj.ptr()->untag()->GetClassId(),
633 SizeInSnapshot(obj), obj.IsCanonical());
634#if defined(HASH_IN_OBJECT_HEADER)
635 tags = UntaggedObject::HashTag::update(obj.ptr()->untag()->GetHeaderHash(),
636 tags);
637#endif
638 return tags;
639}
static uword GetMarkedTags(classid_t cid, intptr_t size, bool is_canonical=false)

◆ GetTextObjectCount()

intptr_t dart::ImageWriter::GetTextObjectCount ( ) const

Definition at line 327 of file image_snapshot.cc.

327 {
328 return instructions_.length();
329}

◆ GetTextOffsetFor()

int32_t dart::ImageWriter::GetTextOffsetFor ( InstructionsPtr  instructions,
CodePtr  code 
)

Definition at line 237 of file image_snapshot.cc.

238 {
239 Heap* const heap = thread_->heap();
240 intptr_t offset = heap->GetObjectId(instructions);
241 if (offset != 0) {
242 return offset;
243 }
244
246 heap->SetObjectId(instructions, offset);
247 next_text_offset_ += SizeInSnapshot(instructions);
248 instructions_.Add(InstructionsData(instructions, code, offset));
249
250 ASSERT(offset != 0);
251 return offset;
252}
intptr_t GetObjectId(ObjectPtr raw_obj) const
Definition heap.h:197
Heap * heap() const
Definition thread.cc:876
#define ASSERT(E)

◆ GetTrampolineInfo()

void dart::ImageWriter::GetTrampolineInfo ( intptr_t *  count,
intptr_t *  size 
) const

Definition at line 331 of file image_snapshot.cc.

331 {
332 ASSERT(count != nullptr && size != nullptr);
333 *count = 0;
334 *size = 0;
335 for (auto const& data : instructions_) {
336 if (data.trampoline_length != 0) {
337 *count += 1;
338 *size += data.trampoline_length;
339 }
340 }
341}
int count
static int8_t data[kExtLength]

◆ IsROSpace()

bool dart::ImageWriter::IsROSpace ( ) const
inline

◆ ObjectTypeForProfile()

const char * dart::ImageWriter::ObjectTypeForProfile ( const Object object) const

Definition at line 344 of file image_snapshot.cc.

344 {
345 if (profile_writer_ == nullptr) return nullptr;
346 ASSERT(IsROSpace());
349 Class& klass = thread_->ClassHandle();
350 String& name = thread_->StringHandle();
351 klass = object.clazz();
352 name = klass.UserVisibleName();
353 auto const name_str = name.ToCString();
354 return TagObjectTypeAsReadOnly(zone_, name_str);
355}
bool IsROSpace() const
const char *const name
#define REUSABLE_CLASS_HANDLESCOPE(thread)
#define REUSABLE_STRING_HANDLESCOPE(thread)

◆ PrepareForSerialization()

void dart::ImageWriter::PrepareForSerialization ( GrowableArray< ImageWriterCommand > *  commands)

Definition at line 196 of file image_snapshot.cc.

197 {
198 if (commands != nullptr) {
199 const intptr_t initial_offset = next_text_offset_;
200 for (auto& inst : *commands) {
201 ASSERT((initial_offset + inst.expected_offset) == next_text_offset_);
202 switch (inst.op) {
204 Heap* const heap = thread_->heap();
205 CodePtr code = inst.insert_instruction_of_code.code;
206 InstructionsPtr instructions = Code::InstructionsOf(code);
207 const intptr_t offset = next_text_offset_;
208 instructions_.Add(InstructionsData(instructions, code, offset));
209 next_text_offset_ += SizeInSnapshot(instructions);
210 ASSERT(heap->GetObjectId(instructions) == 0);
211 heap->SetObjectId(instructions, offset);
212 break;
213 }
215 auto trampoline_bytes = inst.insert_trampoline_bytes.buffer;
216 auto trampoline_length = inst.insert_trampoline_bytes.buffer_length;
217 const intptr_t offset = next_text_offset_;
218 instructions_.Add(
219 InstructionsData(trampoline_bytes, trampoline_length, offset));
220 next_text_offset_ += trampoline_length;
221 break;
222 }
224 auto padding_length = inst.insert_padding.padding_length;
225 const intptr_t offset = next_text_offset_;
226 instructions_.Add(InstructionsData(nullptr, padding_length, offset));
227 next_text_offset_ += padding_length;
228 break;
229 }
230 default:
231 UNREACHABLE();
232 }
233 }
234 }
235}
#define UNREACHABLE()
Definition assert.h:248
static InstructionsPtr InstructionsOf(const CodePtr code)
Definition object.h:6748
dict commands
Definition dom.py:171

◆ ResetOffsets()

void dart::ImageWriter::ResetOffsets ( )
inline

Definition at line 387 of file image_snapshot.h.

387 {
388 next_data_offset_ = Image::kHeaderSize;
389 next_text_offset_ = Image::kHeaderSize;
390#if defined(DART_PRECOMPILER)
391 if (FLAG_precompiled_mode) {
392 // We reserve space for the initial InstructionsSection object. It is
393 // manually serialized since it includes offsets to other snapshot parts.
394 // It contains all the payloads which start directly after the header.
395 next_text_offset_ += compiler::target::InstructionsSection::HeaderSize();
396 }
397#endif
398 objects_.Clear();
399 instructions_.Clear();
400 }

◆ SectionSymbol()

const char * dart::ImageWriter::SectionSymbol ( ProgramSection  section,
bool  vm 
)
staticprotected

Definition at line 641 of file image_snapshot.cc.

641 {
642 switch (section) {
652 }
653 UNREACHABLE();
654 return nullptr;
655}
#define kIsolateSnapshotDataAsmSymbol
Definition dart_api.h:3910
#define kIsolateSnapshotBssAsmSymbol
Definition dart_api.h:3913
#define kIsolateSnapshotInstructionsAsmSymbol
Definition dart_api.h:3911
#define kVmSnapshotBssAsmSymbol
Definition dart_api.h:3909
#define kVmSnapshotDataAsmSymbol
Definition dart_api.h:3907
#define kVmSnapshotInstructionsAsmSymbol
Definition dart_api.h:3908
#define kSnapshotBuildIdAsmSymbol
Definition dart_api.h:3906

◆ SetProfileWriter()

void dart::ImageWriter::SetProfileWriter ( V8SnapshotProfileWriter profile_writer)
inline

Definition at line 429 of file image_snapshot.h.

429 {
430 profile_writer_ = profile_writer;
431 }

◆ SizeInSnapshot() [1/2]

static intptr_t dart::ImageWriter::SizeInSnapshot ( const Object object)
inlinestatic

Definition at line 438 of file image_snapshot.h.

438 {
439 return SizeInSnapshot(object.ptr());
440 }

◆ SizeInSnapshot() [2/2]

intptr_t dart::ImageWriter::SizeInSnapshot ( ObjectPtr  object)
static

Definition at line 260 of file image_snapshot.cc.

260 {
261 const classid_t cid = raw_object->GetClassId();
262
263 switch (cid) {
264 case kCompressedStackMapsCid: {
265 auto raw_maps = CompressedStackMaps::RawCast(raw_object);
266 return compiler::target::CompressedStackMaps::InstanceSize(
268 }
269 case kCodeSourceMapCid: {
270 auto raw_map = CodeSourceMap::RawCast(raw_object);
271 return compiler::target::CodeSourceMap::InstanceSize(
272 raw_map->untag()->length_);
273 }
274 case kPcDescriptorsCid: {
275 auto raw_desc = PcDescriptors::RawCast(raw_object);
276 return compiler::target::PcDescriptors::InstanceSize(
277 raw_desc->untag()->length_);
278 }
279 case kInstructionsCid: {
280 auto raw_insns = Instructions::RawCast(raw_object);
281 return compiler::target::Instructions::InstanceSize(
282 Instructions::Size(raw_insns));
283 }
284 case kOneByteStringCid: {
285 auto raw_str = String::RawCast(raw_object);
286 return compiler::target::String::InstanceSize(
288 }
289 case kTwoByteStringCid: {
290 auto raw_str = String::RawCast(raw_object);
291 return compiler::target::String::InstanceSize(
293 }
294 default: {
295 const Class& clazz = Class::Handle(Object::Handle(raw_object).clazz());
296 FATAL("Unsupported class %s in rodata section.\n", clazz.ToCString());
297 return 0;
298 }
299 }
300}
static uintptr_t PayloadSizeOf(const CompressedStackMapsPtr raw)
Definition object.h:6243
intptr_t Size() const
Definition object.h:5711
static Object & Handle()
Definition object.h:407
static ObjectPtr RawCast(ObjectPtr obj)
Definition object.h:325
static constexpr intptr_t kBytesPerElement
Definition object.h:10521
static intptr_t LengthOf(StringPtr obj)
Definition object.h:10190
static constexpr intptr_t kBytesPerElement
Definition object.h:10662
#define FATAL(error)
int32_t classid_t
Definition globals.h:524

◆ TagObjectTypeAsReadOnly()

const char * dart::ImageWriter::TagObjectTypeAsReadOnly ( Zone zone,
const char *  type 
)
static

Definition at line 357 of file image_snapshot.cc.

357 {
358 ASSERT(zone != nullptr && type != nullptr);
359 return OS::SCreate(zone, "(RO) %s", type);
360}
static char * SCreate(Zone *zone, const char *format,...) PRINTF_ATTRIBUTE(2

◆ text_size()

intptr_t dart::ImageWriter::text_size ( ) const
inline

Definition at line 423 of file image_snapshot.h.

423{ return next_text_offset_; }

◆ TraceInstructions()

void dart::ImageWriter::TraceInstructions ( const Instructions instructions)

◆ Write()

void dart::ImageWriter::Write ( NonStreamingWriteStream clustered_stream,
bool  vm 
)

Definition at line 461 of file image_snapshot.cc.

461 {
462 Heap* heap = thread_->heap();
463 TIMELINE_DURATION(thread_, Isolate, "WriteInstructions");
464
465 // Handlify collected raw pointers as building the names below
466 // will allocate on the Dart heap.
467 for (intptr_t i = 0; i < instructions_.length(); i++) {
468 InstructionsData& data = instructions_[i];
469 if (data.trampoline_length != 0) continue;
470
471 data.insns_ = &Instructions::Handle(zone_, data.raw_insns_);
472 ASSERT(data.raw_code_ != nullptr);
473 data.code_ = &Code::Handle(zone_, data.raw_code_);
474
475 // Reset object id as an isolate snapshot after a VM snapshot will not use
476 // the VM snapshot's text image.
477 heap->SetObjectId(data.insns_->ptr(), 0);
478 }
479 for (auto& data : objects_) {
480 if (data.is_object()) {
481 data.obj = &Object::Handle(zone_, data.raw_obj);
482#if defined(SNAPSHOT_BACKTRACE)
483 data.parent = &Object::Handle(zone_, data.raw_parent);
484#endif
485 }
486 }
487
488 // Once we have everything handlified we are going to do convert raw bytes
489 // to string objects. String is used for simplicity as a bit container,
490 // can't use TypedData because it has an internal pointer (data_) field.
491 for (auto& data : objects_) {
492 if (!data.is_object()) {
493 const auto bytes = data.bytes;
494 data.obj = &Object::Handle(
495 zone_, OneByteString::New(bytes.buf, bytes.length, Heap::kOld));
496#if defined(SNAPSHOT_BACKTRACE)
497 data.parent = &Object::null_object();
498#endif
499 data.set_is_object(true);
500 String::Cast(*data.obj).Hash();
501 free(bytes.buf);
502 }
503 }
504
505 // Needs to happen before WriteText, as we add information about the
506 // BSSsection in the text section as an initial InstructionsSection object.
507 WriteBss(vm);
508
510 WriteText(vm);
511
512 // Append the direct-mapped RO data objects after the clustered snapshot
513 // and then for ELF and assembly outputs, add appropriate sections with
514 // that combined data.
516 WriteROData(clustered_stream, vm);
517}
@ kOld
Definition heap.h:39
virtual void WriteROData(NonStreamingWriteStream *clustered_stream, bool vm)
virtual void WriteBss(bool vm)=0
void WriteText(bool vm)
static OneByteStringPtr New(intptr_t len, Heap::Space space)
Definition object.cc:24447
#define TIMELINE_DURATION(thread, stream, name)
Definition timeline.h:39

◆ WriteBss()

virtual void dart::ImageWriter::WriteBss ( bool  vm)
protectedpure virtual

Implemented in dart::BlobImageWriter.

◆ WriteBytes()

virtual intptr_t dart::ImageWriter::WriteBytes ( const void *  bytes,
intptr_t  size 
)
protectedpure virtual

Implemented in dart::BlobImageWriter.

◆ WriteFixed()

template<typename T >
intptr_t dart::ImageWriter::WriteFixed ( T  value)
inlineprotected

Definition at line 639 of file image_snapshot.h.

639 {
640 return WriteBytes(&value, sizeof(value));
641 }

◆ WriteROData()

void dart::ImageWriter::WriteROData ( NonStreamingWriteStream clustered_stream,
bool  vm 
)
protectedvirtual

Reimplemented in dart::BlobImageWriter.

Definition at line 519 of file image_snapshot.cc.

519 {
521 // Heap page starts here.
522 intptr_t section_start = stream->Position();
523
524 stream->WriteWord(next_data_offset_); // Data length.
525 stream->WriteWord(Image::kNoInstructionsSection);
526 // Zero values for the rest of the Image object header bytes.
527 stream->Align(Image::kHeaderSize);
528 ASSERT_EQUAL(stream->Position() - section_start, Image::kHeaderSize);
529#if defined(DART_PRECOMPILER)
530 if (profile_writer_ != nullptr) {
531 // Attribute the Image header to the artificial root.
534 }
535#endif
536
537 // Heap page objects start here.
538
539 for (auto entry : objects_) {
540 ASSERT(entry.is_object());
541 const Object& obj = *entry.obj;
542#if defined(DART_PRECOMPILER)
543 AutoTraceImage(obj, section_start, stream);
544 const char* object_name = namer_.SnapshotNameFor(entry);
545#endif
546 auto const object_start = stream->Position();
547
548 NoSafepointScope no_safepoint;
549
550 // Write object header with the mark and read-only bits set.
551 stream->WriteTargetWord(GetMarkedTags(obj));
552 if (obj.IsCompressedStackMaps()) {
553 const CompressedStackMaps& map = CompressedStackMaps::Cast(obj);
554 const intptr_t payload_size = map.payload_size();
555 stream->WriteFixed<uint32_t>(
556 map.ptr()->untag()->payload()->flags_and_size());
557 stream->WriteBytes(map.ptr()->untag()->payload()->data(), payload_size);
558 } else if (obj.IsCodeSourceMap()) {
559 const CodeSourceMap& map = CodeSourceMap::Cast(obj);
560 stream->WriteTargetWord(map.Length());
561 ASSERT_EQUAL(stream->Position() - object_start,
562 compiler::target::CodeSourceMap::HeaderSize());
563 stream->WriteBytes(map.Data(), map.Length());
564 } else if (obj.IsPcDescriptors()) {
565 const PcDescriptors& desc = PcDescriptors::Cast(obj);
566 stream->WriteTargetWord(desc.Length());
567 ASSERT_EQUAL(stream->Position() - object_start,
568 compiler::target::PcDescriptors::HeaderSize());
569 stream->WriteBytes(desc.ptr()->untag()->data(), desc.Length());
570 } else if (obj.IsString()) {
571 const String& str = String::Cast(obj);
572 RELEASE_ASSERT(String::GetCachedHash(str.ptr()) != 0);
573 RELEASE_ASSERT(str.IsOneByteString() || str.IsTwoByteString());
574
575#if !defined(HASH_IN_OBJECT_HEADER)
576 stream->WriteTargetWord(static_cast<uword>(str.ptr()->untag()->hash()));
577#endif
578 stream->WriteTargetWord(static_cast<uword>(str.ptr()->untag()->length()));
579 ASSERT_EQUAL(stream->Position() - object_start,
580 compiler::target::String::InstanceSize());
581 stream->WriteBytes(
582 str.IsOneByteString()
583 ? static_cast<const void*>(OneByteString::DataStart(str))
584 : static_cast<const void*>(TwoByteString::DataStart(str)),
585 str.Length() * (str.IsOneByteString()
586 ? OneByteString::kBytesPerElement
587 : TwoByteString::kBytesPerElement));
588 } else {
589 const Class& clazz = Class::Handle(obj.clazz());
590 FATAL("Unsupported class %s in rodata section.\n", clazz.ToCString());
591 }
593 ASSERT_EQUAL(stream->Position() - object_start, SizeInSnapshot(obj));
594#if defined(DART_PRECOMPILER)
595 AddDataSymbol(object_name, object_start, stream->Position() - object_start);
596#endif
597 }
598}
#define RELEASE_ASSERT(cond)
Definition assert.h:327
static constexpr intptr_t kRODataAlignment
static uint32_t GetCachedHash(const StringPtr obj)
Definition object.h:10424
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
Definition utils.h:77
static const ObjectId kArtificialRootId
void AttributeBytesTo(const ObjectId &object_id, size_t num_bytes)
SI auto map(std::index_sequence< I... >, Fn &&fn, const Args &... args) -> skvx::Vec< sizeof...(I), decltype(fn(args[0]...))>
Definition SkVx.h:680
static constexpr intptr_t kObjectAlignment

◆ WriteTargetWord()

virtual intptr_t dart::ImageWriter::WriteTargetWord ( word  value)
protectedpure virtual

Implemented in dart::BlobImageWriter.

◆ WriteText()

void dart::ImageWriter::WriteText ( bool  vm)
protected

Definition at line 695 of file image_snapshot.cc.

695 {
696 const bool bare_instruction_payloads = FLAG_precompiled_mode;
697
698 // Start snapshot at page boundary.
699 intptr_t alignment_padding = 0;
701 &alignment_padding)) {
702 return;
703 }
704
705 intptr_t text_offset = 0;
706#if defined(DART_PRECOMPILER)
707 // Parent used for later profile objects. Starts off as the Image. When
708 // writing bare instructions payloads, this is later updated with the
709 // InstructionsSection object which contains all the bare payloads.
710 V8SnapshotProfileWriter::ObjectId parent_id(offset_space_, text_offset);
711#endif
712
713 // This head also provides the gap to make the instructions snapshot
714 // look like a Page.
715 const intptr_t image_size = Utils::RoundUp(
717 text_offset += WriteTargetWord(image_size);
718 // Output the offset to the InstructionsSection object from the start of the
719 // image, if any.
720 text_offset +=
721 WriteTargetWord(FLAG_precompiled_mode ? Image::kHeaderSize
722 : Image::kNoInstructionsSection);
723 // Zero values for the rest of the Image object header bytes.
724 text_offset += Align(Image::kHeaderSize, 0, text_offset);
725 ASSERT_EQUAL(text_offset, Image::kHeaderSize);
726
727#if defined(DART_PRECOMPILER)
728 const char* instructions_symbol = SectionSymbol(ProgramSection::Text, vm);
729 ASSERT(instructions_symbol != nullptr);
730 intptr_t instructions_label = SectionLabel(ProgramSection::Text, vm);
731 ASSERT(instructions_label > 0);
732 const char* bss_symbol = SectionSymbol(ProgramSection::Bss, vm);
733 ASSERT(bss_symbol != nullptr);
734 intptr_t bss_label = SectionLabel(ProgramSection::Bss, vm);
735 ASSERT(bss_label > 0);
736
737 if (profile_writer_ != nullptr) {
739 instructions_symbol);
741 parent_id, ImageWriter::kTextAlignment + alignment_padding);
742 profile_writer_->AddRoot(parent_id);
743 }
744
745 if (FLAG_precompiled_mode) {
746 const intptr_t section_header_length =
747 compiler::target::InstructionsSection::HeaderSize();
748 // Calculated using next_text_offset_, which doesn't include post-payload
749 // padding to object alignment. Note that if not in bare instructions mode,
750 // the section has no contents, instead the instructions objects follow it.
751 const intptr_t section_payload_length =
752 bare_instruction_payloads
753 ? next_text_offset_ - text_offset - section_header_length
754 : 0;
755 const intptr_t section_size =
756 compiler::target::InstructionsSection::InstanceSize(
757 section_payload_length);
758
759 const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
760 if (profile_writer_ != nullptr) {
762 instructions_symbol);
764 section_size - section_payload_length);
765 const intptr_t element_offset = id.nonce() - parent_id.nonce();
767 parent_id,
769 // Later objects will have the InstructionsSection as a parent if in
770 // bare instructions mode, otherwise the image.
771 if (bare_instruction_payloads) {
772 parent_id = id;
773 }
774 }
775
776 // Add the RawInstructionsSection header.
777 text_offset +=
778 WriteTargetWord(GetMarkedTags(kInstructionsSectionCid, section_size));
779 // An InstructionsSection has five fields:
780 // 1) The length of the payload.
781 text_offset += WriteTargetWord(section_payload_length);
782 // 2) The BSS offset from this section.
783 text_offset += Relocation(text_offset, instructions_label, bss_label);
784 // 3) The relocated address of the instructions.
785 text_offset += RelocatedAddress(text_offset, instructions_label);
786 // 4) The GNU build ID note offset from this section.
787 text_offset += Relocation(text_offset, instructions_label,
788 SectionLabel(ProgramSection::BuildId, vm));
789
790 const intptr_t section_contents_alignment =
791 bare_instruction_payloads
794 const intptr_t alignment_offset =
796 const intptr_t expected_size =
797 bare_instruction_payloads
798 ? compiler::target::InstructionsSection::HeaderSize()
799 : compiler::target::InstructionsSection::InstanceSize(0);
800 text_offset +=
801 Align(section_contents_alignment, alignment_offset, text_offset);
802 ASSERT_EQUAL(text_offset - id.nonce(), expected_size);
803 }
804#endif
805
806#if !defined(EMIT_UNWIND_DIRECTIVES_PER_FUNCTION)
808#endif
809
810#if defined(DART_PRECOMPILER)
811 PcDescriptors& descriptors = PcDescriptors::Handle(zone_);
812#endif
813
814 // We don't expect more than 64 bytes of padding.
815 uint8_t padding_bytes[64];
816 memset(&padding_bytes[0], 0, sizeof(padding_bytes));
817
819 for (intptr_t i = 0; i < instructions_.length(); i++) {
820 auto& data = instructions_[i];
821 const bool is_trampoline = data.trampoline_bytes != nullptr;
822 const bool is_padding =
823 data.trampoline_bytes == nullptr && data.trampoline_length != 0;
824 ASSERT_EQUAL(data.text_offset_, text_offset);
825
826#if defined(DART_PRECOMPILER)
827 const char* object_name = namer_.SnapshotNameFor(data);
828
829 if (profile_writer_ != nullptr) {
830 const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
831 auto const type = is_trampoline ? trampoline_type_
832 : is_padding ? padding_type_
834 const intptr_t size = (is_trampoline || is_padding)
835 ? data.trampoline_length
836 : SizeInSnapshot(data.insns_->ptr());
837 profile_writer_->SetObjectTypeAndName(id, type, object_name);
839 const intptr_t element_offset = id.nonce() - parent_id.nonce();
841 parent_id,
843 }
844#endif
845
846 if (is_trampoline) {
847 text_offset += WriteBytes(data.trampoline_bytes, data.trampoline_length);
848 delete[] data.trampoline_bytes;
849 data.trampoline_bytes = nullptr;
850 continue;
851 }
852
853 if (is_padding) {
854 text_offset += WriteBytes(padding_bytes, data.trampoline_length);
855 continue;
856 }
857
858 const intptr_t instr_start = text_offset;
859 const auto& insns = *data.insns_;
860
861 // 1. Write from the object start to the payload start. This includes the
862 // object header and the fixed fields. Not written for AOT snapshots using
863 // bare instructions.
864 if (!bare_instruction_payloads) {
865 NoSafepointScope no_safepoint;
866
867 // Write Instructions with the mark and read-only bits set.
868 text_offset += WriteTargetWord(GetMarkedTags(insns));
869 text_offset += WriteFixed(insns.untag()->size_and_flags_);
870 text_offset +=
871 Align(compiler::target::Instructions::kNonBarePayloadAlignment,
873 text_offset);
874 }
875
876 ASSERT_EQUAL(text_offset - instr_start,
877 compiler::target::Instructions::HeaderSize());
878
879#if defined(DART_PRECOMPILER)
880 const auto& code = *data.code_;
881 // 2. Add a symbol for the code at the entry point in precompiled snapshots.
882 // Linux's perf uses these labels.
883 AddCodeSymbol(code, object_name, text_offset);
884#endif
885
886#if defined(EMIT_UNWIND_DIRECTIVES_PER_FUNCTION)
888#endif
889
890 {
891 NoSafepointScope no_safepoint;
892
893 // 3. Write from the payload start to payload end. For AOT snapshots
894 // with bare instructions, this is the only part serialized other than
895 // any padding needed for alignment.
896 auto const payload_start =
897 reinterpret_cast<const uint8_t*>(insns.PayloadStart());
898 // Double-check the payload alignment, since we will load and write
899 // target-sized words starting from that address.
900 ASSERT(Utils::IsAligned(payload_start, compiler::target::kWordSize));
901 const uword payload_size = insns.Size();
902 auto const payload_end = payload_start + payload_size;
903 auto cursor = payload_start;
904#if defined(DART_PRECOMPILER)
905 descriptors = code.pc_descriptors();
906 PcDescriptors::Iterator iterator(
907 descriptors, /*kind_mask=*/UntaggedPcDescriptors::kBSSRelocation);
908 while (iterator.MoveNext()) {
909 // We only generate BSS relocations in the precompiler.
910 ASSERT(FLAG_precompiled_mode);
911 auto const next_reloc_offset = iterator.PcOffset();
912 auto const next_reloc_address = payload_start + next_reloc_offset;
913 // We only generate BSS relocations that are target word-sized and at
914 // target word-aligned offsets in the payload. Double-check this.
915 ASSERT(
916 Utils::IsAligned(next_reloc_address, compiler::target::kWordSize));
917 text_offset += WriteBytes(cursor, next_reloc_address - cursor);
918
919 // The instruction stream at the relocation position holds the target
920 // offset into the BSS section.
921 const auto target_offset =
922 *reinterpret_cast<const compiler::target::word*>(
923 next_reloc_address);
924 text_offset += Relocation(text_offset, instructions_label, text_offset,
925 bss_label, target_offset);
926 cursor = next_reloc_address + compiler::target::kWordSize;
927 }
928#endif
929 text_offset += WriteBytes(cursor, payload_end - cursor);
930 }
931
932 // 4. Add appropriate padding. Note we can't simply copy from the object
933 // because the host object may have less alignment filler than the target
934 // object in the cross-word case.
935 const intptr_t alignment =
936 bare_instruction_payloads
937 ? compiler::target::Instructions::kBarePayloadAlignment
939 text_offset += AlignWithBreakInstructions(alignment, text_offset);
940
941 ASSERT_EQUAL(text_offset - instr_start, SizeInSnapshot(insns.ptr()));
942#if defined(EMIT_UNWIND_DIRECTIVES_PER_FUNCTION)
944#endif
945 }
946
947 // Should be a no-op unless writing bare instruction payloads, in which case
948 // we need to add post-payload padding for the InstructionsSection object.
949 // Since this follows instructions, we'll use break instructions for padding.
950 ASSERT(bare_instruction_payloads ||
951 Utils::IsAligned(text_offset,
953 text_offset += AlignWithBreakInstructions(
955
956 ASSERT_EQUAL(text_offset, image_size);
957
958#if !defined(EMIT_UNWIND_DIRECTIVES_PER_FUNCTION)
960#endif
961
962 ExitSection(ProgramSection::Text, vm, text_offset);
963}
Align
virtual void FrameUnwindEpilogue()=0
intptr_t WriteFixed(T value)
virtual void FrameUnwindPrologue()=0
intptr_t AlignWithBreakInstructions(intptr_t alignment, intptr_t offset)
virtual void ExitSection(ProgramSection name, bool vm, intptr_t size)=0
static constexpr intptr_t kTextAlignment
virtual bool EnterSection(ProgramSection name, bool vm, intptr_t alignment, intptr_t *alignment_padding=nullptr)=0
static const char * SectionSymbol(ProgramSection section, bool vm)
static constexpr intptr_t kPayloadAlignment
Definition object.h:5916
void AttributeReferenceTo(const ObjectId &from_object_id, const Reference &reference, const ObjectId &to_object_id)
void SetObjectTypeAndName(const ObjectId &object_id, const char *type, const char *name)
void AddRoot(const ObjectId &object_id, const char *name=nullptr)
uint32_t * target
CanvasImage Image
Definition dart_ui.cc:55
static constexpr intptr_t kOldObjectAlignmentOffset
static Reference Element(intptr_t offset)
const uintptr_t id

Friends And Related Symbol Documentation

◆ TraceImageObjectScope

template<class T >
friend class TraceImageObjectScope
friend

Definition at line 724 of file image_snapshot.h.

Member Data Documentation

◆ image_type_

const char* const dart::ImageWriter::image_type_
protected

Definition at line 717 of file image_snapshot.h.

◆ instructions_

GrowableArray<InstructionsData> dart::ImageWriter::instructions_
protected

Definition at line 651 of file image_snapshot.h.

◆ instructions_section_type_

const char* const dart::ImageWriter::instructions_section_type_
protected

Definition at line 718 of file image_snapshot.h.

◆ instructions_type_

const char* const dart::ImageWriter::instructions_type_
protected

Definition at line 719 of file image_snapshot.h.

◆ kBssAlignment

constexpr intptr_t dart::ImageWriter::kBssAlignment = compiler::target::kWordSize
staticconstexpr

Definition at line 380 of file image_snapshot.h.

◆ kNumProgramSections

constexpr intptr_t dart::ImageWriter::kNumProgramSections
staticconstexpr
Initial value:
=
static_cast<int>(ProgramSection::BuildId) + 1

Definition at line 454 of file image_snapshot.h.

◆ kRODataAlignment

constexpr intptr_t dart::ImageWriter::kRODataAlignment = kObjectStartAlignment
staticconstexpr

Definition at line 382 of file image_snapshot.h.

◆ kTextAlignment

constexpr intptr_t dart::ImageWriter::kTextAlignment = kObjectStartAlignment
staticconstexpr

Definition at line 385 of file image_snapshot.h.

◆ next_data_offset_

intptr_t dart::ImageWriter::next_data_offset_
protected

Definition at line 648 of file image_snapshot.h.

◆ next_text_offset_

intptr_t dart::ImageWriter::next_text_offset_
protected

Definition at line 649 of file image_snapshot.h.

◆ objects_

GrowableArray<ObjectData> dart::ImageWriter::objects_
protected

Definition at line 650 of file image_snapshot.h.

◆ offset_space_

IdSpace dart::ImageWriter::offset_space_ = IdSpace::kSnapshot
protected

Definition at line 715 of file image_snapshot.h.

◆ padding_type_

const char* const dart::ImageWriter::padding_type_
protected

Definition at line 721 of file image_snapshot.h.

◆ profile_writer_

V8SnapshotProfileWriter* dart::ImageWriter::profile_writer_ = nullptr
protected

Definition at line 716 of file image_snapshot.h.

◆ thread_

Thread* const dart::ImageWriter::thread_
protected

Definition at line 646 of file image_snapshot.h.

◆ trampoline_type_

const char* const dart::ImageWriter::trampoline_type_
protected

Definition at line 720 of file image_snapshot.h.

◆ zone_

Zone* const dart::ImageWriter::zone_
protected

Definition at line 647 of file image_snapshot.h.


The documentation for this class was generated from the following files: