From 4f4d73f225d45674b8edd62f4e562a4384030cf4 Mon Sep 17 00:00:00 2001 From: Tobias Tebbi Date: Tue, 3 Mar 2020 16:53:40 +0100 Subject: [PATCH] [torque] Generate GC object visitors for Torque classes In the process: * Augment C++-generated Torque classes with SizeFor methods to calculate size of instances. * Add a new "@generateBodyDescriptor" annotation that causes Torque to generate C++ BodyDescriptors code that can be used to visit objects compatible with existing V8 mechanisms, e.g. GC * Fully automate C++ macro machinery so that adding non-extern Torque class doesn't require any C++ changes, including ensuring generation of instance types and proper boilerplate for validators and printers. * Make handling of @export a true annotation, allowing the modifier to be used on class declarations. * Add functionality such that classes with the @export annotation are available to be used from C++. Field accessors for exported classes are public and factory methods are generated to create instances of the objects from C++. * Change the Torque compiler such that Non-exported classes implicitly have the @generateBodyDescriptor annotation added and causes both verifiers and printers to be generated. * Switch non-extern Torque classes from using existing Struct-based machinery to being first-class classes that support more existing Torque class features. Change-Id: Ic60e60c2c6bd7acd57f949bce086898ad14a3b03 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2007490 Commit-Queue: Tobias Tebbi Reviewed-by: Tobias Tebbi Cr-Commit-Position: refs/heads/master@{#66621} --- BUILD.gn | 4 + src/builtins/torque-internal.tq | 2 +- src/codegen/code-stub-assembler.cc | 5 +- src/codegen/code-stub-assembler.h | 9 +- src/compiler/code-assembler.h | 2 +- src/compiler/types.cc | 2 +- src/diagnostics/objects-debug.cc | 1 + src/diagnostics/objects-printer.cc | 1 + src/heap/factory-base.cc | 2 +- src/heap/factory.h | 7 + src/heap/objects-visiting-inl.h | 3 + src/heap/objects-visiting.h | 2 + src/heap/setup-heap-internal.cc | 12 + src/objects/map.cc | 15 +- src/objects/map.h | 12 +- src/objects/object-list-macros.h | 7 +- src/objects/objects-body-descriptors-inl.h | 6 + src/objects/objects-body-descriptors.h | 4 + src/objects/objects-definitions.h | 13 +- src/objects/objects.cc | 9 + src/roots/roots.h | 17 +- src/torque/class-debug-reader-generator.cc | 3 +- src/torque/constants.h | 6 + src/torque/global-context.h | 10 - src/torque/implementation-visitor.cc | 689 ++++++++++++++++---- src/torque/implementation-visitor.h | 2 +- src/torque/instance-type-generator.cc | 47 +- src/torque/torque-compiler.cc | 2 +- src/torque/torque-parser.cc | 33 +- src/torque/type-oracle.cc | 12 + src/torque/type-oracle.h | 8 + src/torque/type-visitor.cc | 127 ++-- src/torque/types.cc | 61 +- src/torque/types.h | 17 +- test/cctest/torque/test-torque.cc | 29 + test/torque/test-torque.tq | 110 +++- third_party/v8/builtins/array-sort.tq | 2 +- tools/debug_helper/BUILD.gn | 1 + tools/debug_helper/get-object-properties.cc | 1 + tools/v8heapconst.py | 324 ++++----- 40 files changed, 1206 insertions(+), 413 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index acad3e591e..0f7e99301a 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1176,11 +1176,14 @@ template("run_torque") { "bit-fields-tq.h", "builtin-definitions-tq.h", "interface-descriptors-tq.inc", + "factory-tq.cc", + "factory-tq.inc", "field-offsets-tq.h", "class-verifiers-tq.cc", "class-verifiers-tq.h", "enum-verifiers-tq.cc", "objects-printer-tq.cc", + "objects-body-descriptors-tq-inl.h", "class-definitions-tq.cc", "class-definitions-tq-inl.h", "class-definitions-tq.h", @@ -1302,6 +1305,7 @@ v8_source_set("torque_generated_definitions") { "$target_gen_dir/torque-generated/class-definitions-tq.cc", "$target_gen_dir/torque-generated/class-verifiers-tq.cc", "$target_gen_dir/torque-generated/class-verifiers-tq.h", + "$target_gen_dir/torque-generated/factory-tq.cc", "$target_gen_dir/torque-generated/objects-printer-tq.cc", ] diff --git a/src/builtins/torque-internal.tq b/src/builtins/torque-internal.tq index 47e91c93dc..b5da601c44 100644 --- a/src/builtins/torque-internal.tq +++ b/src/builtins/torque-internal.tq @@ -148,7 +148,7 @@ namespace torque_internal { type UninitializedHeapObject extends HeapObject; extern macro AllocateAllowLOS(intptr): UninitializedHeapObject; - extern macro GetStructMap(constexpr InstanceType): Map; + extern macro GetInstanceTypeMap(constexpr InstanceType): Map; macro Allocate(sizeInBytes: intptr, map: Map): UninitializedHeapObject { assert(ValidAllocationSize(sizeInBytes, map)); diff --git a/src/codegen/code-stub-assembler.cc b/src/codegen/code-stub-assembler.cc index c61f5e849f..734cb94d22 100644 --- a/src/codegen/code-stub-assembler.cc +++ b/src/codegen/code-stub-assembler.cc @@ -1635,9 +1635,10 @@ TNode CodeStubAssembler::LoadHeapNumberValue( object, HeapNumber::kValueOffset, MachineType::Float64())); } -TNode CodeStubAssembler::GetStructMap(InstanceType instance_type) { +TNode CodeStubAssembler::GetInstanceTypeMap(InstanceType instance_type) { Handle map_handle( - Map::GetStructMap(ReadOnlyRoots(isolate()), instance_type), isolate()); + Map::GetInstanceTypeMap(ReadOnlyRoots(isolate()), instance_type), + isolate()); return HeapConstant(map_handle); } diff --git a/src/codegen/code-stub-assembler.h b/src/codegen/code-stub-assembler.h index f2d1109cf8..19c8711e2e 100644 --- a/src/codegen/code-stub-assembler.h +++ b/src/codegen/code-stub-assembler.h @@ -53,6 +53,9 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol }; V(TypedArraySpeciesProtector, typed_array_species_protector, \ TypedArraySpeciesProtector) +#define TORQUE_INTERNAL_CLASS_LIST_CSA_ADAPTER(V, NAME, Name, name) \ + V(Name##Map, name##_map, Name##Map) + #define HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(V) \ V(AccessorInfoMap, accessor_info_map, AccessorInfoMap) \ V(AccessorPairMap, accessor_pair_map, AccessorPairMap) \ @@ -174,7 +177,9 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol }; V(UndefinedValue, undefined_value, Undefined) \ V(uninitialized_symbol, uninitialized_symbol, UninitializedSymbol) \ V(WeakFixedArrayMap, weak_fixed_array_map, WeakFixedArrayMap) \ - V(zero_string, zero_string, ZeroString) + V(zero_string, zero_string, ZeroString) \ + TORQUE_INTERNAL_CLASS_LIST_GENERATOR(TORQUE_INTERNAL_CLASS_LIST_CSA_ADAPTER, \ + V) #define HEAP_IMMOVABLE_OBJECT_LIST(V) \ HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(V) \ @@ -1942,7 +1947,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler Label* if_bailout); TNode GetConstructor(TNode map); - TNode GetStructMap(InstanceType instance_type); + TNode GetInstanceTypeMap(InstanceType instance_type); TNode AllocateUninitializedFixedArray(intptr_t capacity) { return UncheckedCast(AllocateFixedArray( diff --git a/src/compiler/code-assembler.h b/src/compiler/code-assembler.h index 30689e3592..ad07b8f71f 100644 --- a/src/compiler/code-assembler.h +++ b/src/compiler/code-assembler.h @@ -77,7 +77,7 @@ class PromiseRejectReactionJobTask; class WasmDebugInfo; class Zone; #define MAKE_FORWARD_DECLARATION(V, NAME, Name, name) class Name; -TORQUE_STRUCT_LIST_GENERATOR(MAKE_FORWARD_DECLARATION, UNUSED) +TORQUE_INTERNAL_CLASS_LIST_GENERATOR(MAKE_FORWARD_DECLARATION, UNUSED) #undef MAKE_FORWARD_DECLARATION template diff --git a/src/compiler/types.cc b/src/compiler/types.cc index 606b7e4840..a947d31019 100644 --- a/src/compiler/types.cc +++ b/src/compiler/types.cc @@ -369,7 +369,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) { case PROMISE_REJECT_REACTION_JOB_TASK_TYPE: case PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE: #define MAKE_TORQUE_CLASS_TYPE(V) case V: - TORQUE_INTERNAL_INSTANCE_TYPES(MAKE_TORQUE_CLASS_TYPE) + TORQUE_INSTANCE_TYPES(MAKE_TORQUE_CLASS_TYPE) #undef MAKE_TORQUE_CLASS_TYPE UNREACHABLE(); } diff --git a/src/diagnostics/objects-debug.cc b/src/diagnostics/objects-debug.cc index 95c585cfbf..4a9d029a05 100644 --- a/src/diagnostics/objects-debug.cc +++ b/src/diagnostics/objects-debug.cc @@ -247,6 +247,7 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) { // Every class that has its fields defined in a .tq file and corresponds // to exactly one InstanceType value is included in the following list. TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(MAKE_TORQUE_CASE) + TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(MAKE_TORQUE_CASE) #undef MAKE_TORQUE_CASE case ALLOCATION_SITE_TYPE: diff --git a/src/diagnostics/objects-printer.cc b/src/diagnostics/objects-printer.cc index d6948ddf43..e0017743c9 100644 --- a/src/diagnostics/objects-printer.cc +++ b/src/diagnostics/objects-printer.cc @@ -207,6 +207,7 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT // Every class that has its fields defined in a .tq file and corresponds // to exactly one InstanceType value is included in the following list. TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(MAKE_TORQUE_CASE) + TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(MAKE_TORQUE_CASE) #undef MAKE_TORQUE_CASE case ALLOCATION_SITE_TYPE: diff --git a/src/heap/factory-base.cc b/src/heap/factory-base.cc index fc3f46c4df..94a2a8eea2 100644 --- a/src/heap/factory-base.cc +++ b/src/heap/factory-base.cc @@ -47,7 +47,7 @@ FactoryBase::NewHeapNumber(); template Handle FactoryBase::NewStruct(InstanceType type, AllocationType allocation) { - Map map = Map::GetStructMap(read_only_roots(), type); + Map map = Map::GetInstanceTypeMap(read_only_roots(), type); int size = map.instance_size(); HeapObject result = AllocateRawWithImmortalMap(size, allocation, map); Handle str = handle(Struct::cast(result), isolate()); diff --git a/src/heap/factory.h b/src/heap/factory.h index 9a69733725..81041f7f40 100644 --- a/src/heap/factory.h +++ b/src/heap/factory.h @@ -103,6 +103,13 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase { public: inline ReadOnlyRoots read_only_roots(); + template + Handle MakeHandle(T obj) { + return handle(obj, isolate()); + } + +#include "torque-generated/factory-tq.inc" + Handle NewOddball(Handle map, const char* to_string, Handle to_number, const char* type_of, byte kind); diff --git a/src/heap/objects-visiting-inl.h b/src/heap/objects-visiting-inl.h index d4d6d9375c..03df9a175d 100644 --- a/src/heap/objects-visiting-inl.h +++ b/src/heap/objects-visiting-inl.h @@ -18,6 +18,7 @@ #include "src/objects/oddball.h" #include "src/objects/ordered-hash-table.h" #include "src/wasm/wasm-objects.h" +#include "torque-generated/objects-body-descriptors-tq-inl.h" namespace v8 { namespace internal { @@ -43,6 +44,7 @@ ResultType HeapVisitor::Visit(Map map, return visitor->Visit##TypeName( \ map, ConcreteVisitor::template Cast(object)); TYPED_VISITOR_ID_LIST(CASE) + TORQUE_VISITOR_ID_LIST(CASE) #undef CASE case kVisitShortcutCandidate: return visitor->VisitShortcutCandidate( @@ -96,6 +98,7 @@ void HeapVisitor::VisitMapPointer( return static_cast(size); \ } TYPED_VISITOR_ID_LIST(VISIT) +TORQUE_VISITOR_ID_LIST(VISIT) #undef VISIT template diff --git a/src/heap/objects-visiting.h b/src/heap/objects-visiting.h index 2f2590a880..ea70f36ac0 100644 --- a/src/heap/objects-visiting.h +++ b/src/heap/objects-visiting.h @@ -68,6 +68,7 @@ namespace internal { #define FORWARD_DECLARE(TypeName) class TypeName; TYPED_VISITOR_ID_LIST(FORWARD_DECLARE) +TORQUE_VISITOR_ID_LIST(FORWARD_DECLARE) #undef FORWARD_DECLARE // The base class for visitors that need to dispatch on object type. The default @@ -103,6 +104,7 @@ class HeapVisitor : public ObjectVisitor { #define VISIT(TypeName) \ V8_INLINE ResultType Visit##TypeName(Map map, TypeName object); TYPED_VISITOR_ID_LIST(VISIT) + TORQUE_VISITOR_ID_LIST(VISIT) #undef VISIT V8_INLINE ResultType VisitShortcutCandidate(Map map, ConsString object); V8_INLINE ResultType VisitDataObject(Map map, HeapObject object); diff --git a/src/heap/setup-heap-internal.cc b/src/heap/setup-heap-internal.cc index 80b02bf20f..8c9d8cd456 100644 --- a/src/heap/setup-heap-internal.cc +++ b/src/heap/setup-heap-internal.cc @@ -403,6 +403,18 @@ bool Heap::CreateInitialMaps() { ALLOCATE_VARSIZE_MAP(SMALL_ORDERED_NAME_DICTIONARY_TYPE, small_ordered_name_dictionary) +#define TORQUE_INTERNAL_CLASS_LIST_MAP_ALLOCATOR(V, NAME, Name, name) \ + ALLOCATE_MAP(NAME, Name::kSize, name) + TORQUE_INTERNAL_FIXED_CLASS_LIST_GENERATOR( + TORQUE_INTERNAL_CLASS_LIST_MAP_ALLOCATOR, _); +#undef TORQUE_INTERNAL_CLASS_LIST_MAP_ALLOCATOR + +#define TORQUE_INTERNAL_CLASS_LIST_MAP_ALLOCATOR(V, NAME, Name, name) \ + ALLOCATE_VARSIZE_MAP(NAME, name) + TORQUE_INTERNAL_VARSIZE_CLASS_LIST_GENERATOR( + TORQUE_INTERNAL_CLASS_LIST_MAP_ALLOCATOR, _); +#undef TORQUE_INTERNAL_CLASS_LIST_MAP_ALLOCATOR + ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, sloppy_arguments_elements) ALLOCATE_VARSIZE_MAP(CODE_TYPE, code) diff --git a/src/objects/map.cc b/src/objects/map.cc index 066a331dc5..2dc288628c 100644 --- a/src/objects/map.cc +++ b/src/objects/map.cc @@ -24,6 +24,7 @@ #include "src/roots/roots.h" #include "src/utils/ostreams.h" #include "src/zone/zone-containers.h" +#include "torque-generated/field-offsets-tq.h" namespace v8 { namespace internal { @@ -74,7 +75,7 @@ void Map::PrintReconfiguration(Isolate* isolate, FILE* file, os << "]\n"; } -Map Map::GetStructMap(ReadOnlyRoots roots, InstanceType type) { +Map Map::GetInstanceTypeMap(ReadOnlyRoots roots, InstanceType type) { Map map; switch (type) { #define MAKE_CASE(TYPE, Name, name) \ @@ -82,6 +83,12 @@ Map Map::GetStructMap(ReadOnlyRoots roots, InstanceType type) { map = roots.name##_map(); \ break; STRUCT_LIST(MAKE_CASE) +#undef MAKE_CASE +#define MAKE_CASE(_, TYPE, Name, name) \ + case TYPE: \ + map = roots.name##_map(); \ + break; + TORQUE_INTERNAL_CLASS_LIST_GENERATOR(MAKE_CASE, _) #undef MAKE_CASE default: UNREACHABLE(); @@ -360,6 +367,12 @@ VisitorId Map::GetVisitorId(Map map) { case SYNTHETIC_MODULE_TYPE: return kVisitSyntheticModule; +#define MAKE_TQ_CASE(TYPE, Name) \ + case TYPE: \ + return kVisit##Name; + TORQUE_BODY_DESCRIPTOR_LIST(MAKE_TQ_CASE) +#undef MAKE_TQ_CASE + default: UNREACHABLE(); } diff --git a/src/objects/map.h b/src/objects/map.h index 03d981dd82..0b817e3bab 100644 --- a/src/objects/map.h +++ b/src/objects/map.h @@ -84,6 +84,13 @@ enum InstanceType : uint16_t; V(WeakArray) \ V(WeakCell) +#define TORQUE_OBJECT_BODY_TO_VISITOR_ID_LIST_ADAPTER(V, TYPE, TypeName) \ + V(TypeName) + +#define TORQUE_VISITOR_ID_LIST(V) \ + TORQUE_BODY_DESCRIPTOR_LIST_GENERATOR( \ + TORQUE_OBJECT_BODY_TO_VISITOR_ID_LIST_ADAPTER, V) + // Objects with the same visitor id are processed in the same way by // the heap visitors. The visitor ids for data only objects must precede // other visitor ids. We rely on kDataOnlyVisitorIdCount for quick check @@ -92,8 +99,9 @@ enum VisitorId { #define VISITOR_ID_ENUM_DECL(id) kVisit##id, DATA_ONLY_VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL) kDataOnlyVisitorIdCount, POINTER_VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL) + TORQUE_VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL) #undef VISITOR_ID_ENUM_DECL - kVisitorIdCount + kVisitorIdCount }; enum class ObjectFields { @@ -794,7 +802,7 @@ class Map : public HeapObject { inline bool CanTransition() const; - static Map GetStructMap(ReadOnlyRoots roots, InstanceType type); + static Map GetInstanceTypeMap(ReadOnlyRoots roots, InstanceType type); #define DECL_TESTER(Type, ...) inline bool Is##Type##Map() const; INSTANCE_TYPE_CHECKERS(DECL_TESTER) diff --git a/src/objects/object-list-macros.h b/src/objects/object-list-macros.h index 4b78e2567c..11b5c034c9 100644 --- a/src/objects/object-list-macros.h +++ b/src/objects/object-list-macros.h @@ -5,6 +5,10 @@ #ifndef V8_OBJECTS_OBJECT_LIST_MACROS_H_ #define V8_OBJECTS_OBJECT_LIST_MACROS_H_ +#include "torque-generated/instance-types-tq.h" + +#define TORQUE_INTERNAL_CLASS_NAMES_ADAPTER(V, NAME, Name, name) V(Name) + namespace v8 { namespace internal { @@ -233,7 +237,8 @@ class ZoneForwardList; V(WasmTableObject) \ V(WeakFixedArray) \ V(WeakArrayList) \ - V(WeakCell) + V(WeakCell) \ + TORQUE_INTERNAL_CLASS_LIST_GENERATOR(TORQUE_INTERNAL_CLASS_NAMES_ADAPTER, V) #ifdef V8_INTL_SUPPORT #define HEAP_OBJECT_ORDINARY_TYPE_LIST(V) \ diff --git a/src/objects/objects-body-descriptors-inl.h b/src/objects/objects-body-descriptors-inl.h index e4b2540397..60c508e336 100644 --- a/src/objects/objects-body-descriptors-inl.h +++ b/src/objects/objects-body-descriptors-inl.h @@ -1100,6 +1100,12 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) { case SYNTHETIC_MODULE_TYPE: return Op::template apply(p1, p2, p3, p4); +#define MAKE_TORQUE_BODY_DESCRIPTOR_APPLY(TYPE, TypeName) \ + case TYPE: \ + return Op::template apply(p1, p2, p3, p4); + TORQUE_BODY_DESCRIPTOR_LIST(MAKE_TORQUE_BODY_DESCRIPTOR_APPLY) +#undef MAKE_TORQUE_BODY_DESCRIPTOR_APPLY + default: PrintF("Unknown type: %d\n", type); UNREACHABLE(); diff --git a/src/objects/objects-body-descriptors.h b/src/objects/objects-body-descriptors.h index 728708f436..13adf4c3db 100644 --- a/src/objects/objects-body-descriptors.h +++ b/src/objects/objects-body-descriptors.h @@ -180,6 +180,10 @@ class SubclassBodyDescriptor final : public BodyDescriptorBase { } }; +#define TORQUE_BODY_DESCRIPTOR_LIST_ADAPTER(V, TYPE, TypeName) V(TYPE, TypeName) +#define TORQUE_BODY_DESCRIPTOR_LIST(V) \ + TORQUE_BODY_DESCRIPTOR_LIST_GENERATOR(TORQUE_BODY_DESCRIPTOR_LIST_ADAPTER, V) + } // namespace internal } // namespace v8 diff --git a/src/objects/objects-definitions.h b/src/objects/objects-definitions.h index 24176ac65c..a830e13ed1 100644 --- a/src/objects/objects-definitions.h +++ b/src/objects/objects-definitions.h @@ -159,9 +159,7 @@ namespace internal { wasm_indirect_function_table) \ V(_, WASM_JS_FUNCTION_DATA_TYPE, WasmJSFunctionData, wasm_js_function_data) -#define STRUCT_LIST_GENERATOR(V, _) \ - STRUCT_LIST_GENERATOR_BASE(V, _) \ - TORQUE_STRUCT_LIST_GENERATOR(V, _) +#define STRUCT_LIST_GENERATOR(V, _) STRUCT_LIST_GENERATOR_BASE(V, _) // Adapts one STRUCT_LIST_GENERATOR entry to the STRUCT_LIST entry #define STRUCT_LIST_ADAPTER(V, NAME, Name, name) V(NAME, Name, name) @@ -176,6 +174,15 @@ namespace internal { // Produces (Map, struct_name_map, StructNameMap) entries #define STRUCT_MAPS_LIST(V) STRUCT_LIST_GENERATOR(STRUCT_MAPS_LIST_ADAPTER, V) +// Adapts one STRUCT_LIST_GENERATOR entry to the STRUCT_LIST entry +#define TORQUE_INTERNAL_CLASS_LIST_MAPS_ADAPTER(V, NAME, Name, name) \ + V(Map, name##_map, Name##Map) + +// Produces (NAME, Name, name) entries. +#define TORQUE_INTERNAL_CLASS_MAPS_LIST(V) \ + TORQUE_INTERNAL_CLASS_LIST_GENERATOR( \ + TORQUE_INTERNAL_CLASS_LIST_MAPS_ADAPTER, V) + // // The following macros define list of allocation size objects and list of // their maps. diff --git a/src/objects/objects.cc b/src/objects/objects.cc index bed888a3af..3864f61763 100644 --- a/src/objects/objects.cc +++ b/src/objects/objects.cc @@ -125,6 +125,7 @@ #include "torque-generated/class-definitions-tq-inl.h" #include "torque-generated/internal-class-definitions-tq-inl.h" +#include "torque-generated/objects-body-descriptors-tq-inl.h" namespace v8 { namespace internal { @@ -2276,6 +2277,14 @@ int HeapObject::SizeFromMap(Map map) const { PreparseData data = PreparseData::unchecked_cast(*this); return PreparseData::SizeFor(data.data_length(), data.children_length()); } +#define MAKE_TORQUE_SIZE_FOR(TYPE, TypeName) \ + if (instance_type == TYPE) { \ + TypeName instance = TypeName::unchecked_cast(*this); \ + return TypeName::SizeFor(instance); \ + } + TORQUE_BODY_DESCRIPTOR_LIST(MAKE_TORQUE_SIZE_FOR) +#undef MAKE_TORQUE_SIZE_FOR + if (instance_type == CODE_TYPE) { return Code::unchecked_cast(*this).CodeSize(); } diff --git a/src/roots/roots.h b/src/roots/roots.h index 96118ca835..cf84ebf40b 100644 --- a/src/roots/roots.h +++ b/src/roots/roots.h @@ -302,14 +302,15 @@ class Symbol; #define ACCESSOR_INFO_ROOT_LIST(V) \ ACCESSOR_INFO_LIST_GENERATOR(ACCESSOR_INFO_ROOT_LIST_ADAPTER, V) -#define READ_ONLY_ROOT_LIST(V) \ - STRONG_READ_ONLY_ROOT_LIST(V) \ - INTERNALIZED_STRING_ROOT_LIST(V) \ - PRIVATE_SYMBOL_ROOT_LIST(V) \ - PUBLIC_SYMBOL_ROOT_LIST(V) \ - WELL_KNOWN_SYMBOL_ROOT_LIST(V) \ - STRUCT_MAPS_LIST(V) \ - ALLOCATION_SITE_MAPS_LIST(V) \ +#define READ_ONLY_ROOT_LIST(V) \ + STRONG_READ_ONLY_ROOT_LIST(V) \ + INTERNALIZED_STRING_ROOT_LIST(V) \ + PRIVATE_SYMBOL_ROOT_LIST(V) \ + PUBLIC_SYMBOL_ROOT_LIST(V) \ + WELL_KNOWN_SYMBOL_ROOT_LIST(V) \ + STRUCT_MAPS_LIST(V) \ + TORQUE_INTERNAL_CLASS_MAPS_LIST(V) \ + ALLOCATION_SITE_MAPS_LIST(V) \ DATA_HANDLER_MAPS_LIST(V) #define MUTABLE_ROOT_LIST(V) \ diff --git a/src/torque/class-debug-reader-generator.cc b/src/torque/class-debug-reader-generator.cc index 28623df64c..b4c8156bad 100644 --- a/src/torque/class-debug-reader-generator.cc +++ b/src/torque/class-debug-reader-generator.cc @@ -552,8 +552,7 @@ void ImplementationVisitor::GenerateClassDebugReaders( std::stringstream class_names; std::unordered_set done; - for (const TypeAlias* alias : GlobalContext::GetClasses()) { - const ClassType* type = ClassType::DynamicCast(alias->type()); + for (const ClassType* type : TypeOracle::GetClasses()) { GenerateClassDebugReader(*type, h_contents, cc_contents, visitor, class_names, &done); } diff --git a/src/torque/constants.h b/src/torque/constants.h index b0eb8e432f..90849a1c7c 100644 --- a/src/torque/constants.h +++ b/src/torque/constants.h @@ -71,6 +71,7 @@ static const char* const UNINITIALIZED_ITERATOR_TYPE_STRING = "UninitializedIterator"; static const char* const GENERIC_TYPE_INSTANTIATION_NAMESPACE_STRING = "_generic_type_instantiation_namespace"; +static const char* const FIXED_ARRAY_BASE_TYPE_STRING = "FixedArrayBase"; static const char* const ANNOTATION_GENERATE_PRINT = "@generatePrint"; static const char* const ANNOTATION_NO_VERIFIER = "@noVerifier"; @@ -88,6 +89,9 @@ static const char* const ANNOTATION_INSTANCE_TYPE_VALUE = "@apiExposedInstanceTypeValue"; static const char* const ANNOTATION_IF = "@if"; static const char* const ANNOTATION_IFNOT = "@ifnot"; +static const char* const ANNOTATION_GENERATE_BODY_DESCRIPTOR = + "@generateBodyDescriptor"; +static const char* const ANNOTATION_EXPORT_CPP_CLASS = "@export"; inline bool IsConstexprName(const std::string& name) { return name.substr(0, std::strlen(CONSTEXPR_TYPE_PREFIX)) == @@ -125,6 +129,8 @@ enum class ClassFlag { kHighestInstanceTypeWithinParent = 1 << 9, kLowestInstanceTypeWithinParent = 1 << 10, kUndefinedLayout = 1 << 11, + kGenerateBodyDescriptor = 1 << 12, + kExport = 1 << 13, }; using ClassFlags = base::Flags; diff --git a/src/torque/global-context.h b/src/torque/global-context.h index bb84f9bdf4..bbfbb686ef 100644 --- a/src/torque/global-context.h +++ b/src/torque/global-context.h @@ -35,15 +35,6 @@ class GlobalContext : public ContextualClass { return Get().declarables_; } - static void RegisterClass(const TypeAlias* alias) { - DCHECK(alias->ParentScope()->IsNamespace()); - Get().classes_.push_back(alias); - } - - using GlobalClassList = std::vector; - - static const GlobalClassList& GetClasses() { return Get().classes_; } - static void AddCppInclude(std::string include_path) { Get().cpp_includes_.insert(std::move(include_path)); } @@ -84,7 +75,6 @@ class GlobalContext : public ContextualClass { std::vector> declarables_; std::set cpp_includes_; std::map generated_per_file_; - GlobalClassList classes_; std::map fresh_ids_; friend class LanguageServerData; diff --git a/src/torque/implementation-visitor.cc b/src/torque/implementation-visitor.cc index c5c3173ad9..ff1a33030a 100644 --- a/src/torque/implementation-visitor.cc +++ b/src/torque/implementation-visitor.cc @@ -1482,7 +1482,7 @@ VisitResult ImplementationVisitor::Visit(NewExpression* expr) { VisitResult(TypeOracle::GetConstexprInstanceTypeType(), CapifyStringWithUnderscores(class_type->name()) + "_TYPE")); object_map = GenerateCall( - QualifiedName({TORQUE_INTERNAL_NAMESPACE_STRING}, "GetStructMap"), + QualifiedName({TORQUE_INTERNAL_NAMESPACE_STRING}, "GetInstanceTypeMap"), get_struct_map_arguments, {}, false); CurrentSourcePosition::Scope current_pos(expr->pos); initializer_results.names.insert(initializer_results.names.begin(), @@ -3061,9 +3061,9 @@ class FieldOffsetsGenerator { UpdateSection(f); // Emit kHeaderSize before any indexed field. - // TODO(tebbi): Generalize this code to work with multiple indexed fields. - if (f.index.has_value()) { + if (f.index.has_value() && !header_size_emitted_) { WriteMarker("kHeaderSize"); + header_size_emitted_ = true; } // We don't know statically how much space an indexed field takes, so report @@ -3165,6 +3165,7 @@ class FieldOffsetsGenerator { FieldSectionType current_section_ = FieldSectionType::kNoSection; FieldSections completed_sections_ = FieldSectionType::kNoSection; bool is_finished_ = false; + bool header_size_emitted_ = false; }; class MacroFieldOffsetsGenerator : public FieldOffsetsGenerator { @@ -3187,48 +3188,23 @@ class MacroFieldOffsetsGenerator : public FieldOffsetsGenerator { std::ostream& out_; }; -} // namespace - -void ImplementationVisitor::GenerateCppForInternalClasses( - const std::string& output_directory) { - std::stringstream header; - std::stringstream inl; - std::string base_name = "internal-class-definitions-tq"; - { - IncludeGuardScope header_guard(header, base_name + ".h"); - header << "#include \"src/objects/objects.h\"\n"; - header << "#include \"src/objects/struct.h\"\n"; - header << "#include \"src/objects/js-objects.h\"\n"; - header << "#include \"src/utils/utils.h\"\n"; - header << "#include \"torque-generated/class-definitions-tq.h\"\n"; - IncludeObjectMacrosScope header_macros(header); - NamespaceScope header_namespaces(header, {"v8", "internal"}); - - IncludeGuardScope inl_guard(inl, base_name + "-inl.h"); - inl << "#include \"torque-generated/" << base_name << ".h\"\n"; - inl << "#include \"torque-generated/class-definitions-tq-inl.h\"\n"; - IncludeObjectMacrosScope inl_macros(inl); - NamespaceScope inl_namespaces(inl, {"v8", "internal"}); - - for (const TypeAlias* alias : GlobalContext::GetClasses()) { - const ClassType* type = ClassType::DynamicCast(alias->type()); - if (type->IsExtern()) continue; - const ClassType* super = type->GetSuperClass(); - std::string parent = "TorqueGenerated" + type->name() + "<" + - type->name() + ", " + super->name() + ">"; - header << "class " << type->name() << ": public " << parent << " {\n"; - header << " public:\n"; - header << " TQ_OBJECT_CONSTRUCTORS(" << type->name() << ")\n"; - header << "};\n\n"; - - inl << "TQ_OBJECT_CONSTRUCTORS_IMPL(" << type->name() << ")\n"; - } +void GenerateClassExport(const ClassType* type, std::ostream& header, + std::ostream& inl_header) { + const ClassType* super = type->GetSuperClass(); + std::string parent = "TorqueGenerated" + type->name() + "<" + type->name() + + ", " + super->name() + ">"; + header << "class " << type->name() << " : public " << parent << " {\n"; + header << " public:\n"; + if (type->ShouldGenerateBodyDescriptor()) { + header << " class BodyDescriptor;\n"; } - std::string dir_basename = output_directory + "/" + base_name; - WriteFile(dir_basename + ".h", header.str()); - WriteFile(dir_basename + "-inl.h", inl.str()); + header << " TQ_OBJECT_CONSTRUCTORS(" << type->name() << ")\n"; + header << "};\n\n"; + inl_header << "TQ_OBJECT_CONSTRUCTORS_IMPL(" << type->name() << ")\n"; } +} // namespace + void ImplementationVisitor::GenerateClassFieldOffsets( const std::string& output_directory) { std::stringstream header; @@ -3236,9 +3212,7 @@ void ImplementationVisitor::GenerateClassFieldOffsets( { IncludeGuardScope include_guard(header, file_name); - for (const TypeAlias* alias : GlobalContext::GetClasses()) { - const ClassType* type = ClassType::DynamicCast(alias->type()); - + for (const ClassType* type : TypeOracle::GetClasses()) { // TODO(danno): Remove this once all classes use ClassFieldOffsetGenerator // to generate field offsets without the use of macros. if (!type->GenerateCppClassDefinitions() && !type->HasUndefinedLayout()) { @@ -3251,6 +3225,16 @@ void ImplementationVisitor::GenerateClassFieldOffsets( header << "\n"; } } + + header << "#define TORQUE_BODY_DESCRIPTOR_LIST_GENERATOR(V, _)\\\n"; + for (const ClassType* type : TypeOracle::GetClasses()) { + if (type->ShouldGenerateBodyDescriptor()) { + std::string type_name = + CapifyStringWithUnderscores(type->name()) + "_TYPE"; + header << "V(_, " << type_name << ", " << type->name() << ")\\\n"; + } + } + header << "\n"; } const std::string output_header_path = output_directory + "/" + file_name; WriteFile(output_header_path, header.str()); @@ -3366,6 +3350,29 @@ class CppClassGenerator { std::ostream& impl_; }; +base::Optional> GetOrderedUniqueIndexFields( + const ClassType& type) { + std::vector result; + std::set index_names; + for (const Field& field : type.ComputeAllFields()) { + if (field.index) { + auto name_and_type = ExtractSimpleFieldArraySize(type, *field.index); + if (!name_and_type) { + return base::nullopt; + } + index_names.insert(name_and_type->name); + } + } + + for (const Field& field : type.ComputeAllFields()) { + if (index_names.count(field.name_and_type.name) != 0) { + result.push_back(field); + } + } + + return result; +} + void CppClassGenerator::GenerateClass() { hdr_ << template_decl() << "\n"; hdr_ << "class " << gen_name_ << " : public P {\n"; @@ -3375,10 +3382,16 @@ void CppClassGenerator::GenerateClass() { << " \"Pass in " << super_->name() << " as second template parameter for " << gen_name_ << ".\");\n"; hdr_ << " public: \n"; - hdr_ << " using Super = P;\n"; + hdr_ << " using Super = P;\n\n"; + if (!type_->ShouldExport() && !type_->IsExtern()) { + hdr_ << " protected: // not extern or @export\n"; + } for (const Field& f : type_->fields()) { GenerateFieldAccessor(f); } + if (!type_->ShouldExport() && !type_->IsExtern()) { + hdr_ << " public:\n"; + } GenerateClassCasts(); @@ -3410,9 +3423,82 @@ void CppClassGenerator::GenerateClass() { g.Finish(); hdr_ << "\n"; + auto index_fields = GetOrderedUniqueIndexFields(*type_); + + if (!index_fields.has_value()) { + hdr_ << " // SizeFor implementations not generated due to complex array " + "lengths\n\n"; + } else if (!type_->IsAbstract() && + !type_->IsSubtypeOf(TypeOracle::GetJSObjectType())) { + hdr_ << " V8_INLINE static constexpr int32_t SizeFor("; + bool first = true; + for (const Field& field : *index_fields) { + if (!first) hdr_ << ", "; + hdr_ << field.name_and_type.type->HandlifiedCppTypeName() << " " + << field.name_and_type.name; + first = false; + } + hdr_ << ") {\n"; + if (index_fields->empty()) { + hdr_ << " DCHECK(kHeaderSize == kSize && kHeaderSize == " + << *type_->size().SingleValue() << ");\n"; + } + hdr_ << " int32_t size = kHeaderSize;\n"; + for (const Field& field : type_->ComputeAllFields()) { + if (field.index) { + auto index_name_and_type = + *ExtractSimpleFieldArraySize(*type_, *field.index); + size_t field_size = 0; + std::tie(field_size, std::ignore) = field.GetFieldSizeInformation(); + hdr_ << " size += "; + auto index_field = std::find_if( + index_fields->begin(), index_fields->end(), + [&](const Field& field) { + return field.name_and_type.name == index_name_and_type.name; + }); + if (index_field->name_and_type.type->IsSubtypeOf( + TypeOracle::GetSmiType())) { + hdr_ << "Smi::ToInt(" << index_name_and_type.name << ")"; + } else { + hdr_ << index_name_and_type.name; + } + hdr_ << " * " << field_size << ";\n"; + } + } + hdr_ << " return size;\n"; + hdr_ << " }\n\n"; + hdr_ << " V8_INLINE static constexpr int32_t SizeFor(D o) {\n"; + hdr_ << " return SizeFor("; + first = true; + for (auto field : *index_fields) { + if (!first) hdr_ << ", "; + // Subclasses of FixedArrayBase need to use the synchronized length + // accessor to be consistent (theoretically, FixedArrayBase classes + // can concurrently change size e.g. through left-trimming, although + // in practice this won't happen for Torque-generated classes) as well as + // explicitly convert to a Smi, since the C++-side accessors are + // int-based. + if (field.aggregate == TypeOracle::GetFixedArrayBaseType() && + field.name_and_type.name == "length") { + hdr_ << "Smi::FromInt(o.synchronized_length())"; + } else { + hdr_ << "o." << field.name_and_type.name << "()"; + } + first = false; + } + hdr_ << ");\n }\n"; + hdr_ << "\n"; + } + + hdr_ << " friend class Factory;\n\n"; + GenerateClassConstructors(); hdr_ << "};\n\n"; + + if (!type_->IsExtern()) { + GenerateClassExport(type_, hdr_, inl_); + } } void CppClassGenerator::GenerateClassCasts() { @@ -3448,7 +3534,11 @@ void CppClassGenerator::GenerateClassConstructors() { // TODO(sigurds): Keep in sync with DECL_ACCESSORS and ACCESSORS macro. void CppClassGenerator::GenerateFieldAccessor(const Field& f) { const Type* field_type = f.name_and_type.type; - if (field_type == TypeOracle::GetVoidType() || f.index.has_value()) return; + if (field_type == TypeOracle::GetVoidType()) return; + + // TODO(danno): Support generation of struct accessors + if (f.name_and_type.type->IsStructType()) return; + if (!f.name_and_type.type->IsSubtypeOf(TypeOracle::GetTaggedType())) { return GenerateFieldAccessorForUntagged(f); } @@ -3460,7 +3550,8 @@ void CppClassGenerator::GenerateFieldAccessor(const Field& f) { } Error("Generation of field accessor for ", type_->name(), - ":: ", f.name_and_type.name, " : ", *field_type, " is not supported.") + "::", f.name_and_type.name, " failed (type ", *field_type, + " is not supported).") .Position(f.pos); } @@ -3479,24 +3570,53 @@ void CppClassGenerator::GenerateFieldAccessorForUntagged(const Field& f) { } const std::string& name = f.name_and_type.name; const std::string type = constexpr_version->GetGeneratedTypeName(); - const std::string offset = "k" + CamelifyString(name) + "Offset"; + std::string offset = "k" + CamelifyString(name) + "Offset"; // Generate declarations in header. - hdr_ << " inline " << type << " " << name << "() const;\n"; - hdr_ << " inline void set_" << name << "(" << type << " value);\n\n"; + if (f.index) { + hdr_ << " inline " << type << " " << name << "(int i) const;\n"; + hdr_ << " inline void set_" << name << "(int i, " << type + << " value);\n\n"; + } else { + hdr_ << " inline " << type << " " << name << "() const;\n"; + hdr_ << " inline void set_" << name << "(" << type << " value);\n\n"; + } // Generate implementation in inline header. inl_ << "template \n"; - inl_ << type << " " << gen_name_ << "::" << name << "() const {\n"; - inl_ << " return this->template ReadField<" << type << ">(" << offset - << ");\n"; + inl_ << type << " " << gen_name_ << "::" << name << "("; + if (f.index) { + inl_ << "int i"; + } + inl_ << ") const {\n"; + if (f.index) { + size_t field_size; + std::string size_string; + std::tie(field_size, size_string) = f.GetFieldSizeInformation(); + inl_ << " int offset = " << offset << " + i * " << field_size << ";\n"; + inl_ << " return this->template ReadField<" << type << ">(offset);\n"; + } else { + inl_ << " return this->template ReadField<" << type << ">(" << offset + << ");\n"; + } inl_ << "}\n"; inl_ << "template \n"; - inl_ << "void " << gen_name_ << "::set_" << name << "(" << type - << " value) {\n"; - inl_ << " this->template WriteField<" << type << ">(" << offset - << ", value);\n"; + inl_ << "void " << gen_name_ << "::set_" << name << "("; + if (f.index) { + inl_ << "int i, "; + } + inl_ << type << " value) {\n"; + if (f.index) { + size_t field_size; + std::string size_string; + std::tie(field_size, size_string) = f.GetFieldSizeInformation(); + inl_ << " int offset = " << offset << " + i * " << field_size << ";\n"; + inl_ << " this->template WriteField<" << type << ">(offset, value);\n"; + } else { + inl_ << " this->template WriteField<" << type << ">(" << offset + << ", value);\n"; + } inl_ << "}\n\n"; } @@ -3507,20 +3627,43 @@ void CppClassGenerator::GenerateFieldAccessorForSmi(const Field& f) { const std::string offset = "k" + CamelifyString(name) + "Offset"; // Generate declarations in header. + if (f.index) { + hdr_ << " inline " << type << " " << name << "(int i) const;\n"; + hdr_ << " inline void set_" << name << "(int i, " << type + << " value);\n\n"; + } hdr_ << " inline " << type << " " << name << "() const;\n"; hdr_ << " inline void set_" << name << "(" << type << " value);\n\n"; // Generate implementation in inline header. inl_ << "template \n"; - inl_ << type << " " << gen_name_ << "::" << name << "() const {\n"; - inl_ << " return TaggedField::load(*this);\n"; - inl_ << "}\n"; + inl_ << type << " " << gen_name_ << "::" << name << "("; + if (f.index) { + inl_ << "int i"; + } + inl_ << ") const {\n"; + if (f.index) { + inl_ << " int offset = " << offset << " + i * kTaggedSize;\n"; + inl_ << " return this->template ReadField(offset);\n"; + inl_ << "}\n"; + } else { + inl_ << " return TaggedField::load(*this);\n"; + inl_ << "}\n"; + } inl_ << "template \n"; - inl_ << "void " << gen_name_ << "::set_" << name << "(" << type - << " value) {\n"; + inl_ << "void " << gen_name_ << "::set_" << name << "("; + if (f.index) { + inl_ << "int i, "; + } + inl_ << type << " value) {\n"; inl_ << " DCHECK(value.IsSmi());\n"; - inl_ << " WRITE_FIELD(*this, " << offset << ", value);\n"; + if (f.index) { + inl_ << " int offset = " << offset << " + i * kTaggedSize;\n"; + inl_ << " WRITE_FIELD(*this, offset, value);\n"; + } else { + inl_ << " WRITE_FIELD(*this, " << offset << ", value);\n"; + } inl_ << "}\n\n"; } @@ -3538,11 +3681,13 @@ void CppClassGenerator::GenerateFieldAccessorForObject(const Field& f) { if (!class_type && field_type != TypeOracle::GetObjectType()) { hdr_ << " // Torque type: " << field_type->ToString() << "\n"; } - hdr_ << " inline " << type << " " << name << "() const;\n"; - hdr_ << " inline " << type << " " << name - << "(const Isolate* isolate) const;\n"; - hdr_ << " inline void set_" << name << "(" << type - << " value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);\n\n"; + + hdr_ << " inline " << type << " " << name << "(" << (f.index ? "int i" : "") + << ") const;\n"; + hdr_ << " inline " << type << " " << name << "(const Isolate* isolates" + << (f.index ? ", int i" : "") << ") const;\n"; + hdr_ << " inline void set_" << name << "(" << (f.index ? "int i, " : "") + << type << " value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);\n\n"; std::string type_check; for (const RuntimeType& runtime_type : field_type->GetRuntimeTypes()) { @@ -3552,36 +3697,89 @@ void CppClassGenerator::GenerateFieldAccessorForObject(const Field& f) { // Generate implementation in inline header. inl_ << "template \n"; - inl_ << type << " " << gen_name_ << "::" << name << "() const {\n"; + inl_ << type << " " << gen_name_ << "::" << name << "(" + << (f.index ? "int i" : "") << ") const {\n"; inl_ << " const Isolate* isolate = GetIsolateForPtrCompr(*this);\n"; - inl_ << " return " << gen_name_ << "::" << name << "(isolate);\n"; + inl_ << " return " << gen_name_ << "::" << name << "(isolate" + << (f.index ? ", i" : "") << ");\n"; inl_ << "}\n"; inl_ << "template \n"; inl_ << type << " " << gen_name_ << "::" << name - << "(const Isolate* isolate) const {\n"; + << "(const Isolate* isolate" << (f.index ? ", int i" : "") + << ") const {\n"; + if (class_type) { - inl_ << " return TaggedField<" << type << ", " << offset - << ">::load(isolate, *this);\n"; + if (f.index) { + inl_ << " int offset = " << offset << " + i * kTaggedSize;\n"; + inl_ << " return " << type + << "::cast(RELAXED_READ_FIELD(*this, offset));\n"; + } else { + inl_ << " return TaggedField<" << type << ", " << offset + << ">::load(isolate, *this);\n"; + } } else { // TODO(tebbi): load value as HeapObject when possible - inl_ << " Object value = TaggedField::load(isolate, *this);\n"; + if (f.index) { + inl_ << " int offset = " << offset << " + i * kTaggedSize;\n"; + inl_ << " Object value = Object::cast(RELAXED_READ_FIELD(*this, " + "offset));\n"; + } else { + inl_ << " Object value = TaggedField::load(isolate, *this);\n"; + } inl_ << " DCHECK(" << type_check << ");\n"; inl_ << " return value;\n"; } inl_ << "}\n"; inl_ << "template \n"; - inl_ << "void " << gen_name_ << "::set_" << name << "(" << type - << " value, WriteBarrierMode mode) {\n"; + inl_ << "void " << gen_name_ << "::set_" << name << "("; + if (f.index) { + inl_ << "int i, "; + } + inl_ << type << " value, WriteBarrierMode mode) {\n"; inl_ << " SLOW_DCHECK(" << type_check << ");\n"; - inl_ << " WRITE_FIELD(*this, " << offset << ", value);\n"; + if (f.index) { + inl_ << " int offset = " << offset << " + i * kTaggedSize;\n"; + inl_ << " WRITE_FIELD(*this, offset, value);\n"; + } else { + inl_ << " WRITE_FIELD(*this, " << offset << ", value);\n"; + } inl_ << " CONDITIONAL_WRITE_BARRIER(*this, " << offset << ", value, mode);\n"; inl_ << "}\n\n"; } +void EmitClassDefinitionHeadersIncludes(const std::string& basename, + std::stringstream& header, + std::stringstream& inline_header) { + header << "#include \"src/objects/fixed-array.h\"\n"; + header << "#include \"src/objects/objects.h\"\n"; + header << "#include \"src/objects/smi.h\"\n"; + header << "#include \"torque-generated/field-offsets-tq.h\"\n"; + header << "#include \n\n"; + + inline_header << "#include \"torque-generated/class-definitions-tq.h\"\n"; + inline_header << "#include " + "\"torque-generated/objects-body-descriptors-tq-inl.h\"\n\n"; + inline_header << "#include \"src/objects/js-promise.h\"\n"; + inline_header << "#include \"src/objects/js-weak-refs.h\"\n"; + inline_header << "#include \"src/objects/module.h\"\n"; + inline_header << "#include \"src/objects/objects-inl.h\"\n"; + inline_header << "#include \"src/objects/script.h\"\n"; + inline_header << "#include \"src/objects/shared-function-info.h\"\n"; + inline_header << "#include \"src/objects/tagged-field.h\"\n\n"; +} + +void EmitClassDefinitionHeadersForwardDeclarations(std::stringstream& header) { + // Generate forward declarations for every class. + for (const ClassType* type : TypeOracle::GetClasses()) { + header << "class " << type->GetGeneratedTNodeTypeName() << ";\n"; + } + header << "using BuiltinPtr = Smi;\n\n"; +} + void GenerateStructLayoutDescription(std::ostream& header, const StructType* type) { header << "struct TorqueGenerated" << CamelifyString(type->name()) @@ -3599,32 +3797,70 @@ void GenerateStructLayoutDescription(std::ostream& header, void ImplementationVisitor::GenerateClassDefinitions( const std::string& output_directory) { - std::stringstream header; - std::stringstream inline_header; + std::stringstream external_header; + std::stringstream inline_external_header; + std::stringstream internal_header; + std::stringstream inline_internal_header; std::stringstream implementation; + std::stringstream factory_header; + std::stringstream factory_impl; std::string basename = "class-definitions-tq"; + std::string internal_basename = "internal-" + basename; std::string file_basename = output_directory + "/" + basename; + std::string internal_file_basename = + output_directory + "/" + internal_basename; + std::string factory_basename = "factory-tq"; + std::string factory_file_basename = output_directory + "/" + factory_basename; { - IncludeGuardScope header_guard(header, basename + ".h"); - header << "#include \"src/objects/objects.h\"\n"; - header << "#include \"src/objects/smi.h\"\n"; - header << "#include \"torque-generated/field-offsets-tq.h\"\n"; - header << "#include \n\n"; - IncludeObjectMacrosScope header_macros(header); - NamespaceScope header_namespaces(header, {"v8", "internal"}); - header << "using BuiltinPtr = Smi;\n\n"; + IncludeGuardScope header_guard(external_header, basename + ".h"); - IncludeGuardScope inline_header_guard(inline_header, basename + "-inl.h"); - inline_header << "#include \"torque-generated/class-definitions-tq.h\"\n\n"; - inline_header << "#include \"src/objects/js-promise.h\"\n"; - inline_header << "#include \"src/objects/js-weak-refs.h\"\n"; - inline_header << "#include \"src/objects/module.h\"\n"; - inline_header << "#include \"src/objects/objects-inl.h\"\n"; - inline_header << "#include \"src/objects/script.h\"\n"; - inline_header << "#include \"src/objects/shared-function-info.h\"\n\n"; - IncludeObjectMacrosScope inline_header_macros(inline_header); - NamespaceScope inline_header_namespaces(inline_header, {"v8", "internal"}); + IncludeGuardScope inline_header_guard(inline_external_header, + basename + "-inl.h"); + + IncludeGuardScope internal_header_guard(internal_header, + internal_basename + ".h"); + + IncludeGuardScope internal_inline_header_guard( + inline_internal_header, internal_basename + "-inl.h"); + + external_header + << "#include \"torque-generated/internal-class-definitions-tq.h\"\n"; + + EmitClassDefinitionHeadersIncludes(basename, external_header, + inline_external_header); + + EmitClassDefinitionHeadersIncludes(internal_basename, internal_header, + inline_internal_header); + + IncludeObjectMacrosScope header_macros(external_header); + IncludeObjectMacrosScope inline_header_macros(inline_external_header); + + IncludeObjectMacrosScope internal_header_macros(internal_header); + IncludeObjectMacrosScope internal_inline_header_macros( + inline_internal_header); + + NamespaceScope header_namespaces(external_header, {"v8", "internal"}); + NamespaceScope inline_header_namespaces(inline_external_header, + {"v8", "internal"}); + NamespaceScope internal_header_namespaces(internal_header, + {"v8", "internal"}); + NamespaceScope internal_inline_header_namespaces(inline_internal_header, + {"v8", "internal"}); + + EmitClassDefinitionHeadersForwardDeclarations(external_header); + EmitClassDefinitionHeadersForwardDeclarations(internal_header); + + factory_impl << "#include \"src/heap/factory.h\"\n"; + factory_impl << "#include \"src/heap/factory-inl.h\"\n"; + factory_impl << "#include \"src/heap/heap.h\"\n"; + factory_impl << "#include \"src/heap/heap-inl.h\"\n"; + factory_impl << "#include \"src/execution/isolate.h\"\n\n"; + factory_impl + << "#include " + "\"torque-generated/internal-class-definitions-tq-inl.h\"\n\n"; + NamespaceScope factory_impl_namespaces(factory_impl, {"v8", "internal"}); + factory_impl << "\n"; implementation << "#include \"torque-generated/class-definitions-tq.h\"\n\n"; @@ -3652,16 +3888,16 @@ void ImplementationVisitor::GenerateClassDefinitions( NamespaceScope implementation_namespaces(implementation, {"v8", "internal"}); - // Generate forward declarations for every class. - for (const TypeAlias* alias : GlobalContext::GetClasses()) { - const ClassType* type = ClassType::DynamicCast(alias->type()); - header << "class " << type->GetGeneratedTNodeTypeName() << ";\n"; - } - std::unordered_set structs_used_in_classes; - for (const TypeAlias* alias : GlobalContext::GetClasses()) { - const ClassType* type = ClassType::DynamicCast(alias->type()); + for (const ClassType* type : TypeOracle::GetClasses()) { + std::stringstream& header = (type->IsExtern() || type->ShouldExport()) + ? external_header + : internal_header; + std::stringstream& inline_header = + (type->IsExtern() || type->ShouldExport()) ? inline_external_header + : inline_internal_header; + if (type->GenerateCppClassDefinitions()) { CppClassGenerator g(type, header, inline_header, implementation); g.GenerateClass(); @@ -3673,17 +3909,92 @@ void ImplementationVisitor::GenerateClassDefinitions( structs_used_in_classes.insert(field_as_struct); } } + if (type->ShouldExport()) { + factory_header << type->HandlifiedCppTypeName() << " New" + << type->name() << "("; + factory_impl << type->HandlifiedCppTypeName() << " Factory::New" + << type->name() << "("; + + for (const Field& f : type->ComputeAllFields()) { + if (f.name_and_type.name == "map") continue; + if (!f.index) { + std::string type_string = + f.name_and_type.type->HandlifiedCppTypeName(); + factory_header << type_string << " " << f.name_and_type.name + << ", "; + factory_impl << type_string << " " << f.name_and_type.name << ", "; + } + } + + factory_header << "AllocationType allocation_type);\n"; + factory_impl << "AllocationType allocation_type) {\n"; + + factory_impl << " int size = "; + const ClassType* super = type->GetSuperClass(); + std::string gen_name = "TorqueGenerated" + type->name(); + std::string gen_name_T = + gen_name + "<" + type->name() + ", " + super->name() + ">"; + factory_impl << gen_name_T << "::SizeFor("; + + bool first = true; + auto index_fields = GetOrderedUniqueIndexFields(*type); + CHECK(index_fields.has_value()); + for (auto index_field : *index_fields) { + if (!first) { + factory_impl << ", "; + } + factory_impl << index_field.name_and_type.name; + first = false; + } + + factory_impl << ");\n"; + factory_impl << " ReadOnlyRoots roots(isolate());\n"; + factory_impl << " HeapObject result =\n"; + factory_impl << " " + "isolate()->heap()->AllocateRawWith" + "(size, allocation_type);\n"; + factory_impl << " result.set_map_after_allocation(roots." + << SnakeifyString(type->name()) + << "_map(), SKIP_WRITE_BARRIER);\n"; + factory_impl << " " << type->HandlifiedCppTypeName() + << " result_handle(" << type->name() + << "::cast(result), isolate());\n"; + + for (const Field& f : type->ComputeAllFields()) { + if (f.name_and_type.name == "map") continue; + if (!f.index) { + factory_impl << " result_handle->set_" + << SnakeifyString(f.name_and_type.name) << "("; + if (f.name_and_type.type->IsSubtypeOf( + TypeOracle::GetTaggedType()) && + !f.name_and_type.type->IsSubtypeOf(TypeOracle::GetSmiType())) { + factory_impl << "*" << f.name_and_type.name + << ", SKIP_WRITE_BARRIER"; + } else { + factory_impl << f.name_and_type.name; + } + factory_impl << ");\n"; + } + } + + factory_impl << " return result_handle;\n"; + factory_impl << "}\n\n"; + } } for (const StructType* type : structs_used_in_classes) { if (type != TypeOracle::GetFloat64OrHoleType()) { - GenerateStructLayoutDescription(header, type); + GenerateStructLayoutDescription(external_header, type); } } } - WriteFile(file_basename + ".h", header.str()); - WriteFile(file_basename + "-inl.h", inline_header.str()); + WriteFile(file_basename + ".h", external_header.str()); + WriteFile(file_basename + "-inl.h", inline_external_header.str()); WriteFile(file_basename + ".cc", implementation.str()); + WriteFile(internal_file_basename + ".h", internal_header.str()); + WriteFile(internal_file_basename + "-inl.h", inline_internal_header.str()); + WriteFile(factory_file_basename + ".inc", factory_header.str()); + WriteFile(factory_file_basename + ".cc", factory_impl.str()); } namespace { @@ -3700,8 +4011,17 @@ void GeneratePrintDefinitionsForClass(std::ostream& impl, const ClassType* type, for (const AggregateType* aggregate_type : hierarchy) { for (const Field& f : aggregate_type->fields()) { if (f.name_and_type.name == "map") continue; - impl << " os << \"\\n - " << f.name_and_type.name << ": \" << " - << "Brief(this->" << f.name_and_type.name << "());\n"; + if (!f.index.has_value()) { + if ((aggregate_type == TypeOracle::GetFixedArrayBaseType() && + f.name_and_type.name == "length") || + !f.name_and_type.type->IsSubtypeOf(TypeOracle::GetTaggedType())) { + impl << " os << \"\\n - " << f.name_and_type.name << ": \" << " + << "this->" << f.name_and_type.name << "();\n"; + } else { + impl << " os << \"\\n - " << f.name_and_type.name << ": \" << " + << "Brief(this->" << f.name_and_type.name << "());\n"; + } + } } } impl << " os << \"\\n\";\n"; @@ -3725,8 +4045,7 @@ void ImplementationVisitor::GeneratePrintDefinitions( NamespaceScope impl_namespaces(impl, {"v8", "internal"}); - for (const TypeAlias* alias : GlobalContext::GetClasses()) { - const ClassType* type = ClassType::DynamicCast(alias->type()); + for (const ClassType* type : TypeOracle::GetClasses()) { if (!type->ShouldGeneratePrint()) continue; if (type->GenerateCppClassDefinitions()) { @@ -3748,6 +4067,142 @@ void ImplementationVisitor::GeneratePrintDefinitions( WriteFile(output_directory + "/" + file_name, new_contents); } +void ImplementationVisitor::GenerateBodyDescriptors( + const std::string& output_directory) { + std::string file_name = "objects-body-descriptors-tq-inl"; + std::stringstream h_contents; + { + IncludeGuardScope include_guard(h_contents, file_name + ".h"); + + h_contents << "\n#include \"src/objects/objects-body-descriptors.h\"\n"; + h_contents << "\n#include \"torque-generated/class-definitions-tq.h\"\n"; + h_contents + << "\n#include \"torque-generated/internal-class-definitions-tq.h\"\n"; + h_contents << "\n#include " + "\"torque-generated/internal-class-definitions-tq-inl.h\"\n"; + + NamespaceScope h_namespaces(h_contents, {"v8", "internal"}); + + for (const ClassType* type : TypeOracle::GetClasses()) { + std::string name = type->name(); + if (!type->ShouldGenerateBodyDescriptor()) continue; + + const ClassType* super_class = type->GetSuperClass(); + std::string super_name = super_class->name(); + h_contents << "class " << name + << "::BodyDescriptor final : public BodyDescriptorBase {\n"; + + h_contents << " public:\n"; + + h_contents << " static bool IsValidSlot(Map map, HeapObject obj, int " + "offset) {\n"; + + if (super_class == TypeOracle::GetHeapObjectType() || + super_class == TypeOracle::GetFixedArrayBaseType()) { + h_contents << " if (offset < " << super_name + << "::kHeaderSize) return true;\n"; + } else { + h_contents << " if (" << super_name + << "::BodyDescriptor::IsValidSlot(map, obj, offset)) return " + "true;\n"; + } + + h_contents << " return offset >= " << name + << "::kStartOfStrongFieldsOffset" + << " && offset < " << name << "" + << "::kEndOfStrongFieldsOffset;\n"; + h_contents << " }\n\n"; + + h_contents << " template \n"; + h_contents << " static inline void IterateBody(Map map, HeapObject obj, " + "int object_size, ObjectVisitor* v) {\n"; + + // There may be MaybeObjects embedded in the strong pointer section, which + // are not suppored. + for (auto& f : type->fields()) { + for (const Type* t : LowerType(f.name_and_type.type)) { + if (t->IsSubtypeOf(TypeOracle::GetTaggedType()) && + !t->IsSubtypeOf(TypeOracle::GetObjectType())) { + Error("Cannot generate body descriptor for field ", + f.name_and_type.name, " of class ", name, " because ", *t, + " can contain tagged weak pointers."); + } + } + } + + if (super_class != TypeOracle::GetHeapObjectType() && + super_class != TypeOracle::GetFixedArrayBaseType()) { + h_contents + << " " << super_name + << "::BodyDescriptor::IterateBody(map, obj, object_size, v);\n"; + } + + h_contents << " if (" << name + << "::kStartOfStrongFieldsOffset != " << name + << "::kEndOfStrongFieldsOffset) {\n"; + h_contents << " IteratePointers(obj, " << name + << "::kStartOfStrongFieldsOffset, " << name + << "::kEndOfStrongFieldsOffset, v);\n"; + h_contents << " }\n"; + + h_contents << " if (" << name + << "::kStartOfWeakFieldsOffset != " << name + << "::kEndOfWeakFieldsOffset) {\n"; + h_contents << " IterateCustomWeakPointers(obj, " << name + << "::kStartOfWeakFieldsOffset, " << name + << "::kEndOfWeakFieldsOffset, v);\n"; + h_contents << " }\n"; + + // Since all of the index fields are at the end of the object and must + // only be Tagged values, emit only a single IteratePointers from the + // beginning of the first indexed field to the end of the object. + bool first_index_seen = false; + for (const Field& field : type->ComputeAllFields()) { + if (field.index && !first_index_seen) { + std::string indexed_field_name = + CamelifyString(field.name_and_type.name); + if (field.name_and_type.type->IsSubtypeOf( + TypeOracle::GetObjectType())) { + h_contents << " BodyDescriptorBase::IteratePointers(obj, " + << name << "::k" << indexed_field_name << "Offset, " + << name << "::SizeFor(" << name << "::cast(obj)), v);\n"; + } else { + Error( + "generating body descriptors for indexed fields not subtype of " + "Object isn't (yet) supported"); + } + first_index_seen = true; + } + if (first_index_seen) { + for (const Type* t : LowerType(field.name_and_type.type)) { + if (!t->IsSubtypeOf(TypeOracle::GetObjectType())) { + Error("cannot generate class body descriptor for \"", + type->name(), + "\", all fields of including and after the first indexed " + "member must no comprised only of subtypes of Object " + "(field \"", + field.name_and_type.name, "\" is not)"); + } + } + } + } + + h_contents << " }\n\n"; + + h_contents + << " static inline int SizeOf(Map map, HeapObject raw_object) {\n"; + h_contents << " " << name << " object = " << name + << "::cast(raw_object);\n"; + h_contents << " return " << name << "::SizeFor(object);\n"; + h_contents << " }\n\n"; + + h_contents << "};\n"; + } + } + + WriteFile(output_directory + "/" + file_name + ".h", h_contents.str()); +} + namespace { // Generate verification code for a single piece of class data, which might be @@ -3909,8 +4364,7 @@ void ImplementationVisitor::GenerateClassVerifiers( // Generate forward declarations to avoid including any headers. h_contents << "class Isolate;\n"; - for (const TypeAlias* alias : GlobalContext::GetClasses()) { - const ClassType* type = ClassType::DynamicCast(alias->type()); + for (const ClassType* type : TypeOracle::GetClasses()) { if (!type->ShouldGenerateVerify()) continue; h_contents << "class " << type->name() << ";\n"; } @@ -3920,8 +4374,7 @@ void ImplementationVisitor::GenerateClassVerifiers( h_contents << "class " << verifier_class << "{\n"; h_contents << " public:\n"; - for (const TypeAlias* alias : GlobalContext::GetClasses()) { - const ClassType* type = ClassType::DynamicCast(alias->type()); + for (const ClassType* type : TypeOracle::GetClasses()) { std::string name = type->name(); if (!type->ShouldGenerateVerify()) continue; diff --git a/src/torque/implementation-visitor.h b/src/torque/implementation-visitor.h index 0d58b19d46..49db6431cb 100644 --- a/src/torque/implementation-visitor.h +++ b/src/torque/implementation-visitor.h @@ -388,13 +388,13 @@ class ImplementationVisitor { void GenerateBitFields(const std::string& output_directory); void GeneratePrintDefinitions(const std::string& output_directory); void GenerateClassDefinitions(const std::string& output_directory); + void GenerateBodyDescriptors(const std::string& output_directory); void GenerateInstanceTypes(const std::string& output_directory); void GenerateClassVerifiers(const std::string& output_directory); void GenerateEnumVerifiers(const std::string& output_directory); void GenerateClassDebugReaders(const std::string& output_directory); void GenerateExportedMacrosAssembler(const std::string& output_directory); void GenerateCSATypes(const std::string& output_directory); - void GenerateCppForInternalClasses(const std::string& output_directory); VisitResult Visit(Expression* expr); const Type* Visit(Statement* stmt); diff --git a/src/torque/instance-type-generator.cc b/src/torque/instance-type-generator.cc index 3f1aec3777..a06c984629 100644 --- a/src/torque/instance-type-generator.cc +++ b/src/torque/instance-type-generator.cc @@ -289,6 +289,8 @@ std::unique_ptr AssignInstanceTypes() { // - fully_defined_single_instance_types: This list is pairs of class name and // instance type, for classes which have defined layouts and a single // corresponding instance type. +// - fully_defined_multiple_instance_types: This list is pairs of class name and +// instance type, for classes which have defined layouts and subclasses. // - only_declared_single_instance_types: This list is pairs of class name and // instance type, for classes which have a single corresponding instance type // and do not have layout definitions in Torque. @@ -302,6 +304,7 @@ std::unique_ptr AssignInstanceTypes() { void PrintInstanceTypes(InstanceTypeTree* root, std::ostream& definitions, std::ostream& values, std::ostream& fully_defined_single_instance_types, + std::ostream& fully_defined_multiple_instance_types, std::ostream& only_declared_single_instance_types, std::ostream& fully_defined_range_instance_types, std::ostream& only_declared_range_instance_types, @@ -331,6 +334,7 @@ void PrintInstanceTypes(InstanceTypeTree* root, std::ostream& definitions, for (auto& child : root->children) { PrintInstanceTypes( child.get(), definitions, values, fully_defined_single_instance_types, + fully_defined_multiple_instance_types, only_declared_single_instance_types, fully_defined_range_instance_types, only_declared_range_instance_types, inner_indent); } @@ -351,6 +355,11 @@ void PrintInstanceTypes(InstanceTypeTree* root, std::ostream& definitions, : fully_defined_range_instance_types; range_instance_types << " V(" << root->type->name() << ", FIRST_" << type_name << ", LAST_" << type_name << ") \\\n"; + if (!root->type->IsExtern() && !root->type->IsAbstract() && + !root->type->HasUndefinedLayout()) { + fully_defined_multiple_instance_types << " V(" << root->type->name() + << ", " << type_name << ") \\\n"; + } } } } @@ -370,12 +379,14 @@ void ImplementationVisitor::GenerateInstanceTypes( std::unique_ptr instance_types = AssignInstanceTypes(); std::stringstream values_list; std::stringstream fully_defined_single_instance_types; + std::stringstream fully_defined_multiple_instance_types; std::stringstream only_declared_single_instance_types; std::stringstream fully_defined_range_instance_types; std::stringstream only_declared_range_instance_types; if (instance_types != nullptr) { PrintInstanceTypes(instance_types.get(), header, values_list, fully_defined_single_instance_types, + fully_defined_multiple_instance_types, only_declared_single_instance_types, fully_defined_range_instance_types, only_declared_range_instance_types, " "); @@ -394,6 +405,12 @@ void ImplementationVisitor::GenerateInstanceTypes( header << fully_defined_single_instance_types.str(); header << "\n"; + header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that have\n"; + header << "// full Torque definitions and subclasses.\n"; + header << "#define TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(V) \\\n"; + header << fully_defined_multiple_instance_types.str(); + header << "\n"; + header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that are\n"; header << "// declared but not defined in Torque. These classes may\n"; header << "// correspond with actual C++ classes, but they are not\n"; @@ -416,10 +433,9 @@ void ImplementationVisitor::GenerateInstanceTypes( header << only_declared_range_instance_types.str(); header << "\n"; - header << "// Instance types for Torque-internal classes.\n"; - header << "#define TORQUE_INTERNAL_INSTANCE_TYPES(V) \\\n"; - for (const TypeAlias* alias : GlobalContext::GetClasses()) { - const ClassType* type = ClassType::DynamicCast(alias->type()); + header << "// Instance types for non-extern Torque classes.\n"; + header << "#define TORQUE_INSTANCE_TYPES(V) \\\n"; + for (const ClassType* type : TypeOracle::GetClasses()) { if (type->IsExtern()) continue; std::string type_name = CapifyStringWithUnderscores(type->name()) + "_TYPE"; @@ -427,11 +443,11 @@ void ImplementationVisitor::GenerateInstanceTypes( } header << "\n"; - header << "// Struct list entries for Torque-internal classes.\n"; - header << "#define TORQUE_STRUCT_LIST_GENERATOR(V, _) \\\n"; - for (const TypeAlias* alias : GlobalContext::GetClasses()) { - const ClassType* type = ClassType::DynamicCast(alias->type()); + header << "// Map list macros for non-extern Torque classes.\n"; + header << "#define TORQUE_INTERNAL_VARSIZE_CLASS_LIST_GENERATOR(V, _) \\\n"; + for (const ClassType* type : TypeOracle::GetClasses()) { if (type->IsExtern()) continue; + if (!type->HasIndexedField()) continue; std::string type_name = CapifyStringWithUnderscores(type->name()) + "_TYPE"; std::string variable_name = SnakeifyString(type->name()); @@ -439,6 +455,21 @@ void ImplementationVisitor::GenerateInstanceTypes( << variable_name << ") \\\n"; } header << "\n"; + header << "#define TORQUE_INTERNAL_FIXED_CLASS_LIST_GENERATOR(V, _) \\\n"; + for (const ClassType* type : TypeOracle::GetClasses()) { + if (type->IsExtern()) continue; + if (type->HasIndexedField()) continue; + std::string type_name = + CapifyStringWithUnderscores(type->name()) + "_TYPE"; + std::string variable_name = SnakeifyString(type->name()); + header << " V(_, " << type_name << ", " << type->name() << ", " + << variable_name << ") \\\n"; + } + header << "\n"; + header << "#define TORQUE_INTERNAL_CLASS_LIST_GENERATOR(V, _) \\\n"; + header << " TORQUE_INTERNAL_VARSIZE_CLASS_LIST_GENERATOR(V, _) \\\n"; + header << " TORQUE_INTERNAL_FIXED_CLASS_LIST_GENERATOR(V, _)\n"; + header << "\n"; } std::string output_header_path = output_directory + "/" + file_name; WriteFile(output_header_path, header.str()); diff --git a/src/torque/torque-compiler.cc b/src/torque/torque-compiler.cc index cb41cff946..ad7d906d54 100644 --- a/src/torque/torque-compiler.cc +++ b/src/torque/torque-compiler.cc @@ -88,10 +88,10 @@ void CompileCurrentAst(TorqueCompilerOptions options) { implementation_visitor.GenerateClassVerifiers(output_directory); implementation_visitor.GenerateClassDebugReaders(output_directory); implementation_visitor.GenerateEnumVerifiers(output_directory); + implementation_visitor.GenerateBodyDescriptors(output_directory); implementation_visitor.GenerateExportedMacrosAssembler(output_directory); implementation_visitor.GenerateCSATypes(output_directory); implementation_visitor.GenerateInstanceTypes(output_directory); - implementation_visitor.GenerateCppForInternalClasses(output_directory); implementation_visitor.EndCSAFiles(); implementation_visitor.GenerateImplementation(output_directory); diff --git a/src/torque/torque-parser.cc b/src/torque/torque-parser.cc index 91a278c137..d2405fc57c 100644 --- a/src/torque/torque-parser.cc +++ b/src/torque/torque-parser.cc @@ -549,9 +549,24 @@ base::Optional MakeIntrinsicDeclaration( return ParseResult{result}; } +namespace { +bool HasExportAnnotation(ParseResultIterator* child_results, + const char* declaration) { + auto annotations = child_results->NextAs>(); + if (annotations.size()) { + if (annotations.size() > 1 || annotations[0].name->value != "@export") { + Error(declaration, + " declarations only support a single @export annotation"); + } + return true; + } + return false; +} +} // namespace + base::Optional MakeTorqueMacroDeclaration( ParseResultIterator* child_results) { - auto export_to_csa = child_results->NextAs(); + bool export_to_csa = HasExportAnnotation(child_results, "macro"); auto transitioning = child_results->NextAs(); auto operator_name = child_results->NextAs>(); auto name = child_results->NextAs(); @@ -835,7 +850,8 @@ base::Optional MakeClassDeclaration( child_results, {ANNOTATION_GENERATE_PRINT, ANNOTATION_NO_VERIFIER, ANNOTATION_ABSTRACT, ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT, - ANNOTATION_GENERATE_CPP_CLASS, + ANNOTATION_GENERATE_CPP_CLASS, ANNOTATION_GENERATE_BODY_DESCRIPTOR, + ANNOTATION_EXPORT_CPP_CLASS, ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT, ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT}, {ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE, @@ -854,6 +870,12 @@ base::Optional MakeClassDeclaration( if (annotations.Contains(ANNOTATION_GENERATE_CPP_CLASS)) { flags |= ClassFlag::kGenerateCppClassDefinitions; } + if (annotations.Contains(ANNOTATION_GENERATE_BODY_DESCRIPTOR)) { + flags |= ClassFlag::kGenerateBodyDescriptor; + } + if (annotations.Contains(ANNOTATION_EXPORT_CPP_CLASS)) { + flags |= ClassFlag::kExport; + } if (annotations.Contains(ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT)) { flags |= ClassFlag::kHighestInstanceTypeWithinParent; } @@ -945,7 +967,8 @@ base::Optional MakeSpecializationDeclaration( base::Optional MakeStructDeclaration( ParseResultIterator* child_results) { - bool is_export = child_results->NextAs(); + bool is_export = HasExportAnnotation(child_results, "Struct"); + StructFlags flags = StructFlag::kNone; if (is_export) flags |= StructFlag::kExport; @@ -2322,7 +2345,7 @@ struct TorqueGrammar : Grammar { Sequence({Token("generates"), &externalString})), &optionalClassBody}, AsSingletonVector()), - Rule({CheckIf(Token("@export")), Token("struct"), &name, + Rule({annotations, Token("struct"), &name, TryOrDefault(&genericParameters), Token("{"), List(&method), List(&structField), Token("}")}, @@ -2363,7 +2386,7 @@ struct TorqueGrammar : Grammar { Rule({Token("extern"), CheckIf(Token("transitioning")), Token("runtime"), &name, &typeListMaybeVarArgs, &optionalReturnType, Token(";")}, AsSingletonVector()), - Rule({CheckIf(Token("@export")), CheckIf(Token("transitioning")), + Rule({annotations, CheckIf(Token("transitioning")), Optional( Sequence({Token("operator"), &externalString})), Token("macro"), &name, diff --git a/src/torque/type-oracle.cc b/src/torque/type-oracle.cc index 0e5a8a7b6b..845ddf3659 100644 --- a/src/torque/type-oracle.cc +++ b/src/torque/type-oracle.cc @@ -4,6 +4,7 @@ #include "src/torque/type-oracle.h" #include "src/torque/type-visitor.h" +#include "src/torque/types.h" namespace v8 { namespace internal { @@ -68,6 +69,17 @@ Namespace* TypeOracle::CreateGenericTypeInstantiationNamespace() { return Get().generic_type_instantiation_namespaces_.back().get(); } +// static +std::vector TypeOracle::GetClasses() { + std::vector result; + for (const std::unique_ptr& t : Get().aggregate_types_) { + if (auto* class_type = ClassType::DynamicCast(t.get())) { + result.push_back(class_type); + } + } + return result; +} + } // namespace torque } // namespace internal } // namespace v8 diff --git a/src/torque/type-oracle.h b/src/torque/type-oracle.h index e553f14d3f..8a39b51ed0 100644 --- a/src/torque/type-oracle.h +++ b/src/torque/type-oracle.h @@ -293,6 +293,10 @@ class TypeOracle : public ContextualClass { return Get().GetBuiltinType(UNINITIALIZED_ITERATOR_TYPE_STRING); } + static const Type* GetFixedArrayBaseType() { + return Get().GetBuiltinType(FIXED_ARRAY_BASE_TYPE_STRING); + } + static base::Optional ImplicitlyConvertableFrom( const Type* to, const Type* from) { while (from != nullptr) { @@ -315,6 +319,10 @@ class TypeOracle : public ContextualClass { static const std::vector>& GetBitFieldStructTypes(); + // By construction, this list of all classes is topologically sorted w.r.t. + // inheritance. + static std::vector GetClasses(); + static void FinalizeAggregateTypes(); static size_t FreshTypeId() { return Get().next_type_id_++; } diff --git a/src/torque/type-visitor.cc b/src/torque/type-visitor.cc index 2a44b57d54..9780d2d5ae 100644 --- a/src/torque/type-visitor.cc +++ b/src/torque/type-visitor.cc @@ -244,81 +244,83 @@ const StructType* TypeVisitor::ComputeType( const ClassType* TypeVisitor::ComputeType( ClassDeclaration* decl, MaybeSpecializationKey specialized_from) { - ClassType* new_class; // TODO(sigurds): Remove this hack by introducing a declarable for classes. const TypeAlias* alias = Declarations::LookupTypeAlias(QualifiedName(decl->name->value)); - GlobalContext::RegisterClass(alias); DCHECK_EQ(*alias->delayed_, decl); - bool is_shape = decl->flags & ClassFlag::kIsShape; - if (is_shape && !(decl->flags & ClassFlag::kExtern)) { - ReportError("Shapes must be extern, add \"extern\" to the declaration."); + ClassFlags flags = decl->flags; + bool is_shape = flags & ClassFlag::kIsShape; + std::string generates = decl->name->value; + const Type* super_type = TypeVisitor::ComputeType(*decl->super); + if (is_shape) { + if (!(flags & ClassFlag::kExtern)) { + ReportError("Shapes must be extern, add \"extern\" to the declaration."); + } + if (flags & ClassFlag::kUndefinedLayout) { + ReportError("Shapes need to define their layout."); + } + const ClassType* super_class = ClassType::DynamicCast(super_type); + if (!super_class || + !super_class->IsSubtypeOf(TypeOracle::GetJSObjectType())) { + Error("Shapes need to extend a subclass of ", + *TypeOracle::GetJSObjectType()) + .Throw(); + } + // Shapes use their super class in CSA code since they have incomplete + // support for type-checks on the C++ side. + generates = super_class->name(); } - if (is_shape && decl->flags & ClassFlag::kUndefinedLayout) { - ReportError("Shapes need to define their layout."); + if (!decl->super) { + ReportError("Extern class must extend another type."); } - if (decl->flags & ClassFlag::kExtern) { - if (!decl->super) { - ReportError("Extern class must extend another type."); + if (super_type != TypeOracle::GetStrongTaggedType()) { + const ClassType* super_class = ClassType::DynamicCast(super_type); + if (!super_class) { + ReportError( + "class \"", decl->name->value, + "\" must extend either StrongTagged or an already declared class"); } - const Type* super_type = TypeVisitor::ComputeType(*decl->super); - if (super_type != TypeOracle::GetStrongTaggedType()) { - const ClassType* super_class = ClassType::DynamicCast(super_type); - if (!super_class) { - ReportError( - "class \"", decl->name->value, - "\" must extend either StrongTagged or an already declared class"); - } - if (super_class->HasUndefinedLayout() && - !(decl->flags & ClassFlag::kUndefinedLayout)) { - Error("Class \"", decl->name->value, - "\" defines its layout but extends a class which does not") - .Position(decl->pos); - } + if (super_class->HasUndefinedLayout() && + !(flags & ClassFlag::kUndefinedLayout)) { + Error("Class \"", decl->name->value, + "\" defines its layout but extends a class which does not") + .Position(decl->pos); } - - std::string generates = decl->name->value; - if (is_shape) { - const ClassType* super_class = ClassType::DynamicCast(super_type); - if (!super_class || - !super_class->IsSubtypeOf(TypeOracle::GetJSObjectType())) { - Error("Shapes need to extend a subclass of ", - *TypeOracle::GetJSObjectType()) - .Throw(); - } - // Shapes use their super class in CSA code since they have incomplete - // support for type-checks on the C++ side. - generates = super_class->name(); + if ((flags & ClassFlag::kExport) && + !(super_class->ShouldExport() || super_class->IsExtern())) { + Error("cannot export class ", decl->name, + " because superclass is neither @export or extern"); } + } + if ((flags & ClassFlag::kGenerateBodyDescriptor || + flags & ClassFlag::kExport) && + flags & ClassFlag::kUndefinedLayout) { + Error("Class \"", decl->name->value, + "\" requires a layout but doesn't have one"); + } + if (flags & ClassFlag::kExtern) { if (decl->generates) { bool enforce_tnode_type = true; generates = ComputeGeneratesType(decl->generates, enforce_tnode_type); } - - new_class = TypeOracle::GetClassType(super_type, decl->name->value, - decl->flags, generates, decl, alias); + if (flags & ClassFlag::kExport) { + Error("cannot export a class that is marked extern"); + } } else { - if (!decl->super) { - ReportError("Intern class ", decl->name->value, - " must extend class Struct."); - } - const Type* super_type = TypeVisitor::ComputeType(*decl->super); - const ClassType* super_class = ClassType::DynamicCast(super_type); - const Type* struct_type = - Declarations::LookupGlobalType(QualifiedName("Struct")); - if (!super_class || super_class != struct_type) { - ReportError("Intern class ", decl->name->value, - " must extend class Struct."); - } if (decl->generates) { ReportError("Only extern classes can specify a generated type."); } - new_class = TypeOracle::GetClassType( - super_type, decl->name->value, - decl->flags | ClassFlag::kGeneratePrint | ClassFlag::kGenerateVerify, - decl->name->value, decl, alias); + if (super_type != TypeOracle::GetStrongTaggedType()) { + if (flags & ClassFlag::kUndefinedLayout) { + Error("non-external classes must have defined layouts"); + } + } + flags = flags | ClassFlag::kGeneratePrint | ClassFlag::kGenerateVerify | + ClassFlag::kGenerateBodyDescriptor; } - return new_class; + + return TypeOracle::GetClassType(super_type, decl->name->value, flags, + generates, decl, alias); } const Type* TypeVisitor::ComputeType(TypeExpression* type_expression) { @@ -406,17 +408,6 @@ void TypeVisitor::VisitClassFieldsAndMethods( ReportError("in-object properties cannot be weak"); } } - if (!(class_declaration->flags & ClassFlag::kExtern)) { - if (!field_type->IsSubtypeOf(TypeOracle::GetObjectType())) { - ReportError( - "non-extern classes only support subtypes of type Object, but " - "found type ", - *field_type); - } - if (field_expression.weak) { - ReportError("non-extern classes do not support weak fields"); - } - } base::Optional array_length = field_expression.index; const Field& field = class_type->RegisterField( {field_expression.name_and_type.name->pos, diff --git a/src/torque/types.cc b/src/torque/types.cc index f556c15391..d4aff5a7b6 100644 --- a/src/torque/types.cc +++ b/src/torque/types.cc @@ -67,6 +67,20 @@ std::string Type::SimpleName() const { return *aliases_.begin(); } +// TODO(danno): HandlifiedCppTypeName should be used universally in Torque +// where the C++ type of a Torque object is required. +std::string Type::HandlifiedCppTypeName() const { + if (IsSubtypeOf(TypeOracle::GetTaggedType()) && + !IsSubtypeOf(TypeOracle::GetSmiType())) { + base::Optional class_type = ClassSupertype(); + std::string type = + class_type ? (*class_type)->GetGeneratedTNodeTypeName() : "Object"; + return "Handle<" + type + ">"; + } else { + return ConstexprVersion()->GetGeneratedTypeName(); + } +} + bool Type::IsSubtypeOf(const Type* supertype) const { if (supertype->IsTopType()) return true; if (IsNever()) return true; @@ -517,24 +531,43 @@ void ClassType::GenerateAccessors() { // For each field, construct AST snippets that implement a CSA accessor // function. The implementation iterator will turn the snippets into code. for (auto& field : fields_) { - if (field.index || field.name_and_type.type == TypeOracle::GetVoidType()) { + if (field.name_and_type.type == TypeOracle::GetVoidType()) { continue; } CurrentSourcePosition::Scope position_activator(field.pos); + IdentifierExpression* parameter = MakeNode(MakeNode(std::string{"o"})); + IdentifierExpression* index = + MakeNode(MakeNode(std::string{"i"})); // Load accessor std::string camel_field_name = CamelifyString(field.name_and_type.name); std::string load_macro_name = "Load" + this->name() + camel_field_name; + + // For now, only generate indexed accessors for simple types + if (field.index.has_value() && field.name_and_type.type->IsStructType()) { + continue; + } + Signature load_signature; load_signature.parameter_names.push_back(MakeNode("o")); load_signature.parameter_types.types.push_back(this); + if (field.index) { + load_signature.parameter_names.push_back(MakeNode("i")); + load_signature.parameter_types.types.push_back( + TypeOracle::GetIntPtrType()); + } load_signature.parameter_types.var_args = false; load_signature.return_type = field.name_and_type.type; - Statement* load_body = - MakeNode(MakeNode( - parameter, MakeNode(field.name_and_type.name))); + + Expression* load_expression = MakeNode( + parameter, MakeNode(field.name_and_type.name)); + if (field.index) { + load_expression = + MakeNode(load_expression, index); + } + Statement* load_body = MakeNode(load_expression); Declarations::DeclareMacro(load_macro_name, true, base::nullopt, load_signature, load_body, base::nullopt); @@ -544,17 +577,25 @@ void ClassType::GenerateAccessors() { std::string store_macro_name = "Store" + this->name() + camel_field_name; Signature store_signature; store_signature.parameter_names.push_back(MakeNode("o")); - store_signature.parameter_names.push_back(MakeNode("v")); store_signature.parameter_types.types.push_back(this); + if (field.index) { + store_signature.parameter_names.push_back(MakeNode("i")); + store_signature.parameter_types.types.push_back( + TypeOracle::GetIntPtrType()); + } + store_signature.parameter_names.push_back(MakeNode("v")); store_signature.parameter_types.types.push_back(field.name_and_type.type); store_signature.parameter_types.var_args = false; // TODO(danno): Store macros probably should return their value argument store_signature.return_type = TypeOracle::GetVoidType(); - Statement* store_body = - MakeNode(MakeNode( - MakeNode( - parameter, MakeNode(field.name_and_type.name)), - value)); + Expression* store_expression = MakeNode( + parameter, MakeNode(field.name_and_type.name)); + if (field.index) { + store_expression = + MakeNode(store_expression, index); + } + Statement* store_body = MakeNode( + MakeNode(store_expression, value)); Declarations::DeclareMacro(store_macro_name, true, base::nullopt, store_signature, store_body, base::nullopt, false); diff --git a/src/torque/types.h b/src/torque/types.h index a07a2b0950..9641e47ba9 100644 --- a/src/torque/types.h +++ b/src/torque/types.h @@ -113,6 +113,8 @@ class V8_EXPORT_PRIVATE Type : public TypeBase { // Used for naming generated code. virtual std::string SimpleName() const; + std::string HandlifiedCppTypeName() const; + const Type* parent() const { return parent_; } bool IsVoid() const { return IsAbstractName(VOID_TYPE_STRING); } bool IsNever() const { return IsAbstractName(NEVER_TYPE_STRING); } @@ -611,12 +613,15 @@ class ClassType final : public AggregateType { std::string GetGeneratedTNodeTypeNameImpl() const override; bool IsExtern() const { return flags_ & ClassFlag::kExtern; } bool ShouldGeneratePrint() const { - return (flags_ & ClassFlag::kGeneratePrint || !IsExtern()) && - !HasUndefinedLayout(); + return !IsExtern() || + ((flags_ & ClassFlag::kGeneratePrint) && !HasUndefinedLayout()); } bool ShouldGenerateVerify() const { - return (flags_ & ClassFlag::kGenerateVerify || !IsExtern()) && - !HasUndefinedLayout() && !IsShape(); + return !IsExtern() || ((flags_ & ClassFlag::kGenerateVerify) && + (!HasUndefinedLayout() && !IsShape())); + } + bool ShouldGenerateBodyDescriptor() const { + return flags_ & ClassFlag::kGenerateBodyDescriptor || !IsExtern(); } bool IsTransient() const override { return flags_ & ClassFlag::kTransient; } bool IsAbstract() const { return flags_ & ClassFlag::kAbstract; } @@ -624,8 +629,10 @@ class ClassType final : public AggregateType { return flags_ & ClassFlag::kHasSameInstanceTypeAsParent; } bool GenerateCppClassDefinitions() const { - return flags_ & ClassFlag::kGenerateCppClassDefinitions || !IsExtern(); + return flags_ & ClassFlag::kGenerateCppClassDefinitions || !IsExtern() || + ShouldGenerateBodyDescriptor(); } + bool ShouldExport() const { return flags_ & ClassFlag::kExport; } bool IsShape() const { return flags_ & ClassFlag::kIsShape; } bool HasStaticSize() const; bool HasIndexedField() const override; diff --git a/test/cctest/torque/test-torque.cc b/test/cctest/torque/test-torque.cc index 4e94fe21f0..f7059f79f4 100644 --- a/test/cctest/torque/test-torque.cc +++ b/test/cctest/torque/test-torque.cc @@ -736,6 +736,35 @@ TEST(TestTestParentFrameArguments) { asm_tester.GenerateCode(); } +TEST(TestFullyGeneratedClassFromCpp) { + CcTest::InitializeVM(); + Isolate* isolate(CcTest::i_isolate()); + i::HandleScope scope(isolate); + CodeAssemblerTester asm_tester(isolate, 1); + TestTorqueAssembler m(asm_tester.state()); + { m.Return(m.TestFullyGeneratedClassFromCpp()); } + FunctionTester ft(asm_tester.GenerateCode(), 0); + Handle result = + Handle::cast(ft.Call().ToHandleChecked()); + CHECK_EQ(result->c_field(), 7); + CHECK_EQ(result->d_field(), 8); + CHECK_EQ(Smi::ToInt(result->e_field()), 9); +} + +TEST(TestFullyGeneratedClassWithElements) { + CcTest::InitializeVM(); + Isolate* isolate(CcTest::i_isolate()); + i::HandleScope scope(isolate); + CodeAssemblerTester asm_tester(isolate, 1); + TestTorqueAssembler m(asm_tester.state()); + { + m.TestFullyGeneratedClassWithElements(); + m.Return(m.UndefinedConstant()); + } + FunctionTester ft(asm_tester.GenerateCode(), 0); + ft.Call(); +} + } // namespace compiler } // namespace internal } // namespace v8 diff --git a/test/torque/test-torque.tq b/test/torque/test-torque.tq index 8948fd0eb0..bd5424a636 100644 --- a/test/torque/test-torque.tq +++ b/test/torque/test-torque.tq @@ -767,7 +767,7 @@ namespace test { check(a.b.GetX() == 2); } - class InternalClass extends Struct { + class InternalClass extends HeapObject { macro Flip() labels NotASmi { const tmp = Cast(this.b) otherwise NotASmi; this.b = this.a; @@ -833,7 +833,7 @@ namespace test { return new FixedArray{map: kFixedArrayMap, length: 5, objects: ...i}; } - class SmiPair extends Struct { + class SmiPair extends HeapObject { macro GetA():&Smi { return & this.a; } @@ -920,7 +920,7 @@ namespace test { StaticAssert(1 + 2 == 3); } - class SmiBox extends Struct { + class SmiBox extends HeapObject { value: Smi; unrelated: Smi; } @@ -1120,4 +1120,108 @@ namespace test { check(val3.d == 99); check(val3.e == 1234); } + + @export + class ExportedSubClass extends ExportedSubClassBase { + c_field: int32; + d_field: int32; + e_field: Smi; + } + + @export + class ExportedSubClassBase extends HeapObject { + a: HeapObject; + b: HeapObject; + } + + class InternalClassWithSmiElements extends FixedArrayBase { + data: Smi; + object: Oddball; + entries[length]: Smi; + } + + struct InternalClassStructElement { + a: Smi; + b: Smi; + } + + class InternalClassWithStructElements extends HeapObject { + dummy1: int32; + dummy2: int32; + count: Smi; + data: Smi; + object: Object; + entries[count]: Smi; + more_entries[count]: InternalClassStructElement; + } + + struct SmiGeneratorIterator { + macro Next(): Smi labels _NoMore { + return this.value++; + } + value: Smi; + } + + struct InternalClassStructElementGeneratorIterator { + macro Next(): InternalClassStructElement labels _NoMore { + return InternalClassStructElement{a: this.value++, b: this.value++}; + } + value: Smi; + } + + @export + macro TestFullyGeneratedClassWithElements() { + // Test creation, initialization and access of a fully generated class with + // simple (Smi) elements + const length: Smi = Convert(3); + const object1 = new InternalClassWithSmiElements{ + length, + data: 0, + object: Undefined, + entries: ...SmiGeneratorIterator { + value: 11 + } + }; + assert(object1.length == 3); + assert(object1.data == 0); + assert(object1.object == Undefined); + assert(object1.entries[0] == 11); + assert(object1.entries[1] == 12); + assert(object1.entries[2] == 13); + + // Test creation, initialization and access of a fully generated class + // with elements that are a struct. + const object2 = new InternalClassWithStructElements{ + dummy1: 44, + dummy2: 45, + count: length, + data: 55, + object: Undefined, + entries: ...SmiGeneratorIterator{value: 3}, + more_entries: ...InternalClassStructElementGeneratorIterator { + value: 1 + } + }; + + assert(object2.dummy1 == 44); + assert(object2.dummy2 == 45); + assert(object2.count == 3); + assert(object2.data == 55); + assert(object2.object == Undefined); + assert(object2.entries[0] == 3); + assert(object2.entries[1] == 4); + assert(object2.entries[2] == 5); + assert(object2.more_entries[0].a == 1); + assert(object2.more_entries[0].b == 2); + assert(object2.more_entries[1].a == 3); + assert(object2.more_entries[1].b == 4); + assert(object2.more_entries[2].a == 5); + assert(object2.more_entries[2].b == 6); + } + + @export + macro TestFullyGeneratedClassFromCpp(): ExportedSubClass { + return new + ExportedSubClass{a: Null, b: Null, c_field: 7, d_field: 8, e_field: 9}; + } } diff --git a/third_party/v8/builtins/array-sort.tq b/third_party/v8/builtins/array-sort.tq index d920599e6e..2d9f33a312 100644 --- a/third_party/v8/builtins/array-sort.tq +++ b/third_party/v8/builtins/array-sort.tq @@ -14,7 +14,7 @@ // https://github.com/python/cpython/blob/master/Objects/listsort.txt namespace array { - class SortState extends Struct { + class SortState extends HeapObject { macro Compare(implicit context: Context)(x: JSAny, y: JSAny): Number { const sortCompare: CompareBuiltinFn = this.sortComparePtr; return sortCompare(context, this.userCmpFn, x, y); diff --git a/tools/debug_helper/BUILD.gn b/tools/debug_helper/BUILD.gn index 702ebcc527..b151e12918 100644 --- a/tools/debug_helper/BUILD.gn +++ b/tools/debug_helper/BUILD.gn @@ -69,6 +69,7 @@ v8_component("v8_debug_helper") { sources = [ "$target_gen_dir/../../torque-generated/class-debug-readers-tq.cc", "$target_gen_dir/../../torque-generated/class-debug-readers-tq.h", + "$target_gen_dir/../../torque-generated/instance-types-tq.h", "$target_gen_dir/heap-constants-gen.cc", "debug-helper-internal.cc", "debug-helper-internal.h", diff --git a/tools/debug_helper/get-object-properties.cc b/tools/debug_helper/get-object-properties.cc index f3bd4811f2..99e62796a7 100644 --- a/tools/debug_helper/get-object-properties.cc +++ b/tools/debug_helper/get-object-properties.cc @@ -104,6 +104,7 @@ TypedObject GetTypedObjectByInstanceType(uintptr_t address, case i::INSTANCE_TYPE: \ return {type_source, std::make_unique(address)}; TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(INSTANCE_TYPE_CASE) + TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(INSTANCE_TYPE_CASE) #undef INSTANCE_TYPE_CASE default: diff --git a/tools/v8heapconst.py b/tools/v8heapconst.py index 81f9679343..453083aa3a 100644 --- a/tools/v8heapconst.py +++ b/tools/v8heapconst.py @@ -29,8 +29,8 @@ INSTANCE_TYPES = { 65: "BIG_INT_BASE_TYPE", 66: "HEAP_NUMBER_TYPE", 67: "ODDBALL_TYPE", - 68: "SOURCE_TEXT_MODULE_TYPE", - 69: "SYNTHETIC_MODULE_TYPE", + 68: "EXPORTED_SUB_CLASS_BASE_TYPE", + 69: "EXPORTED_SUB_CLASS_TYPE", 70: "FOREIGN_TYPE", 71: "PROMISE_FULFILL_REACTION_JOB_TASK_TYPE", 72: "PROMISE_REJECT_REACTION_JOB_TASK_TYPE", @@ -60,84 +60,88 @@ INSTANCE_TYPES = { 96: "FEEDBACK_CELL_TYPE", 97: "FUNCTION_TEMPLATE_RARE_DATA_TYPE", 98: "INTERCEPTOR_INFO_TYPE", - 99: "INTERNAL_CLASS_TYPE", - 100: "INTERPRETER_DATA_TYPE", - 101: "PROMISE_CAPABILITY_TYPE", - 102: "PROMISE_REACTION_TYPE", - 103: "PROPERTY_DESCRIPTOR_OBJECT_TYPE", - 104: "PROTOTYPE_INFO_TYPE", - 105: "SCRIPT_TYPE", - 106: "SMI_BOX_TYPE", - 107: "SMI_PAIR_TYPE", - 108: "SORT_STATE_TYPE", - 109: "SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE", - 110: "STACK_FRAME_INFO_TYPE", - 111: "STACK_TRACE_FRAME_TYPE", - 112: "TEMPLATE_OBJECT_DESCRIPTION_TYPE", - 113: "TUPLE2_TYPE", - 114: "WASM_CAPI_FUNCTION_DATA_TYPE", - 115: "WASM_DEBUG_INFO_TYPE", - 116: "WASM_EXCEPTION_TAG_TYPE", - 117: "WASM_EXPORTED_FUNCTION_DATA_TYPE", - 118: "WASM_INDIRECT_FUNCTION_TABLE_TYPE", - 119: "WASM_JS_FUNCTION_DATA_TYPE", - 120: "FIXED_ARRAY_TYPE", - 121: "HASH_TABLE_TYPE", - 122: "EPHEMERON_HASH_TABLE_TYPE", - 123: "GLOBAL_DICTIONARY_TYPE", - 124: "NAME_DICTIONARY_TYPE", - 125: "NUMBER_DICTIONARY_TYPE", - 126: "ORDERED_HASH_MAP_TYPE", - 127: "ORDERED_HASH_SET_TYPE", - 128: "ORDERED_NAME_DICTIONARY_TYPE", - 129: "SIMPLE_NUMBER_DICTIONARY_TYPE", - 130: "STRING_TABLE_TYPE", - 131: "CLOSURE_FEEDBACK_CELL_ARRAY_TYPE", - 132: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE", - 133: "SCOPE_INFO_TYPE", - 134: "SCRIPT_CONTEXT_TABLE_TYPE", - 135: "BYTE_ARRAY_TYPE", - 136: "BYTECODE_ARRAY_TYPE", - 137: "FIXED_DOUBLE_ARRAY_TYPE", - 138: "AWAIT_CONTEXT_TYPE", - 139: "BLOCK_CONTEXT_TYPE", - 140: "CATCH_CONTEXT_TYPE", - 141: "DEBUG_EVALUATE_CONTEXT_TYPE", - 142: "EVAL_CONTEXT_TYPE", - 143: "FUNCTION_CONTEXT_TYPE", - 144: "MODULE_CONTEXT_TYPE", - 145: "NATIVE_CONTEXT_TYPE", - 146: "SCRIPT_CONTEXT_TYPE", - 147: "WITH_CONTEXT_TYPE", - 148: "SMALL_ORDERED_HASH_MAP_TYPE", - 149: "SMALL_ORDERED_HASH_SET_TYPE", - 150: "SMALL_ORDERED_NAME_DICTIONARY_TYPE", - 151: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE", - 152: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE", - 153: "WEAK_FIXED_ARRAY_TYPE", - 154: "TRANSITION_ARRAY_TYPE", - 155: "CELL_TYPE", - 156: "CODE_TYPE", - 157: "CODE_DATA_CONTAINER_TYPE", - 158: "COVERAGE_INFO_TYPE", - 159: "DESCRIPTOR_ARRAY_TYPE", - 160: "EMBEDDER_DATA_ARRAY_TYPE", - 161: "FEEDBACK_METADATA_TYPE", - 162: "FEEDBACK_VECTOR_TYPE", - 163: "FILLER_TYPE", - 164: "FREE_SPACE_TYPE", - 165: "MAP_TYPE", - 166: "PREPARSE_DATA_TYPE", - 167: "PROPERTY_ARRAY_TYPE", - 168: "PROPERTY_CELL_TYPE", - 169: "SHARED_FUNCTION_INFO_TYPE", - 170: "WEAK_ARRAY_LIST_TYPE", - 171: "WEAK_CELL_TYPE", - 172: "JS_PROXY_TYPE", + 99: "INTERPRETER_DATA_TYPE", + 100: "PROMISE_CAPABILITY_TYPE", + 101: "PROMISE_REACTION_TYPE", + 102: "PROPERTY_DESCRIPTOR_OBJECT_TYPE", + 103: "PROTOTYPE_INFO_TYPE", + 104: "SCRIPT_TYPE", + 105: "SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE", + 106: "STACK_FRAME_INFO_TYPE", + 107: "STACK_TRACE_FRAME_TYPE", + 108: "TEMPLATE_OBJECT_DESCRIPTION_TYPE", + 109: "TUPLE2_TYPE", + 110: "WASM_CAPI_FUNCTION_DATA_TYPE", + 111: "WASM_DEBUG_INFO_TYPE", + 112: "WASM_EXCEPTION_TAG_TYPE", + 113: "WASM_EXPORTED_FUNCTION_DATA_TYPE", + 114: "WASM_INDIRECT_FUNCTION_TABLE_TYPE", + 115: "WASM_JS_FUNCTION_DATA_TYPE", + 116: "FIXED_ARRAY_TYPE", + 117: "HASH_TABLE_TYPE", + 118: "EPHEMERON_HASH_TABLE_TYPE", + 119: "GLOBAL_DICTIONARY_TYPE", + 120: "NAME_DICTIONARY_TYPE", + 121: "NUMBER_DICTIONARY_TYPE", + 122: "ORDERED_HASH_MAP_TYPE", + 123: "ORDERED_HASH_SET_TYPE", + 124: "ORDERED_NAME_DICTIONARY_TYPE", + 125: "SIMPLE_NUMBER_DICTIONARY_TYPE", + 126: "STRING_TABLE_TYPE", + 127: "CLOSURE_FEEDBACK_CELL_ARRAY_TYPE", + 128: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE", + 129: "SCOPE_INFO_TYPE", + 130: "SCRIPT_CONTEXT_TABLE_TYPE", + 131: "BYTE_ARRAY_TYPE", + 132: "BYTECODE_ARRAY_TYPE", + 133: "FIXED_DOUBLE_ARRAY_TYPE", + 134: "INTERNAL_CLASS_WITH_SMI_ELEMENTS_TYPE", + 135: "AWAIT_CONTEXT_TYPE", + 136: "BLOCK_CONTEXT_TYPE", + 137: "CATCH_CONTEXT_TYPE", + 138: "DEBUG_EVALUATE_CONTEXT_TYPE", + 139: "EVAL_CONTEXT_TYPE", + 140: "FUNCTION_CONTEXT_TYPE", + 141: "MODULE_CONTEXT_TYPE", + 142: "NATIVE_CONTEXT_TYPE", + 143: "SCRIPT_CONTEXT_TYPE", + 144: "WITH_CONTEXT_TYPE", + 145: "SMALL_ORDERED_HASH_MAP_TYPE", + 146: "SMALL_ORDERED_HASH_SET_TYPE", + 147: "SMALL_ORDERED_NAME_DICTIONARY_TYPE", + 148: "SOURCE_TEXT_MODULE_TYPE", + 149: "SYNTHETIC_MODULE_TYPE", + 150: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE", + 151: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE", + 152: "WEAK_FIXED_ARRAY_TYPE", + 153: "TRANSITION_ARRAY_TYPE", + 154: "CELL_TYPE", + 155: "CODE_TYPE", + 156: "CODE_DATA_CONTAINER_TYPE", + 157: "COVERAGE_INFO_TYPE", + 158: "DESCRIPTOR_ARRAY_TYPE", + 159: "EMBEDDER_DATA_ARRAY_TYPE", + 160: "FEEDBACK_METADATA_TYPE", + 161: "FEEDBACK_VECTOR_TYPE", + 162: "FILLER_TYPE", + 163: "FREE_SPACE_TYPE", + 164: "INTERNAL_CLASS_TYPE", + 165: "INTERNAL_CLASS_WITH_STRUCT_ELEMENTS_TYPE", + 166: "MAP_TYPE", + 167: "PREPARSE_DATA_TYPE", + 168: "PROPERTY_ARRAY_TYPE", + 169: "PROPERTY_CELL_TYPE", + 170: "SHARED_FUNCTION_INFO_TYPE", + 171: "SMI_BOX_TYPE", + 172: "SMI_PAIR_TYPE", + 173: "SORT_STATE_TYPE", + 174: "WEAK_ARRAY_LIST_TYPE", + 175: "WEAK_CELL_TYPE", + 176: "JS_PROXY_TYPE", 1057: "JS_OBJECT_TYPE", - 173: "JS_GLOBAL_OBJECT_TYPE", - 174: "JS_GLOBAL_PROXY_TYPE", - 175: "JS_MODULE_NAMESPACE_TYPE", + 177: "JS_GLOBAL_OBJECT_TYPE", + 178: "JS_GLOBAL_PROXY_TYPE", + 179: "JS_MODULE_NAMESPACE_TYPE", 1040: "JS_SPECIAL_API_OBJECT_TYPE", 1041: "JS_PRIMITIVE_WRAPPER_TYPE", 1042: "JS_MAP_KEY_ITERATOR_TYPE", @@ -194,78 +198,78 @@ INSTANCE_TYPES = { # List of known V8 maps. KNOWN_MAPS = { - ("read_only_space", 0x00121): (164, "FreeSpaceMap"), - ("read_only_space", 0x00149): (165, "MetaMap"), + ("read_only_space", 0x00121): (163, "FreeSpaceMap"), + ("read_only_space", 0x00149): (166, "MetaMap"), ("read_only_space", 0x0018d): (67, "NullMap"), - ("read_only_space", 0x001c5): (159, "DescriptorArrayMap"), - ("read_only_space", 0x001f5): (153, "WeakFixedArrayMap"), - ("read_only_space", 0x0021d): (163, "OnePointerFillerMap"), - ("read_only_space", 0x00245): (163, "TwoPointerFillerMap"), + ("read_only_space", 0x001c5): (158, "DescriptorArrayMap"), + ("read_only_space", 0x001f5): (152, "WeakFixedArrayMap"), + ("read_only_space", 0x0021d): (162, "OnePointerFillerMap"), + ("read_only_space", 0x00245): (162, "TwoPointerFillerMap"), ("read_only_space", 0x00289): (67, "UninitializedMap"), ("read_only_space", 0x002cd): (8, "OneByteInternalizedStringMap"), ("read_only_space", 0x00329): (67, "UndefinedMap"), ("read_only_space", 0x0035d): (66, "HeapNumberMap"), ("read_only_space", 0x003a1): (67, "TheHoleMap"), ("read_only_space", 0x00401): (67, "BooleanMap"), - ("read_only_space", 0x00489): (135, "ByteArrayMap"), - ("read_only_space", 0x004b1): (120, "FixedArrayMap"), - ("read_only_space", 0x004d9): (120, "FixedCOWArrayMap"), - ("read_only_space", 0x00501): (121, "HashTableMap"), + ("read_only_space", 0x00489): (131, "ByteArrayMap"), + ("read_only_space", 0x004b1): (116, "FixedArrayMap"), + ("read_only_space", 0x004d9): (116, "FixedCOWArrayMap"), + ("read_only_space", 0x00501): (117, "HashTableMap"), ("read_only_space", 0x00529): (64, "SymbolMap"), ("read_only_space", 0x00551): (40, "OneByteStringMap"), - ("read_only_space", 0x00579): (133, "ScopeInfoMap"), - ("read_only_space", 0x005a1): (169, "SharedFunctionInfoMap"), - ("read_only_space", 0x005c9): (156, "CodeMap"), - ("read_only_space", 0x005f1): (155, "CellMap"), - ("read_only_space", 0x00619): (168, "GlobalPropertyCellMap"), + ("read_only_space", 0x00579): (129, "ScopeInfoMap"), + ("read_only_space", 0x005a1): (170, "SharedFunctionInfoMap"), + ("read_only_space", 0x005c9): (155, "CodeMap"), + ("read_only_space", 0x005f1): (154, "CellMap"), + ("read_only_space", 0x00619): (169, "GlobalPropertyCellMap"), ("read_only_space", 0x00641): (70, "ForeignMap"), - ("read_only_space", 0x00669): (154, "TransitionArrayMap"), + ("read_only_space", 0x00669): (153, "TransitionArrayMap"), ("read_only_space", 0x00691): (45, "ThinOneByteStringMap"), - ("read_only_space", 0x006b9): (162, "FeedbackVectorMap"), + ("read_only_space", 0x006b9): (161, "FeedbackVectorMap"), ("read_only_space", 0x0070d): (67, "ArgumentsMarkerMap"), ("read_only_space", 0x0076d): (67, "ExceptionMap"), ("read_only_space", 0x007c9): (67, "TerminationExceptionMap"), ("read_only_space", 0x00831): (67, "OptimizedOutMap"), ("read_only_space", 0x00891): (67, "StaleRegisterMap"), - ("read_only_space", 0x008d5): (134, "ScriptContextTableMap"), - ("read_only_space", 0x008fd): (131, "ClosureFeedbackCellArrayMap"), - ("read_only_space", 0x00925): (161, "FeedbackMetadataArrayMap"), - ("read_only_space", 0x0094d): (120, "ArrayListMap"), + ("read_only_space", 0x008d5): (130, "ScriptContextTableMap"), + ("read_only_space", 0x008fd): (127, "ClosureFeedbackCellArrayMap"), + ("read_only_space", 0x00925): (160, "FeedbackMetadataArrayMap"), + ("read_only_space", 0x0094d): (116, "ArrayListMap"), ("read_only_space", 0x00975): (65, "BigIntMap"), - ("read_only_space", 0x0099d): (132, "ObjectBoilerplateDescriptionMap"), - ("read_only_space", 0x009c5): (136, "BytecodeArrayMap"), - ("read_only_space", 0x009ed): (157, "CodeDataContainerMap"), - ("read_only_space", 0x00a15): (158, "CoverageInfoMap"), - ("read_only_space", 0x00a3d): (137, "FixedDoubleArrayMap"), - ("read_only_space", 0x00a65): (123, "GlobalDictionaryMap"), + ("read_only_space", 0x0099d): (128, "ObjectBoilerplateDescriptionMap"), + ("read_only_space", 0x009c5): (132, "BytecodeArrayMap"), + ("read_only_space", 0x009ed): (156, "CodeDataContainerMap"), + ("read_only_space", 0x00a15): (157, "CoverageInfoMap"), + ("read_only_space", 0x00a3d): (133, "FixedDoubleArrayMap"), + ("read_only_space", 0x00a65): (119, "GlobalDictionaryMap"), ("read_only_space", 0x00a8d): (96, "ManyClosuresCellMap"), - ("read_only_space", 0x00ab5): (120, "ModuleInfoMap"), - ("read_only_space", 0x00add): (124, "NameDictionaryMap"), + ("read_only_space", 0x00ab5): (116, "ModuleInfoMap"), + ("read_only_space", 0x00add): (120, "NameDictionaryMap"), ("read_only_space", 0x00b05): (96, "NoClosuresCellMap"), - ("read_only_space", 0x00b2d): (125, "NumberDictionaryMap"), + ("read_only_space", 0x00b2d): (121, "NumberDictionaryMap"), ("read_only_space", 0x00b55): (96, "OneClosureCellMap"), - ("read_only_space", 0x00b7d): (126, "OrderedHashMapMap"), - ("read_only_space", 0x00ba5): (127, "OrderedHashSetMap"), - ("read_only_space", 0x00bcd): (128, "OrderedNameDictionaryMap"), - ("read_only_space", 0x00bf5): (166, "PreparseDataMap"), - ("read_only_space", 0x00c1d): (167, "PropertyArrayMap"), + ("read_only_space", 0x00b7d): (122, "OrderedHashMapMap"), + ("read_only_space", 0x00ba5): (123, "OrderedHashSetMap"), + ("read_only_space", 0x00bcd): (124, "OrderedNameDictionaryMap"), + ("read_only_space", 0x00bf5): (167, "PreparseDataMap"), + ("read_only_space", 0x00c1d): (168, "PropertyArrayMap"), ("read_only_space", 0x00c45): (92, "SideEffectCallHandlerInfoMap"), ("read_only_space", 0x00c6d): (92, "SideEffectFreeCallHandlerInfoMap"), ("read_only_space", 0x00c95): (92, "NextCallSideEffectFreeCallHandlerInfoMap"), - ("read_only_space", 0x00cbd): (129, "SimpleNumberDictionaryMap"), - ("read_only_space", 0x00ce5): (120, "SloppyArgumentsElementsMap"), - ("read_only_space", 0x00d0d): (148, "SmallOrderedHashMapMap"), - ("read_only_space", 0x00d35): (149, "SmallOrderedHashSetMap"), - ("read_only_space", 0x00d5d): (150, "SmallOrderedNameDictionaryMap"), - ("read_only_space", 0x00d85): (68, "SourceTextModuleMap"), - ("read_only_space", 0x00dad): (130, "StringTableMap"), - ("read_only_space", 0x00dd5): (69, "SyntheticModuleMap"), - ("read_only_space", 0x00dfd): (152, "UncompiledDataWithoutPreparseDataMap"), - ("read_only_space", 0x00e25): (151, "UncompiledDataWithPreparseDataMap"), - ("read_only_space", 0x00e4d): (170, "WeakArrayListMap"), - ("read_only_space", 0x00e75): (122, "EphemeronHashTableMap"), - ("read_only_space", 0x00e9d): (160, "EmbedderDataArrayMap"), - ("read_only_space", 0x00ec5): (171, "WeakCellMap"), + ("read_only_space", 0x00cbd): (125, "SimpleNumberDictionaryMap"), + ("read_only_space", 0x00ce5): (116, "SloppyArgumentsElementsMap"), + ("read_only_space", 0x00d0d): (145, "SmallOrderedHashMapMap"), + ("read_only_space", 0x00d35): (146, "SmallOrderedHashSetMap"), + ("read_only_space", 0x00d5d): (147, "SmallOrderedNameDictionaryMap"), + ("read_only_space", 0x00d85): (148, "SourceTextModuleMap"), + ("read_only_space", 0x00dad): (126, "StringTableMap"), + ("read_only_space", 0x00dd5): (149, "SyntheticModuleMap"), + ("read_only_space", 0x00dfd): (151, "UncompiledDataWithoutPreparseDataMap"), + ("read_only_space", 0x00e25): (150, "UncompiledDataWithPreparseDataMap"), + ("read_only_space", 0x00e4d): (174, "WeakArrayListMap"), + ("read_only_space", 0x00e75): (118, "EphemeronHashTableMap"), + ("read_only_space", 0x00e9d): (159, "EmbedderDataArrayMap"), + ("read_only_space", 0x00ec5): (175, "WeakCellMap"), ("read_only_space", 0x00eed): (32, "StringMap"), ("read_only_space", 0x00f15): (41, "ConsOneByteStringMap"), ("read_only_space", 0x00f3d): (33, "ConsStringMap"), @@ -305,36 +309,40 @@ KNOWN_MAPS = { ("read_only_space", 0x0357d): (93, "ClassPositionsMap"), ("read_only_space", 0x035a5): (94, "DebugInfoMap"), ("read_only_space", 0x035cd): (97, "FunctionTemplateRareDataMap"), - ("read_only_space", 0x035f5): (100, "InterpreterDataMap"), - ("read_only_space", 0x0361d): (101, "PromiseCapabilityMap"), - ("read_only_space", 0x03645): (102, "PromiseReactionMap"), - ("read_only_space", 0x0366d): (103, "PropertyDescriptorObjectMap"), - ("read_only_space", 0x03695): (104, "PrototypeInfoMap"), - ("read_only_space", 0x036bd): (105, "ScriptMap"), - ("read_only_space", 0x036e5): (109, "SourceTextModuleInfoEntryMap"), - ("read_only_space", 0x0370d): (110, "StackFrameInfoMap"), - ("read_only_space", 0x03735): (111, "StackTraceFrameMap"), - ("read_only_space", 0x0375d): (112, "TemplateObjectDescriptionMap"), - ("read_only_space", 0x03785): (113, "Tuple2Map"), - ("read_only_space", 0x037ad): (114, "WasmCapiFunctionDataMap"), - ("read_only_space", 0x037d5): (115, "WasmDebugInfoMap"), - ("read_only_space", 0x037fd): (116, "WasmExceptionTagMap"), - ("read_only_space", 0x03825): (117, "WasmExportedFunctionDataMap"), - ("read_only_space", 0x0384d): (118, "WasmIndirectFunctionTableMap"), - ("read_only_space", 0x03875): (119, "WasmJSFunctionDataMap"), - ("read_only_space", 0x0389d): (99, "InternalClassMap"), - ("read_only_space", 0x038c5): (107, "SmiPairMap"), - ("read_only_space", 0x038ed): (106, "SmiBoxMap"), - ("read_only_space", 0x03915): (108, "SortStateMap"), - ("read_only_space", 0x0393d): (85, "AllocationSiteWithWeakNextMap"), - ("read_only_space", 0x03965): (85, "AllocationSiteWithoutWeakNextMap"), - ("read_only_space", 0x0398d): (76, "LoadHandler1Map"), - ("read_only_space", 0x039b5): (76, "LoadHandler2Map"), - ("read_only_space", 0x039dd): (76, "LoadHandler3Map"), - ("read_only_space", 0x03a05): (77, "StoreHandler0Map"), - ("read_only_space", 0x03a2d): (77, "StoreHandler1Map"), - ("read_only_space", 0x03a55): (77, "StoreHandler2Map"), - ("read_only_space", 0x03a7d): (77, "StoreHandler3Map"), + ("read_only_space", 0x035f5): (99, "InterpreterDataMap"), + ("read_only_space", 0x0361d): (100, "PromiseCapabilityMap"), + ("read_only_space", 0x03645): (101, "PromiseReactionMap"), + ("read_only_space", 0x0366d): (102, "PropertyDescriptorObjectMap"), + ("read_only_space", 0x03695): (103, "PrototypeInfoMap"), + ("read_only_space", 0x036bd): (104, "ScriptMap"), + ("read_only_space", 0x036e5): (105, "SourceTextModuleInfoEntryMap"), + ("read_only_space", 0x0370d): (106, "StackFrameInfoMap"), + ("read_only_space", 0x03735): (107, "StackTraceFrameMap"), + ("read_only_space", 0x0375d): (108, "TemplateObjectDescriptionMap"), + ("read_only_space", 0x03785): (109, "Tuple2Map"), + ("read_only_space", 0x037ad): (110, "WasmCapiFunctionDataMap"), + ("read_only_space", 0x037d5): (111, "WasmDebugInfoMap"), + ("read_only_space", 0x037fd): (112, "WasmExceptionTagMap"), + ("read_only_space", 0x03825): (113, "WasmExportedFunctionDataMap"), + ("read_only_space", 0x0384d): (114, "WasmIndirectFunctionTableMap"), + ("read_only_space", 0x03875): (115, "WasmJSFunctionDataMap"), + ("read_only_space", 0x0389d): (134, "InternalClassWithSmiElementsMap"), + ("read_only_space", 0x038c5): (165, "InternalClassWithStructElementsMap"), + ("read_only_space", 0x038ed): (164, "InternalClassMap"), + ("read_only_space", 0x03915): (172, "SmiPairMap"), + ("read_only_space", 0x0393d): (171, "SmiBoxMap"), + ("read_only_space", 0x03965): (68, "ExportedSubClassBaseMap"), + ("read_only_space", 0x0398d): (69, "ExportedSubClassMap"), + ("read_only_space", 0x039b5): (173, "SortStateMap"), + ("read_only_space", 0x039dd): (85, "AllocationSiteWithWeakNextMap"), + ("read_only_space", 0x03a05): (85, "AllocationSiteWithoutWeakNextMap"), + ("read_only_space", 0x03a2d): (76, "LoadHandler1Map"), + ("read_only_space", 0x03a55): (76, "LoadHandler2Map"), + ("read_only_space", 0x03a7d): (76, "LoadHandler3Map"), + ("read_only_space", 0x03aa5): (77, "StoreHandler0Map"), + ("read_only_space", 0x03acd): (77, "StoreHandler1Map"), + ("read_only_space", 0x03af5): (77, "StoreHandler2Map"), + ("read_only_space", 0x03b1d): (77, "StoreHandler3Map"), ("map_space", 0x00121): (1057, "ExternalMap"), ("map_space", 0x00149): (1073, "JSMessageObjectMap"), }