@@ -484,65 +484,74 @@ PER_ISOLATE_EXTERNAL_POINTER_TAGS(CHECK_NON_SHARED_EXTERNAL_POINTER_TAGS)
484484// Indirect Pointers.
485485//
486486// When the sandbox is enabled, indirect pointers are used to reference
487- // HeapObjects that live outside of the sandbox (but are still managed through
488- // the GC). When object A references an object B through an indirect pointer,
489- // object A will contain a IndirectPointerHandle, i.e. a shifted 32-bit index,
490- // which identifies an entry in a pointer table (such as the CodePointerTable).
487+ // HeapObjects that live outside of the sandbox (but are still managed by V8's
488+ // garbage collector). When object A references an object B through an indirect
489+ // pointer, object A will contain a IndirectPointerHandle, i.e. a shifted
490+ // 32-bit index, which identifies an entry in a pointer table (generally an
491+ // indirect pointer table, or the code pointer table if it is a Code object).
491492// This table entry then contains the actual pointer to object B. Further,
492493// object B owns this pointer table entry, and it is responsible for updating
493494// the "self-pointer" in the entry when it is relocated in memory. This way, in
494495// contrast to "normal" pointers, indirect pointers never need to be tracked by
495496// the GC (i.e. there is no remembered set for them).
496- // Currently there is only one type of object referenced through indirect
497- // pointers (Code objects), but once there are different types of such objects,
498- // the pointer table entry would probably also contain the type of the target
499- // object (e.g. by XORing the instance type into the top bits of the pointer).
500497
501498// An IndirectPointerHandle represents a 32-bit index into a pointer table.
502499using IndirectPointerHandle = uint32_t ;
503500
501+ // The size of the virtual memory reservation for the indirect pointer table.
502+ // As with the external pointer table, a maximum table size in combination with
503+ // shifted indices allows omitting bounds checks.
504+ constexpr size_t kIndirectPointerTableReservationSize = 8 * MB;
505+
504506// The indirect pointer handles are stores shifted to the left by this amount
505507// to guarantee that they are smaller than the maximum table size.
506- constexpr uint32_t kIndirectPointerHandleShift = 6 ;
508+ constexpr uint32_t kIndirectPointerHandleShift = 12 ;
507509
508510// A null handle always references an entry that contains nullptr.
509511constexpr IndirectPointerHandle kNullIndirectPointerHandle = 0 ;
510512
511- // Currently only Code objects can be referenced through indirect pointers and
512- // various places rely on that assumption. They will all static_assert against
513- // this constant to make them easy to find and fix once we reference other types
514- // of objects indirectly.
515- constexpr bool kAllIndirectPointerObjectsAreCode = true ;
513+ // The maximum number of entries in an indirect pointer table.
514+ constexpr int kIndirectPointerTableEntrySize = 8 ;
515+ constexpr int kIndirectPointerTableEntrySizeLog2 = 3 ;
516+ constexpr size_t kMaxIndirectPointers =
517+ kIndirectPointerTableReservationSize / kIndirectPointerTableEntrySize ;
518+ static_assert ((1 << (32 - kIndirectPointerHandleShift )) == kMaxIndirectPointers ,
519+ " kIndirectPointerTableReservationSize and "
520+ " kIndirectPointerHandleShift don't match" );
516521
517522//
518523// Code Pointers.
519524//
520525// When the sandbox is enabled, Code objects are referenced from inside the
521526// sandbox through indirect pointers that reference entries in the code pointer
522- // table (CPT). Each entry in the CPT contains both a pointer to a Code object
523- // as well as a pointer to the Code's entrypoint. This allows calling/jumping
524- // into Code with one fewer memory access (compared to the case where the
525- // entrypoint pointer needs to be loaded from the Code object).
526- // As such, a CodePointerHandle can be used both to obtain the referenced Code
527- // object and to directly load its entrypoint pointer.
527+ // table (CPT) instead of the indirect pointer table (IPT). Each entry in the
528+ // CPT contains both a pointer to a Code object as well as a pointer to the
529+ // Code's entrypoint. This allows calling/jumping into Code with one fewer
530+ // memory access (compared to the case where the entrypoint pointer needs to be
531+ // loaded from the Code object). As such, a CodePointerHandle can be used both
532+ // to obtain the referenced Code object and to directly load its entrypoint
533+ // pointer.
528534using CodePointerHandle = IndirectPointerHandle;
529- constexpr uint32_t kCodePointerHandleShift = kIndirectPointerHandleShift ;
530- constexpr CodePointerHandle kNullCodePointerHandle = 0 ;
531535
532- // The size of the virtual memory reservation for code pointer table.
533- // This determines the maximum number of entries in a table. Using a maximum
534- // size allows omitting bounds checks on table accesses if the indices are
535- // guaranteed (e.g. through shifting) to be below the maximum index. This
536- // value must be a power of two.
536+ // The size of the virtual memory reservation for the code pointer table.
537+ // As with the other tables, a maximum table size in combination with shifted
538+ // indices allows omitting bounds checks.
537539constexpr size_t kCodePointerTableReservationSize = 1 * GB;
538540
539- // The maximum number of entries in an external pointer table.
541+ // Code pointer handles are shifted by a different amount than indirect pointer
542+ // handles as the tables have a different maximum size.
543+ constexpr uint32_t kCodePointerHandleShift = 6 ;
544+
545+ // A null handle always references an entry that contains nullptr.
546+ constexpr CodePointerHandle kNullCodePointerHandle = 0 ;
547+
548+ // The maximum number of entries in a code pointer table.
540549constexpr int kCodePointerTableEntrySize = 16 ;
541550constexpr int kCodePointerTableEntrySizeLog2 = 4 ;
542551constexpr size_t kMaxCodePointers =
543552 kCodePointerTableReservationSize / kCodePointerTableEntrySize ;
544553static_assert (
545- (1 << (32 - kIndirectPointerHandleShift )) == kMaxCodePointers ,
554+ (1 << (32 - kCodePointerHandleShift )) == kMaxCodePointers ,
546555 " kCodePointerTableReservationSize and kCodePointerHandleShift don't match" );
547556
548557constexpr int kCodePointerTableEntryEntrypointOffset = 0 ;
@@ -602,9 +611,11 @@ class Internals {
602611 static const int kHandleScopeDataSize =
603612 2 * kApiSystemPointerSize + 2 * kApiInt32Size ;
604613
605- // ExternalPointerTable layout guarantees.
614+ // ExternalPointerTable and IndirectPointerTable layout guarantees.
606615 static const int kExternalPointerTableBasePointerOffset = 0 ;
607616 static const int kExternalPointerTableSize = 2 * kApiSystemPointerSize ;
617+ static const int kIndirectPointerTableSize = 2 * kApiSystemPointerSize ;
618+ static const int kIndirectPointerTableBasePointerOffset = 0 ;
608619
609620 // IsolateData layout guarantees.
610621 static const int kIsolateCageBaseOffset = 0 ;
@@ -639,8 +650,10 @@ class Internals {
639650 kIsolateEmbedderDataOffset + kNumIsolateDataSlots * kApiSystemPointerSize ;
640651 static const int kIsolateSharedExternalPointerTableAddressOffset =
641652 kIsolateExternalPointerTableOffset + kExternalPointerTableSize ;
642- static const int kIsolateApiCallbackThunkArgumentOffset =
653+ static const int kIsolateIndirectPointerTableOffset =
643654 kIsolateSharedExternalPointerTableAddressOffset + kApiSystemPointerSize ;
655+ static const int kIsolateApiCallbackThunkArgumentOffset =
656+ kIsolateIndirectPointerTableOffset + kIndirectPointerTableSize ;
644657#else
645658 static const int kIsolateApiCallbackThunkArgumentOffset =
646659 kIsolateEmbedderDataOffset + kNumIsolateDataSlots * kApiSystemPointerSize ;
@@ -763,6 +776,15 @@ class Internals {
763776 return ReadRawField<uint16_t >(map, kMapInstanceTypeOffset );
764777 }
765778
779+ V8_INLINE static Address LoadMap (Address obj) {
780+ if (!HasHeapObjectTag (obj)) return kNullAddress ;
781+ Address map = ReadTaggedPointerField (obj, kHeapObjectMapOffset );
782+ #ifdef V8_MAP_PACKING
783+ map = UnpackMapWord (map);
784+ #endif
785+ return map;
786+ }
787+
766788 V8_INLINE static int GetOddballKind (Address obj) {
767789 return SmiValue (ReadTaggedSignedField (obj, kOddballKindOffset ));
768790 }
0 commit comments