328 {
329 Thread::Current()->long_jump_base()->Jump(1, Object::branch_offset_error());
330}
331
332word RuntimeEntry::OffsetFromThread()
const {
333 return target::Thread::OffsetFromThread(runtime_entry_);
334}
335
336bool RuntimeEntry::is_leaf() const {
337 return runtime_entry_->is_leaf();
338}
339
340intptr_t RuntimeEntry::argument_count() const {
341 return runtime_entry_->argument_count();
342}
343
345
349
353}
354
358}
359
369}
370
371word Object::tags_offset() {
372 return 0;
373}
374
375const word UntaggedObject::kCardRememberedBit =
377
379
381
382const word UntaggedObject::kOldAndNotRememberedBit =
384
386
388
390
392
393const word UntaggedObject::kClassIdTagPos =
395
396const word UntaggedObject::kClassIdTagSize =
398
400
402
403const word UntaggedObject::kSizeTagMaxSizeTag =
405 ObjectAlignment::kObjectAlignment;
406
407const word UntaggedObject::kTagBitsSizeTagPos =
409
410const word UntaggedAbstractType::kTypeStateFinalizedInstantiated =
412const word UntaggedAbstractType::kTypeStateShift =
414const word UntaggedAbstractType::kTypeStateBits =
416const word UntaggedAbstractType::kNullabilityMask =
418
419const word UntaggedType::kTypeClassIdShift =
421
422const word UntaggedTypeParameter::kIsFunctionTypeParameterBit =
424
425const word UntaggedObject::kBarrierOverlapShift =
427
428const word UntaggedObject::kGenerationalBarrierMask =
430
431const word UntaggedObject::kIncrementalBarrierMask =
433
436}
437
439
442}
443
447}
448
450 switch (handle.
id()) {
451 case kMintCid:
452 return Mint::InstanceSize();
453 case kDoubleCid:
454 return Double::InstanceSize();
455 case kInt32x4Cid:
456 return Int32x4::InstanceSize();
457 case kFloat32x4Cid:
458 return Float32x4::InstanceSize();
459 case kFloat64x2Cid:
460 return Float64x2::InstanceSize();
461 case kObjectCid:
462 return Object::InstanceSize();
463 case kInstanceCid:
464 return Instance::InstanceSize();
465 case kGrowableObjectArrayCid:
466 return GrowableObjectArray::InstanceSize();
467 case kClosureCid:
468 return Closure::InstanceSize();
469 case kTypedDataBaseCid:
470 return TypedDataBase::InstanceSize();
471 case kMapCid:
472 return Map::InstanceSize();
473 case kSetCid:
474 return Set::InstanceSize();
475 case kUnhandledExceptionCid:
476 return UnhandledException::InstanceSize();
477 case kWeakPropertyCid:
478 return WeakProperty::InstanceSize();
479 case kWeakReferenceCid:
480 return WeakReference::InstanceSize();
481 case kFinalizerCid:
482 return Finalizer::InstanceSize();
483 case kFinalizerEntryCid:
484 return FinalizerEntry::InstanceSize();
485 case kNativeFinalizerCid:
486 return NativeFinalizer::InstanceSize();
490 case kPointerCid:
491 case kDynamicLibraryCid:
492#define HANDLE_CASE(clazz) case kFfi##clazz##Cid:
494#undef HANDLE_CASE
495#define HANDLE_CASE(clazz) \
496 case kTypedData##clazz##Cid: \
497 case kTypedData##clazz##ViewCid: \
498 case kExternalTypedData##clazz##Cid: \
499 case kUnmodifiableTypedData##clazz##ViewCid:
501#undef HANDLE_CASE
503 default:
504 if (handle.
id() >= kNumPredefinedCids) {
506 }
507 }
508 FATAL(
"Unsupported class for size translation: %s (id=%" Pd
509 ", kNumPredefinedCids=%" Pd ")\n",
510 handle.
ToCString(), handle.
id(), kNumPredefinedCids);
511 return -1;
512}
513
516 ObjectAlignment::kObjectAlignment);
517}
518
519
520
521
522
523
524
525bool Class::HasCompressedPointers(
const dart::Class& handle) {
527}
528
529intptr_t Class::NumTypeArguments(
const dart::Class& klass) {
531}
532
533bool Class::HasTypeArgumentsField(
const dart::Class& klass) {
536}
537
538intptr_t Class::TypeArgumentsFieldOffset(
const dart::Class& klass) {
540}
541
542bool Class::TraceAllocation(
const dart::Class& klass) {
544}
545
546word Instance::first_field_offset() {
548}
549
550word Instance::native_fields_array_offset() {
552}
553
554word Instance::DataOffsetFor(intptr_t cid) {
556
557 return 0;
558 }
560 return TypedData::payload_offset();
561 }
562 switch (cid) {
563 case kArrayCid:
564 case kImmutableArrayCid:
565 return Array::data_offset();
566 case kTypeArgumentsCid:
567 return TypeArguments::types_offset();
568 case kOneByteStringCid:
569 return OneByteString::data_offset();
570 case kTwoByteStringCid:
571 return TwoByteString::data_offset();
572 case kRecordCid:
573 return Record::field_offset(0);
574 default:
576 return Array::data_offset();
577 }
578}
579
580word Instance::ElementSizeFor(intptr_t cid) {
585 }
586 switch (cid) {
587 case kArrayCid:
588 case kImmutableArrayCid:
589 return kCompressedWordSize;
590 case kTypeArgumentsCid:
591 return kCompressedWordSize;
592 case kOneByteStringCid:
594 case kTwoByteStringCid:
596 default:
598 return 0;
599 }
600}
601
602word ICData::CodeIndexFor(word num_args) {
604}
605
606word ICData::CountIndexFor(word num_args) {
608}
609
610word ICData::TargetIndexFor(word num_args) {
612}
613
614word ICData::ExactnessIndexFor(word num_args) {
616}
617
618word ICData::TestEntryLengthFor(word num_args,
bool exactness_check) {
620}
621
622word ICData::EntryPointIndexFor(word num_args) {
624}
625
626const word MegamorphicCache::kSpreadFactor =
628
629
630
631
632
633
634
635
636#define DEFINE_CONSTANT(Class, Name) const word Class::Name = Class##_##Name;
637
638#define DEFINE_ARRAY_SIZEOF(clazz, name, ElementOffset) \
639 word clazz::name() { \
640 return 0; \
641 } \
642 word clazz::name(intptr_t length) { \
643 return RoundedAllocationSize(clazz::ElementOffset(length)); \
644 }
645
646#define DEFINE_PAYLOAD_SIZEOF(clazz, name, header) \
647 word clazz::name() { \
648 return 0; \
649 } \
650 word clazz::name(word payload_size) { \
651 return RoundedAllocationSize(clazz::header() + payload_size); \
652 }
653
654#if defined(TARGET_ARCH_IA32)
655
656#define DEFINE_FIELD(clazz, name) \
657 word clazz::name() { \
658 return clazz##_##name; \
659 }
660
661#define DEFINE_ARRAY(clazz, name) \
662 word clazz::name(intptr_t index) { \
663 return clazz##_elements_start_offset + index * clazz##_element_size; \
664 }
665
666#define DEFINE_SIZEOF(clazz, name, what) \
667 word clazz::name() { \
668 return clazz##_##name; \
669 }
670
671#define DEFINE_RANGE(Class, Getter, Type, First, Last, Filter) \
672 word Class::Getter(Type index) { \
673 return Class##_##Getter[static_cast<intptr_t>(index) - \
674 static_cast<intptr_t>(First)]; \
675 }
676
684
692
693#else
694
695#define DEFINE_JIT_FIELD(clazz, name) \
696 word clazz::name() { \
697 if (FLAG_precompiled_mode) { \
698 FATAL("Use of JIT-only field %s in precompiled mode", \
699 #clazz "::" #name); \
700 } \
701 return clazz##_##name; \
702 }
703
704#define DEFINE_JIT_ARRAY(clazz, name) \
705 word clazz::name(intptr_t index) { \
706 if (FLAG_precompiled_mode) { \
707 FATAL("Use of JIT-only array %s in precompiled mode", \
708 #clazz "::" #name); \
709 } \
710 return clazz##_elements_start_offset + index * clazz##_element_size; \
711 }
712
713#define DEFINE_JIT_SIZEOF(clazz, name, what) \
714 word clazz::name() { \
715 if (FLAG_precompiled_mode) { \
716 FATAL("Use of JIT-only sizeof %s in precompiled mode", \
717 #clazz "::" #name); \
718 } \
719 return clazz##_##name; \
720 }
721
722#define DEFINE_JIT_RANGE(Class, Getter, Type, First, Last, Filter) \
723 word Class::Getter(Type index) { \
724 if (FLAG_precompiled_mode) { \
725 FATAL("Use of JIT-only range %s in precompiled mode", \
726 #Class "::" #Getter); \
727 } \
728 return Class##_##Getter[static_cast<intptr_t>(index) - \
729 static_cast<intptr_t>(First)]; \
730 }
731
739
740#undef DEFINE_JIT_FIELD
741#undef DEFINE_JIT_ARRAY
742#undef DEFINE_JIT_SIZEOF
743#undef DEFINE_JIT_RANGE
744
745#if defined(DART_PRECOMPILER)
746
747
748
749
750
751#define DEFINE_AOT_FIELD(clazz, name) \
752 word clazz::name() { \
753 return AOT_##clazz##_##name; \
754 }
755
756#define DEFINE_AOT_ARRAY(clazz, name) \
757 word clazz::name(intptr_t index) { \
758 return AOT_##clazz##_elements_start_offset + \
759 index * AOT_##clazz##_element_size; \
760 }
761
762#define DEFINE_AOT_SIZEOF(clazz, name, what) \
763 word clazz::name() { \
764 return AOT_##clazz##_##name; \
765 }
766
767#define DEFINE_AOT_RANGE(Class, Getter, Type, First, Last, Filter) \
768 word Class::Getter(Type index) { \
769 return AOT_##Class##_##Getter[static_cast<intptr_t>(index) - \
770 static_cast<intptr_t>(First)]; \
771 }
772#else
773#define DEFINE_AOT_FIELD(clazz, name) \
774 word clazz::name() { \
775 FATAL("Use of AOT-only field %s outside of the precompiler", \
776 #clazz "::" #name); \
777 }
778
779#define DEFINE_AOT_ARRAY(clazz, name) \
780 word clazz::name(intptr_t index) { \
781 FATAL("Use of AOT-only array %s outside of the precompiler", \
782 #clazz "::" #name); \
783 }
784
785#define DEFINE_AOT_SIZEOF(clazz, name, what) \
786 word clazz::name() { \
787 FATAL("Use of AOT-only sizeof %s outside of the precompiler", \
788 #clazz "::" #name); \
789 }
790
791#define DEFINE_AOT_RANGE(Class, Getter, Type, First, Last, Filter) \
792 word Class::Getter(Type index) { \
793 FATAL("Use of AOT-only range %s outside of the precompiler", \
794 #Class "::" #Getter); \
795 }
796#endif
797
805
806#undef DEFINE_AOT_FIELD
807#undef DEFINE_AOT_ARRAY
808#undef DEFINE_AOT_SIZEOF
809#undef DEFINE_AOT_RANGE
810
811#define DEFINE_FIELD(clazz, name) \
812 word clazz::name() { \
813 return FLAG_precompiled_mode ? AOT_##clazz##_##name : clazz##_##name; \
814 }
815
816#define DEFINE_ARRAY(clazz, name) \
817 word clazz::name(intptr_t index) { \
818 if (FLAG_precompiled_mode) { \
819 return AOT_##clazz##_elements_start_offset + \
820 index * AOT_##clazz##_element_size; \
821 } else { \
822 return clazz##_elements_start_offset + index * clazz##_element_size; \
823 } \
824 }
825
826#define DEFINE_SIZEOF(clazz, name, what) \
827 word clazz::name() { \
828 return FLAG_precompiled_mode ? AOT_##clazz##_##name : clazz##_##name; \
829 }
830
831#define DEFINE_RANGE(Class, Getter, Type, First, Last, Filter) \
832 word Class::Getter(Type index) { \
833 if (FLAG_precompiled_mode) { \
834 return AOT_##Class##_##Getter[static_cast<intptr_t>(index) - \
835 static_cast<intptr_t>(First)]; \
836 } else { \
837 return Class##_##Getter[static_cast<intptr_t>(index) - \
838 static_cast<intptr_t>(First)]; \
839 } \
840 }
841
849
850#endif
851
852#undef DEFINE_FIELD
853#undef DEFINE_ARRAY
854#undef DEFINE_SIZEOF
855#undef DEFINE_RANGE
856#undef DEFINE_PAYLOAD_SIZEOF
857#undef DEFINE_CONSTANT
858
860
862
863
864
865
866
867
869 return FLAG_precompiled_mode;
870}
871
872word Instructions::HeaderSize() {
874 ? 0
875 : Utils::RoundUp(UnalignedHeaderSize(), kNonBarePayloadAlignment);
876}
877
878word Instructions::InstanceSize() {
879 return 0;
880}
881
882word Instructions::InstanceSize(word payload_size) {
884 ? kBarePayloadAlignment
885 : ObjectAlignment::kObjectAlignment;
886 return Utils::RoundUp(Instructions::HeaderSize() + payload_size, alignment);
887}
888
889word Thread::stack_overflow_shared_stub_entry_point_offset(
bool fpu_regs) {
890 return fpu_regs ? stack_overflow_shared_with_fpu_regs_entry_point_offset()
891 : stack_overflow_shared_without_fpu_regs_entry_point_offset();
892}
893
894uword Thread::full_safepoint_state_unacquired() {
896}
897
898uword Thread::full_safepoint_state_acquired() {
900}
901
902uword Thread::generated_execution_state() {
904}
905
906uword Thread::native_execution_state() {
908}
909
910uword Thread::vm_execution_state() {
912}
913
914uword Thread::vm_tag_dart_id() {
915 return dart::VMTag::kDartTagId;
916}
917
918uword Thread::exit_through_runtime_call() {
920}
921
922uword Thread::exit_through_ffi() {
924}
925
928 return object_null_offset() +
930 dart::Thread::object_null_offset());
931}
932
935 return AllocateArray_entry_point_offset() +
937 host_offset - dart::Thread::AllocateArray_entry_point_offset());
938}
939
944 *
offset = Thread::OffsetFromThread(
object);
945 }
946 return true;
947 }
948 return false;
949}
950
951static_assert(
953 "Expected that size of Smi on HOST is at least as large as on target.");
954
957}
958
962}
963
966}
967
970 return static_cast<word>(dart::Smi::Cast(
a).Value());
971}
972
975}
976
979 return dart::Double::Cast(
a).value();
980}
981
982#if defined(TARGET_ARCH_IA32)
984 static_assert(kHostWordSize ==
kWordSize,
985 "Can't embed raw pointers to runtime objects when host and "
986 "target word sizes are different");
987 return code.EntryPoint();
988}
989
990bool CanEmbedAsRawPointerInGeneratedCode(
const dart::Object& obj) {
992}
993
995 static_assert(kHostWordSize ==
kWordSize,
996 "Can't embed raw pointers to runtime objects when host and "
997 "target word sizes are different");
998 return static_cast<word>(
a.ptr());
999}
1000#endif
1001
1002word RegExp::function_offset(classid_t cid,
bool sticky) {
1003#if !defined(DART_COMPRESSED_POINTERS)
1005#else
1006
1007
1009#endif
1010}
1011
1012const word Symbols::kNumberOfOneCharCodeSymbols =
1014const word Symbols::kNullCharCodeSymbolOffset =
1016
1018
1019const uint8_t Nullability::kNullable =
1021const uint8_t Nullability::kNonNullable =
1023const uint8_t Nullability::kLegacy =
1025
1026bool Heap::IsAllocatableInNewSpace(intptr_t instance_size) {
1028}
1029
1032}
1033
1037}
1038
1039word FreeListElement::FakeInstance::InstanceSize() {
1040 return 0;
1041}
1042
1043word ForwardingCorpse::FakeInstance::InstanceSize() {
1044 return 0;
1045}
1046
1047word Instance::NextFieldOffset() {
1049}
1050
1051intptr_t Array::index_at_offset(intptr_t offset_in_bytes) {
1054}
1055
1056intptr_t Record::field_index_at_offset(intptr_t offset_in_bytes) {
1059}
1060
1061word String::InstanceSize(word payload_size) {
1062 return RoundedAllocationSize(String::InstanceSize() + payload_size);
1063}
1064
1065word LocalVarDescriptors::InstanceSize() {
1066 return 0;
1067}
1068
1069word Integer::NextFieldOffset() {
1071}
1072
1073word Smi::InstanceSize() {
1074 return 0;
1075}
1076
1077word Number::NextFieldOffset() {
1079}
1080
1084 return;
1085 }
1086
1087 if (
type.IsNullable()) {
1088 return;
1089 }
1090
1092 if (
type.IsDoubleType()) {
1093 if (FlowGraphCompiler::SupportsUnboxedDoubles()) {
1095 }
1096 }
else if (
type.IsFloat32x4Type()) {
1097 if (FlowGraphCompiler::SupportsUnboxedSimd128()) {
1098 cid = kFloat32x4Cid;
1099 }
1100 }
else if (
type.IsFloat64x2Type()) {
1101 if (FlowGraphCompiler::SupportsUnboxedSimd128()) {
1102 cid = kFloat64x2Cid;
1103 }
1104 }
1105
1106 if (cid != kIllegalCid) {
1113 }
1114}
1115
1116}
1117}
1118}
1119
1120#else
1121
1125
1126const word Array::kMaxElements = Array_kMaxElements;
1127const word Context::kMaxElements = Context_kMaxElements;
1128const word Record::kMaxElements = Record_kMaxElements;
1129
1130const word RecordShape::kNumFieldsMask = RecordShape_kNumFieldsMask;
1131const word RecordShape::kMaxNumFields = RecordShape_kMaxNumFields;
1132const word RecordShape::kFieldNamesIndexShift =
1133 RecordShape_kFieldNamesIndexShift;
1134const word RecordShape::kFieldNamesIndexMask = RecordShape_kFieldNamesIndexMask;
1135const word RecordShape::kMaxFieldNamesIndex = RecordShape_kMaxFieldNamesIndex;
1136
1137}
1138}
1139}
1140
1141#endif
#define RELEASE_ASSERT(cond)
#define CLASS_LIST_FFI_TYPE_MARKER(V)
#define CLASS_LIST_TYPED_DATA(V)
static intptr_t index_at_offset(intptr_t offset_in_bytes)
static constexpr uword encode(ClassIdTagType value)
bool TraceAllocation(IsolateGroup *isolate_group) const
intptr_t target_type_arguments_field_offset() const
intptr_t target_instance_size() const
intptr_t NumTypeArguments() const
intptr_t host_type_arguments_field_offset() const
bool HasCompressedPointers() const
static constexpr intptr_t kNoTypeArguments
static intptr_t FieldOffsetFor(intptr_t field_id)
void set_is_unboxed(bool b) const
intptr_t TargetOffset() const
void set_guarded_cid(intptr_t cid) const
void set_guarded_list_length_in_object_offset(intptr_t offset) const
intptr_t field_id() const
void set_is_nullable(bool val) const
void set_guarded_list_length(intptr_t list_length) const
static intptr_t ExactnessIndexFor(intptr_t num_args)
static intptr_t CodeIndexFor(intptr_t num_args)
static intptr_t TargetIndexFor(intptr_t num_args)
static intptr_t CountIndexFor(intptr_t num_args)
static intptr_t TestEntryLengthFor(intptr_t num_args, bool tracking_exactness)
static intptr_t EntryPointIndexFor(intptr_t num_args)
static intptr_t NextFieldOffset()
static intptr_t NativeFieldsOffset()
static IsolateGroup * Current()
static constexpr intptr_t kSpreadFactor
bool InVMIsolateHeap() const
static bool ShouldHaveImmutabilityBitSet(classid_t class_id)
virtual const char * ToCString() const
static constexpr intptr_t kHashBits
static constexpr intptr_t kBytesPerElement
static intptr_t field_index_at_offset(intptr_t offset_in_bytes)
static intptr_t function_offset(intptr_t cid, bool sticky)
static intptr_t RawValue(intptr_t value)
static constexpr int kNumberOfOneCharCodeSymbols
static constexpr int kNullCharCodeSymbolOffset
static uword full_safepoint_state_unacquired()
static intptr_t OffsetFromThread(const Object &object)
@ kExitThroughRuntimeCall
static bool CanLoadFromThread(const Object &object)
static uword full_safepoint_state_acquired()
static constexpr intptr_t kBytesPerElement
intptr_t ElementSizeInBytes() const
static constexpr intptr_t kNullabilityMask
static constexpr intptr_t kTypeStateBits
static constexpr intptr_t kTypeStateShift
static constexpr intptr_t kMaxSizeTagInUnitsOfAlignment
static constexpr bool SizeFits(intptr_t size)
static constexpr uword encode(intptr_t size)
static constexpr intptr_t kIncrementalBarrierMask
static constexpr intptr_t kGenerationalBarrierMask
static constexpr intptr_t kBarrierOverlapShift
@ kOldAndNotRememberedBit
static constexpr intptr_t kIsFunctionTypeParameterBit
static constexpr intptr_t kTypeClassIdShift
static word TranslateOffsetInWords(word offset)
uword MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size)
static uword GetInstanceSizeImpl(const dart::Class &handle)
static word TranslateOffsetInWordsToHost(word offset)
void UnboxFieldIfSupported(const dart::Field &field, const dart::AbstractType &type)
bool CanLoadFromThread(const dart::Object &object, intptr_t *offset)
double DoubleValue(const dart::Object &a)
word ToRawSmi(const dart::Object &a)
bool IsDouble(const dart::Object &a)
bool SizeFitsInSizeTag(uword instance_size)
word SmiValue(const dart::Object &a)
static DART_FORCE_INLINE bool BareInstructionsPayloads()
const word kPageSizeInWords
bool IsTypedDataViewClassId(intptr_t index)
bool IsTypedDataClassId(intptr_t index)
static constexpr intptr_t kPageSize
bool IsUnmodifiableTypedDataViewClassId(intptr_t index)
@ kUnmodifiableByteDataViewCid
bool IsAllocatableInNewSpace(intptr_t size)
static constexpr intptr_t kCompressedWordSize
constexpr intptr_t kWordSize
static constexpr intptr_t kPageMask
bool IsExternalTypedDataClassId(intptr_t index)
#define DEFINE_AOT_RANGE(Class, Getter, Type, First, Last, Filter)
#define DEFINE_AOT_SIZEOF(clazz, name, what)
#define DEFINE_ARRAY_SIZEOF(clazz, name, ElementOffset)
#define DEFINE_JIT_SIZEOF(clazz, name, what)
#define DEFINE_ARRAY(clazz, name)
#define DEFINE_CONSTANT(Class, Name)
#define DEFINE_PAYLOAD_SIZEOF(clazz, name, header)
#define DEFINE_AOT_FIELD(clazz, name)
#define DEFINE_FIELD(clazz, name)
#define HANDLE_CASE(clazz)
#define DEFINE_AOT_ARRAY(clazz, name)
#define DEFINE_JIT_RANGE(Class, Getter, Type, First, Last, Filter)
#define DEFINE_JIT_ARRAY(clazz, name)
#define DEFINE_RANGE(Class, Getter, Type, First, Last, Filter)
#define DEFINE_JIT_FIELD(clazz, name)
#define DEFINE_SIZEOF(clazz, name, what)
#define JIT_OFFSETS_LIST(FIELD, ARRAY, SIZEOF, ARRAY_SIZEOF, PAYLOAD_SIZEOF, RANGE, CONSTANT)
#define AOT_OFFSETS_LIST(FIELD, ARRAY, SIZEOF, ARRAY_SIZEOF, PAYLOAD_SIZEOF, RANGE, CONSTANT)
#define COMMON_OFFSETS_LIST(FIELD, ARRAY, SIZEOF, ARRAY_SIZEOF, PAYLOAD_SIZEOF, RANGE, CONSTANT)