27 return heap->old_space()->ContainsUnsafe(
ToAddr(
this));
32 if (!IsHeapObject()) {
37 FATAL(
"RAW_NULL encountered");
52 FATAL(
"New object missing kNewBit: %" Px "\n",
tags);
55 FATAL(
"New object has kOldAndNotRememberedBit: %" Px "\n",
tags);
64 FATAL(
"Invalid class id encountered %" Pd "\n", class_id);
72 intptr_t size_from_class = HeapSizeFromClass(
tags);
73 if ((size_from_tags != 0) && (size_from_tags != size_from_class)) {
75 "Inconsistent size encountered "
76 "cid: %" Pd ", size_from_tags: %" Pd ", size_from_class: %" Pd "\n",
77 class_id, size_from_tags, size_from_class);
85intptr_t UntaggedObject::HeapSizeFromClass(
uword tags)
const {
87 intptr_t instance_size = 0;
90 const CodePtr raw_code =
static_cast<const CodePtr
>(
this);
91 intptr_t pointer_offsets_length =
96 case kInstructionsCid: {
97 const InstructionsPtr raw_instructions =
98 static_cast<const InstructionsPtr
>(
this);
103 case kInstructionsSectionCid: {
104 const InstructionsSectionPtr raw_section =
105 static_cast<const InstructionsSectionPtr
>(
this);
111 const ContextPtr raw_context =
static_cast<const ContextPtr
>(
this);
112 intptr_t num_variables = raw_context->untag()->num_variables_;
116 case kContextScopeCid: {
117 const ContextScopePtr raw_context_scope =
118 static_cast<const ContextScopePtr
>(
this);
119 intptr_t num_variables = raw_context_scope->untag()->num_variables_;
123 case kOneByteStringCid: {
124 const OneByteStringPtr raw_string =
125 static_cast<const OneByteStringPtr
>(
this);
126 intptr_t string_length =
Smi::Value(raw_string->untag()->length());
130 case kTwoByteStringCid: {
131 const TwoByteStringPtr raw_string =
132 static_cast<const TwoByteStringPtr
>(
this);
133 intptr_t string_length =
Smi::Value(raw_string->untag()->length());
138 case kImmutableArrayCid: {
139 const ArrayPtr raw_array =
static_cast<const ArrayPtr
>(
this);
140 intptr_t array_length =
141 Smi::Value(raw_array->untag()->length<std::memory_order_acquire>());
145 case kWeakArrayCid: {
146 const WeakArrayPtr raw_array =
static_cast<const WeakArrayPtr
>(
this);
147 intptr_t array_length =
Smi::Value(raw_array->untag()->length());
151 case kObjectPoolCid: {
152 const ObjectPoolPtr raw_object_pool =
153 static_cast<const ObjectPoolPtr
>(
this);
154 intptr_t
len = raw_object_pool->untag()->length_;
159 const RecordPtr raw_record =
static_cast<const RecordPtr
>(
this);
160 intptr_t num_fields =
161 RecordShape(raw_record->untag()->shape()).num_fields();
165#define SIZE_FROM_CLASS(clazz) case kTypedData##clazz##Cid:
167 const TypedDataPtr raw_obj =
static_cast<const TypedDataPtr
>(
this);
168 intptr_t array_len =
Smi::Value(raw_obj->untag()->length());
169 intptr_t lengthInBytes =
174#undef SIZE_FROM_CLASS
178 case kSuspendStateCid: {
179 const SuspendStatePtr raw_suspend_state =
180 static_cast<const SuspendStatePtr
>(
this);
181 intptr_t frame_capacity = raw_suspend_state->untag()->frame_capacity();
185 case kTypeArgumentsCid: {
186 const TypeArgumentsPtr raw_array =
187 static_cast<const TypeArgumentsPtr
>(
this);
188 intptr_t array_length =
Smi::Value(raw_array->untag()->length());
192 case kPcDescriptorsCid: {
193 const PcDescriptorsPtr raw_descriptors =
194 static_cast<const PcDescriptorsPtr
>(
this);
195 intptr_t
length = raw_descriptors->untag()->length_;
199 case kCodeSourceMapCid: {
200 const CodeSourceMapPtr raw_code_source_map =
201 static_cast<const CodeSourceMapPtr
>(
this);
202 intptr_t
length = raw_code_source_map->untag()->length_;
206 case kCompressedStackMapsCid: {
207 const CompressedStackMapsPtr maps =
208 static_cast<const CompressedStackMapsPtr
>(
this);
213 case kLocalVarDescriptorsCid: {
214 const LocalVarDescriptorsPtr raw_descriptors =
215 static_cast<const LocalVarDescriptorsPtr
>(
this);
216 intptr_t num_descriptors = raw_descriptors->untag()->num_entries_;
220 case kExceptionHandlersCid: {
221 const ExceptionHandlersPtr raw_handlers =
222 static_cast<const ExceptionHandlersPtr
>(
this);
223 intptr_t num_handlers = raw_handlers->untag()->num_entries();
230 instance_size = element->HeapSize(
tags);
235 ForwardingCorpse* element =
reinterpret_cast<ForwardingCorpse*
>(
addr);
236 instance_size = element->HeapSize(
tags);
239 case kWeakSerializationReferenceCid: {
248 auto class_table = isolate_group->heap_walk_class_table();
249 if (!class_table->IsValidIndex(class_id) ||
250 !class_table->HasValidClassAt(class_id)) {
251 FATAL(
"Invalid cid: %" Pd ", obj: %p, tags: %x. Corrupt heap?",
252 class_id,
this,
static_cast<uint32_t
>(
tags));
254 ASSERT(class_table->SizeAt(class_id) > 0);
256 instance_size = isolate_group->heap_walk_class_table()->SizeAt(class_id);
259 ASSERT(instance_size != 0);
262 if ((class_id == kArrayCid) && (instance_size > tags_size && tags_size > 0)) {
266 int retries_remaining = 1000;
269 const ArrayPtr raw_array =
static_cast<const ArrayPtr
>(
this);
270 intptr_t array_length =
Smi::Value(raw_array->untag()->length());
272 }
while ((instance_size > tags_size) && (--retries_remaining > 0));
274 if ((instance_size != tags_size) && (tags_size != 0)) {
275 FATAL(
"Size mismatch: %" Pd " from class vs %" Pd " from tags %" Px "\n",
276 instance_size, tags_size,
tags);
279 return instance_size;
282intptr_t UntaggedObject::VisitPointersPredefined(ObjectPointerVisitor* visitor,
289#define RAW_VISITPOINTERS(clazz) \
290 case k##clazz##Cid: { \
291 clazz##Ptr raw_obj = static_cast<clazz##Ptr>(this); \
292 size = Untagged##clazz::Visit##clazz##Pointers(raw_obj, visitor); \
296#undef RAW_VISITPOINTERS
297#define RAW_VISITPOINTERS(clazz) case kTypedData##clazz##Cid:
299 TypedDataPtr raw_obj =
static_cast<TypedDataPtr
>(
this);
300 size = UntaggedTypedData::VisitTypedDataPointers(raw_obj, visitor);
303#undef RAW_VISITPOINTERS
304#define RAW_VISITPOINTERS(clazz) case kExternalTypedData##clazz##Cid:
306 auto raw_obj =
static_cast<ExternalTypedDataPtr
>(
this);
307 size = UntaggedExternalTypedData::VisitExternalTypedDataPointers(raw_obj,
311#undef RAW_VISITPOINTERS
314#define RAW_VISITPOINTERS(clazz) \
315 case kTypedData##clazz##ViewCid: \
316 case kUnmodifiableTypedData##clazz##ViewCid:
318 auto raw_obj =
static_cast<TypedDataViewPtr
>(
this);
320 UntaggedTypedDataView::VisitTypedDataViewPointers(raw_obj, visitor);
323#undef RAW_VISITPOINTERS
325 InstancePtr raw_obj =
static_cast<InstancePtr
>(
this);
326 size = UntaggedInstance::VisitInstancePointers(raw_obj, visitor);
329#define RAW_VISITPOINTERS(clazz) case kFfi##clazz##Cid:
335#undef RAW_VISITPOINTERS
339 size = element->HeapSize();
344 ForwardingCorpse* forwarder =
reinterpret_cast<ForwardingCorpse*
>(
addr);
345 size = forwarder->HeapSize();
353 FATAL(
"Invalid cid: %" Pd ", obj: %p, tags: %x. Corrupt heap?", class_id,
354 this,
static_cast<uint32_t
>(tags_));
360 const intptr_t expected_size =
HeapSize();
367 ASSERT(size == expected_size ||
368 (class_id == kArrayCid && size > expected_size));
378 VisitPointersPredefined(visitor, class_id);
386 ->host_next_field_offset_in_words_
388 ASSERT(next_field_offset > 0);
395 const auto unboxed_fields_bitmap =
398 if (!unboxed_fields_bitmap.IsEmpty()) {
401 if (!unboxed_fields_bitmap.Get(bit++)) {
413#define REGULAR_VISITOR(Type) \
414 intptr_t Untagged##Type::Visit##Type##Pointers( \
415 Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
417 ASSERT(raw_obj->IsHeapObject()); \
418 ASSERT_UNCOMPRESSED(Type); \
419 visitor->VisitPointers(raw_obj->untag()->from(), raw_obj->untag()->to()); \
420 return Type::InstanceSize(); \
423#if !defined(DART_COMPRESSED_POINTERS)
424#define COMPRESSED_VISITOR(Type) REGULAR_VISITOR(Type)
426#define COMPRESSED_VISITOR(Type) \
427 intptr_t Untagged##Type::Visit##Type##Pointers( \
428 Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
430 ASSERT(raw_obj->IsHeapObject()); \
431 ASSERT_COMPRESSED(Type); \
432 visitor->VisitCompressedPointers(raw_obj->heap_base(), \
433 raw_obj->untag()->from(), \
434 raw_obj->untag()->to()); \
435 return Type::InstanceSize(); \
444#define TYPED_DATA_VIEW_VISITOR(Type) \
445 intptr_t Untagged##Type::Visit##Type##Pointers( \
446 Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
448 ASSERT(raw_obj->IsHeapObject()); \
449 ASSERT_COMPRESSED(Type); \
450 visitor->VisitTypedDataViewPointers(raw_obj, raw_obj->untag()->from(), \
451 raw_obj->untag()->to()); \
452 return Type::InstanceSize(); \
457#define VARIABLE_VISITOR(Type, get_length) \
458 intptr_t Untagged##Type::Visit##Type##Pointers( \
459 Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
461 ASSERT(raw_obj->IsHeapObject()); \
462 intptr_t length = get_length; \
463 visitor->VisitPointers(raw_obj->untag()->from(), \
464 raw_obj->untag()->to(length)); \
465 return Type::InstanceSize(length); \
468#if !defined(DART_COMPRESSED_POINTERS)
469#define VARIABLE_COMPRESSED_VISITOR(Type, get_length) \
470 VARIABLE_VISITOR(Type, get_length)
472#define VARIABLE_COMPRESSED_VISITOR(Type, get_length) \
473 intptr_t Untagged##Type::Visit##Type##Pointers( \
474 Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
476 ASSERT(raw_obj->IsHeapObject()); \
477 intptr_t length = get_length; \
478 visitor->VisitCompressedPointers(raw_obj->heap_base(), \
479 raw_obj->untag()->from(), \
480 raw_obj->untag()->to(length)); \
481 return Type::InstanceSize(length); \
486#define NULL_VISITOR(Type) \
487 intptr_t Untagged##Type::Visit##Type##Pointers( \
488 Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
490 ASSERT(raw_obj->IsHeapObject()); \
491 ASSERT_NOTHING_TO_VISIT(Type); \
492 return Type::InstanceSize(); \
497#define VARIABLE_NULL_VISITOR(Type, get_length) \
498 intptr_t Untagged##Type::Visit##Type##Pointers( \
499 Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
501 ASSERT(raw_obj->IsHeapObject()); \
502 ASSERT_NOTHING_TO_VISIT(Type); \
503 intptr_t length = get_length; \
504 return Type::InstanceSize(length); \
508#define UNREACHABLE_VISITOR(Type) \
509 intptr_t Untagged##Type::Visit##Type##Pointers( \
510 Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
567 TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *
608 ASSERT(raw_obj->IsHeapObject());
610 visitor->VisitCompressedPointers(
611 raw_obj->heap_base(), raw_obj->untag()->from(), raw_obj->untag()->to());
613 if (visitor->trace_values_through_fields()) {
615 visitor->isolate_group()->ForEachIsolate(
618 Smi::Value(raw_obj->untag()->host_offset_or_field_id());
627intptr_t UntaggedSuspendState::VisitSuspendStatePointers(
628 SuspendStatePtr raw_obj,
629 ObjectPointerVisitor* visitor) {
630 ASSERT(raw_obj->IsHeapObject());
633 if (visitor->CanVisitSuspendStatePointers(raw_obj)) {
634 visitor->VisitCompressedPointers(
635 raw_obj->heap_base(), raw_obj->untag()->from(), raw_obj->untag()->to());
637 const uword pc = raw_obj->untag()->pc_;
640 ASSERT(thread !=
nullptr);
641 ASSERT(thread->isolate_group() == visitor->isolate_group());
642 const uword sp =
reinterpret_cast<uword>(raw_obj->untag()->payload());
643 StackFrame
frame(thread);
646 frame.fp_ = sp + raw_obj->untag()->frame_size_;
647 frame.VisitObjectPointers(visitor);
654bool UntaggedCode::ContainsPC(
const ObjectPtr raw_obj,
uword pc) {
655 if (!raw_obj->IsCode())
return false;
656 auto const raw_code =
static_cast<const CodePtr
>(raw_obj);
662intptr_t UntaggedCode::VisitCodePointers(CodePtr raw_obj,
663 ObjectPointerVisitor* visitor) {
664 visitor->VisitPointers(raw_obj->untag()->from(), raw_obj->untag()->to());
666 UntaggedCode* obj = raw_obj->untag();
668#if defined(TARGET_ARCH_IA32)
674 for (intptr_t i = 0; i <
length; i++) {
675 int32_t
offset = obj->data()[i];
676 visitor->VisitPointer(
reinterpret_cast<ObjectPtr*
>(entry_point +
offset));
688intptr_t UntaggedObjectPool::VisitObjectPoolPointers(
689 ObjectPoolPtr raw_obj,
690 ObjectPointerVisitor* visitor) {
691 const intptr_t
length = raw_obj->untag()->length_;
692 UntaggedObjectPool::Entry* entries = raw_obj->untag()->data();
693 uint8_t* entry_bits = raw_obj->untag()->entry_bits();
694 for (intptr_t i = 0; i <
length; ++i) {
697 if (entry_type == ObjectPool::EntryType::kTaggedObject) {
698 visitor->VisitPointer(&entries[i].raw_obj_);
704bool UntaggedInstructions::ContainsPC(
const InstructionsPtr raw_instr,
714intptr_t UntaggedInstance::VisitInstancePointers(
716 ObjectPointerVisitor* visitor) {
718 ASSERT(raw_obj->IsHeapObject());
720 intptr_t instance_size = SizeTag::decode(
tags);
721 if (instance_size == 0) {
722 instance_size = visitor->class_table()->SizeAt(raw_obj->GetClassId());
727 uword from = obj_addr +
sizeof(UntaggedObject);
729 visitor->VisitCompressedPointers(raw_obj->heap_base(),
732 return instance_size;
735intptr_t UntaggedImmutableArray::VisitImmutableArrayPointers(
736 ImmutableArrayPtr raw_obj,
737 ObjectPointerVisitor* visitor) {
738 return UntaggedArray::VisitArrayPointers(raw_obj, visitor);
741intptr_t UntaggedConstMap::VisitConstMapPointers(
743 ObjectPointerVisitor* visitor) {
744 return UntaggedMap::VisitMapPointers(raw_obj, visitor);
747intptr_t UntaggedConstSet::VisitConstSetPointers(
749 ObjectPointerVisitor* visitor) {
750 return UntaggedSet::VisitSetPointers(raw_obj, visitor);
753void UntaggedObject::RememberCard(ObjectPtr
const* slot) {
757#if defined(DART_COMPRESSED_POINTERS)
769 ASSERT(object->IsOldObject());
777#define ENUM_CASE(name, init) \
778 case Kind::k##name: \
788 ASSERT(cstr !=
nullptr && out !=
nullptr);
789#define ENUM_CASE(name, init) \
790 if (strcmp(#name, cstr) == 0) { \
791 *out = Kind::k##name; \
#define CLASS_LIST_NO_OBJECT(V)
#define CLASS_LIST_FFI_TYPE_MARKER(V)
#define CLASS_LIST_TYPED_DATA(V)
static intptr_t InstanceSize()
static constexpr bool decode(uword value)
ClassPtr At(intptr_t cid) const
bool IsValidIndex(intptr_t cid) const
UnboxedFieldBitmap GetUnboxedFieldsMapAt(intptr_t cid) const
bool HasValidClassAt(intptr_t cid) const
static intptr_t InstanceSize()
static uword PayloadSizeOf(const CodePtr code)
static intptr_t InstanceSize()
static uword PayloadStartOf(const CodePtr code)
static intptr_t InstanceSize()
static uintptr_t PayloadSizeOf(const CompressedStackMapsPtr raw)
static intptr_t InstanceSize()
static intptr_t InstanceSize()
static IsolateGroup * vm_isolate_group()
static intptr_t InstanceSize()
static intptr_t InstanceSize()
static intptr_t InstanceSize()
static intptr_t Size(const InstructionsSectionPtr instr)
static intptr_t InstanceSize()
uword PayloadStart() const
static IsolateGroup * Current()
ClassTable * class_table() const
FieldTable * field_table() const
static intptr_t InstanceSize()
static void Sleep(int64_t millis)
const ClassTable * class_table() const
void VisitCompressedPointers(uword heap_base, CompressedObjectPtr *first, CompressedObjectPtr *last)
compiler::ObjectPoolBuilderEntry::EntryType EntryType
static intptr_t InstanceSize()
void Validate(IsolateGroup *isolate_group) const
UntaggedObject * untag() const
static intptr_t InstanceSize()
static Page * Of(ObjectPtr obj)
void RememberCard(ObjectPtr const *slot)
static intptr_t InstanceSize()
static intptr_t InstanceSize()
static intptr_t InstanceSize()
static intptr_t InstanceSize()
static Thread * Current()
static intptr_t InstanceSize()
static intptr_t InstanceSize()
intptr_t ElementSizeInBytes() const
static intptr_t InstanceSize()
static constexpr uword decode(uword tag)
void Validate(IsolateGroup *isolate_group) const
bool IsCardRemembered() const
static uword ToAddr(const UntaggedObject *raw_obj)
intptr_t HeapSize() const
bool InVMIsolateHeap() const
void VisitPointersPrecise(ObjectPointerVisitor *visitor)
intptr_t GetClassId() const
friend class FreeListElement
static const char * KindToCString(Kind k)
static bool ParseKind(const char *cstr, Kind *out)
static intptr_t InstanceSize()
static intptr_t InstanceSize()
static constexpr intptr_t kCompressedWordSizeLog2
@ kUnmodifiableByteDataViewCid
static constexpr intptr_t kCompressedWordSize
raw_obj untag() -> num_entries()) VARIABLE_COMPRESSED_VISITOR(Array, Smi::Value(raw_obj->untag() ->length())) VARIABLE_COMPRESSED_VISITOR(TypedData, TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *Smi::Value(raw_obj->untag() ->length())) VARIABLE_COMPRESSED_VISITOR(Record, RecordShape(raw_obj->untag() ->shape()).num_fields()) VARIABLE_NULL_VISITOR(CompressedStackMaps, CompressedStackMaps::PayloadSizeOf(raw_obj)) VARIABLE_NULL_VISITOR(OneByteString, Smi::Value(raw_obj->untag() ->length())) VARIABLE_NULL_VISITOR(TwoByteString, Smi::Value(raw_obj->untag() ->length())) intptr_t UntaggedField::VisitFieldPointers(FieldPtr raw_obj, ObjectPointerVisitor *visitor)
ObjectPtr CompressedObjectPtr
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
#define SIZE_FROM_CLASS(clazz)
#define TYPED_DATA_VIEW_VISITOR(Type)
#define COMPRESSED_VISITOR(Type)
#define VARIABLE_COMPRESSED_VISITOR(Type, get_length)
#define REGULAR_VISITOR(Type)
#define ENUM_CASE(name, init)
#define RAW_VISITPOINTERS(clazz)
#define NULL_VISITOR(Type)
#define UNREACHABLE_VISITOR(Type)
#define VARIABLE_NULL_VISITOR(Type, get_length)
#define FOR_EACH_RAW_PC_DESCRIPTOR(V)
#define ASSERT_COMPRESSED(Type)
#define END_LEAF_RUNTIME_ENTRY
#define DEFINE_LEAF_RUNTIME_ENTRY(type, name, argument_count,...)