[torque] Generate instance types

Design doc:
https://docs.google.com/document/d/1ZU6rCvF2YHBGMLujWqqaxlPsjFfjKDE9C3-EugfdlAE/edit

Changes from the design doc:
- Changed to use 'class' declarations rather than 'type' declarations
  for things that need instance types but whose layout is not known to
  Torque. These declarations end with a semicolon rather than having a
  full set of methods and fields surrounded by {}. If the class's name
  should not be treated as a class name in generated output (because
  it's actually a template, or doesn't exist at all), we use the
  standard 'generates' clause to declare the most appropriate C++ class.
- Removed @instanceTypeName.
- @highestInstanceType became @highestInstanceTypeWithinParentClassRange
  to indicate a semantic change: it no longer denotes the highest
  instance type globally, but only within the range of values for its
  immediate parent class. This lets us use it for Oddball, which is
  expected to be the highest primitive type.
- Added new abstract classes JSCustomElementsObject and JSSpecialObject
  to help with some range checks.
- Added @lowestInstanceTypeWithinParentClassRange so we can move the new
  classes JSCustomElementsObject and JSSpecialObject to the beginning of
  the JSObject range. This seems like the least-brittle way to establish
  ranges that also include JSProxy (and these ranges are verified with
  static assertions in instance-type.h).
- Renamed @instanceTypeValue to @apiExposedInstanceTypeValue.
- Renamed @instanceTypeFlags to @reserveBitsInInstanceType.

This change introduces the new annotations and adds the ability for
Torque to assign instance types that satisfy those annotations. Torque
now emits two new macros:
- TORQUE_ASSIGNED_INSTANCE_TYPES, which is used to define the
  InstanceType enumeration
- TORQUE_ASSIGNED_INSTANCE_TYPE_LIST, which replaces the non-String
  parts of INSTANCE_TYPE_LIST

The design document mentions a couple of other macro lists that could
easily be replaced, but I'd like to defer those to a subsequent checkin
because this one is already pretty large.

Bug: v8:7793
Change-Id: Ie71d93a9d5b610e62be0ffa3bb36180c3357a6e8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1757094
Commit-Queue: Seth Brenith <seth.brenith@microsoft.com>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Sathya Gunasekaran  <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64258}
This commit is contained in:
Seth Brenith 2019-10-11 14:52:06 -07:00 committed by Commit Bot
parent 844cf4d8a8
commit 8c7ae31456
47 changed files with 1337 additions and 930 deletions

View File

@ -967,6 +967,8 @@ action("postmortem-metadata") {
"src/objects/name-inl.h",
"src/objects/oddball-inl.h",
"src/objects/oddball.h",
"src/objects/primitive-heap-object.h",
"src/objects/primitive-heap-object-inl.h",
"src/objects/scope-info.h",
"src/objects/script.h",
"src/objects/script-inl.h",
@ -979,6 +981,7 @@ action("postmortem-metadata") {
"src/objects/string-inl.h",
"src/objects/struct.h",
"src/objects/struct-inl.h",
"$target_gen_dir/torque-generated/instance-types-tq.h",
]
outputs = [
@ -987,6 +990,10 @@ action("postmortem-metadata") {
args = rebase_path(outputs, root_build_dir) +
rebase_path(sources, root_build_dir)
deps = [
":run_torque",
]
}
torque_files = [
@ -2671,6 +2678,8 @@ v8_source_set("v8_base_without_compiler") {
"src/objects/osr-optimized-code-cache-inl.h",
"src/objects/osr-optimized-code-cache.cc",
"src/objects/osr-optimized-code-cache.h",
"src/objects/primitive-heap-object-inl.h",
"src/objects/primitive-heap-object.h",
"src/objects/promise-inl.h",
"src/objects/promise.h",
"src/objects/property-array-inl.h",
@ -3445,6 +3454,7 @@ v8_source_set("torque_base") {
"src/torque/global-context.h",
"src/torque/implementation-visitor.cc",
"src/torque/implementation-visitor.h",
"src/torque/instance-type-generator.cc",
"src/torque/instructions.cc",
"src/torque/instructions.h",
"src/torque/server-data.cc",

View File

@ -84,11 +84,11 @@ void SourceTextModuleDescriptor::AddStarExport(
}
namespace {
Handle<HeapObject> ToStringOrUndefined(Isolate* isolate,
const AstRawString* s) {
return (s == nullptr)
? Handle<HeapObject>::cast(isolate->factory()->undefined_value())
: Handle<HeapObject>::cast(s->string());
Handle<PrimitiveHeapObject> ToStringOrUndefined(Isolate* isolate,
const AstRawString* s) {
return (s == nullptr) ? Handle<PrimitiveHeapObject>::cast(
isolate->factory()->undefined_value())
: Handle<PrimitiveHeapObject>::cast(s->string());
}
} // namespace

View File

@ -90,11 +90,28 @@ type bool generates 'TNode<BoolT>' constexpr 'bool';
type bint generates 'TNode<BInt>' constexpr 'BInt';
type string constexpr 'const char*';
type NameDictionary extends FixedArray;
// The HashTable inheritance hierarchy doesn't actually look like this in C++
// because it uses some class templates that we can't yet (and may never)
// express in Torque, but this is the expected organization of instance types.
@abstract @dirtyInstantiatedAbstractClass
extern class HashTable extends FixedArray generates 'TNode<FixedArray>';
extern class OrderedHashMap extends HashTable;
extern class OrderedHashSet extends HashTable;
extern class OrderedNameDictionary extends HashTable;
extern class NameDictionary extends HashTable;
extern class GlobalDictionary extends HashTable;
extern class SimpleNumberDictionary extends HashTable;
extern class StringTable extends HashTable;
extern class EphemeronHashTable extends HashTable;
type ObjectHashTable extends HashTable
generates 'TNode<ObjectHashTable>';
extern class NumberDictionary extends HashTable;
type RawPtr generates 'TNode<RawPtrT>' constexpr 'void*';
type Code extends HeapObject generates 'TNode<Code>';
extern class Code extends HeapObject;
type BuiltinPtr extends Smi generates 'TNode<BuiltinPtr>';
@abstract
extern class Context extends HeapObject {
length: Smi;
scope_info: ScopeInfo;
@ -102,10 +119,27 @@ extern class Context extends HeapObject {
extension: Object;
native_context: Object;
}
type NativeContext extends Context generates 'TNode<NativeContext>';
extern class AwaitContext extends Context generates 'TNode<Context>';
extern class BlockContext extends Context generates 'TNode<Context>';
extern class CatchContext extends Context generates 'TNode<Context>';
extern class DebugEvaluateContext extends Context
generates 'TNode<Context>';
extern class EvalContext extends Context generates 'TNode<Context>';
extern class FunctionContext extends Context generates 'TNode<Context>';
extern class ModuleContext extends Context generates 'TNode<Context>';
extern class NativeContext extends Context;
extern class ScriptContext extends Context generates 'TNode<Context>';
extern class WithContext extends Context generates 'TNode<Context>';
@generateCppClass
extern class Oddball extends HeapObject {
@abstract
extern class PrimitiveHeapObject extends HeapObject {
}
@generateCppClass
@apiExposedInstanceTypeValue(0x43)
@highestInstanceTypeWithinParentClassRange
extern class Oddball extends PrimitiveHeapObject {
to_number_raw: float64;
to_string: String;
to_number: Number;
@ -113,13 +147,13 @@ extern class Oddball extends HeapObject {
kind: Smi;
}
extern class HeapNumber extends HeapObject { value: float64; }
extern class HeapNumber extends PrimitiveHeapObject { value: float64; }
type Number = Smi | HeapNumber;
type Numeric = Number | BigInt;
@abstract
@generateCppClass
extern class Name extends HeapObject {
extern class Name extends PrimitiveHeapObject {
hash_field: uint32;
}
// This is the same as Name, but with the information that there are no other
@ -137,6 +171,7 @@ type PrivateSymbol extends Symbol;
@abstract
@generateCppClass
@reserveBitsInInstanceType(6)
extern class String extends Name {
length: int32;
}
@ -222,13 +257,21 @@ extern class FixedArrayBase extends HeapObject {
length: Smi;
}
extern class FixedArray extends FixedArrayBase { objects[length]: Object; }
@abstract
@dirtyInstantiatedAbstractClass
extern class FixedArray extends FixedArrayBase {
objects[length]: Object;
}
extern class FixedDoubleArray extends FixedArrayBase {
floats[length]: float64;
}
extern class WeakFixedArray extends HeapObject { length: Smi; }
@abstract
@dirtyInstantiatedAbstractClass
extern class WeakFixedArray extends HeapObject {
length: Smi;
}
extern class ByteArray extends FixedArrayBase {}
@ -236,10 +279,13 @@ extern class ByteArray extends FixedArrayBase {}
extern class ArrayList extends FixedArray {
}
extern class ObjectBoilerplateDescription extends FixedArray;
extern class ClosureFeedbackCellArray extends FixedArray;
extern class ScriptContextTable extends FixedArray;
type LayoutDescriptor extends ByteArray
generates 'TNode<LayoutDescriptor>';
type TransitionArray extends WeakFixedArray
generates 'TNode<TransitionArray>';
extern class TransitionArray extends WeakFixedArray;
type InstanceType extends uint16 constexpr 'v8::internal::InstanceType';
@ -286,6 +332,7 @@ extern class SourcePositionTableWithFrameCache extends Struct {
// We make this class abstract because it is missing the variable-sized part,
// which is still impossible to express in Torque.
@abstract
@dirtyInstantiatedAbstractClass
extern class DescriptorArray extends HeapObject {
number_of_all_descriptors: uint16;
number_of_descriptors: uint16;
@ -331,7 +378,9 @@ intrinsic
}
}
// JSReceiver corresponds to objects in the JS sense.
@abstract
@highestInstanceTypeWithinParentClassRange
extern class JSReceiver extends HeapObject {
properties_or_hash: FixedArrayBase | PropertyArray | Smi;
}
@ -341,6 +390,8 @@ type Constructor extends JSReceiver;
@abstract
@dirtyInstantiatedAbstractClass
@generateCppClass
@apiExposedInstanceTypeValue(0x421)
@highestInstanceTypeWithinParentClassRange
extern class JSObject extends JSReceiver {
// [elements]: The elements (properties with names that are integers).
//
@ -372,6 +423,18 @@ macro NewJSObject(implicit context: Context)(): JSObject {
};
}
@abstract
@generateCppClass
@lowestInstanceTypeWithinParentClassRange
extern class JSCustomElementsObject extends JSObject {
}
@abstract
@generateCppClass
@lowestInstanceTypeWithinParentClassRange
extern class JSSpecialObject extends JSCustomElementsObject {
}
extern macro HasPrototypeSlot(JSFunction): bool;
macro GetDerivedMap(implicit context: Context)(
@ -405,7 +468,8 @@ macro AllocateFastOrSlowJSObjectFromMap(implicit context: Context)(map: Map):
map, properties, kEmptyFixedArray, kNone, kWithSlackTracking);
}
extern class JSFunction extends JSObject {
@highestInstanceTypeWithinParentClassRange
extern class JSFunction extends JSFunctionOrBoundFunction {
shared_function_info: SharedFunctionInfo;
context: Context;
feedback_cell: FeedbackCell;
@ -423,6 +487,7 @@ extern class JSProxy extends JSReceiver {
// Just a starting shape for JSObject; properties can move after initialization.
@noVerifier
@hasSameInstanceTypeAsParent
extern class JSProxyRevocableResult extends JSObject {
proxy: JSAny;
revoke: JSAny;
@ -440,14 +505,14 @@ macro NewJSProxyRevocableResult(implicit context: Context)(
}
@generateCppClass
extern class JSGlobalProxy extends JSObject {
extern class JSGlobalProxy extends JSSpecialObject {
// [native_context]: the owner native context of this global proxy object.
// It is null value if this object is not used by any context.
native_context: Object;
}
@generateCppClass
extern class JSPrimitiveWrapper extends JSObject {
extern class JSPrimitiveWrapper extends JSCustomElementsObject {
value: JSAny;
}
@ -535,8 +600,6 @@ extern class CallHandlerInfo extends Struct {
data: Object;
}
type ObjectHashTable extends FixedArray;
@abstract
extern class Module extends HeapObject {
exports: ObjectHashTable;
@ -590,7 +653,8 @@ extern class SyntheticModule extends Module {
@abstract
@generateCppClass
extern class JSModuleNamespace extends JSObject {
@dirtyInstantiatedAbstractClass
extern class JSModuleNamespace extends JSSpecialObject {
module: Module;
}
@ -613,6 +677,7 @@ extern class JSWeakMap extends JSWeakCollection {
}
@generateCppClass
@abstract
extern class JSCollectionIterator extends JSObject {
// The backing hash table mapping keys to values.
table: Object;
@ -620,6 +685,20 @@ extern class JSCollectionIterator extends JSObject {
index: Object;
}
@abstract extern class JSMapIterator extends JSCollectionIterator;
extern class JSMapKeyIterator extends JSMapIterator
generates 'TNode<JSMapIterator>';
extern class JSMapKeyValueIterator extends JSMapIterator
generates 'TNode<JSMapIterator>';
extern class JSMapValueIterator extends JSMapIterator
generates 'TNode<JSMapIterator>';
@abstract extern class JSSetIterator extends JSCollectionIterator;
extern class JSSetKeyValueIterator extends JSSetIterator
generates 'TNode<JSSetIterator>';
extern class JSSetValueIterator extends JSSetIterator
generates 'TNode<JSSetIterator>';
extern class JSMessageObject extends JSObject {
// Tagged fields.
message_type: Smi;
@ -676,7 +755,7 @@ extern class EmbedderDataArray extends HeapObject {
length: Smi;
}
type ScopeInfo extends HeapObject generates 'TNode<ScopeInfo>';
extern class ScopeInfo extends FixedArray;
@generateCppClass
extern class PreparseData extends HeapObject {
@ -722,8 +801,14 @@ extern class UncompiledDataWithPreparseData extends UncompiledData {
preparse_data: PreparseData;
}
@abstract
@generateCppClass
extern class JSBoundFunction extends JSObject {
@highestInstanceTypeWithinParentClassRange
extern class JSFunctionOrBoundFunction extends JSObject {
}
@generateCppClass
extern class JSBoundFunction extends JSFunctionOrBoundFunction {
// The wrapped function object.
bound_target_function: Callable;
// The value that is always passed as the this value when calling the wrapped
@ -753,8 +838,6 @@ extern operator '.length_intptr' macro LoadAndUntagFixedArrayBaseLength(
FixedArrayBase): intptr;
type SloppyArgumentsElements extends FixedArray;
type NumberDictionary extends HeapObject
generates 'TNode<NumberDictionary>';
extern class FreeSpace extends HeapObject {
size: Smi;
@ -861,7 +944,7 @@ extern class JSDate extends JSObject {
cache_stamp: Undefined | Smi | NaN;
}
extern class JSGlobalObject extends JSObject {
extern class JSGlobalObject extends JSSpecialObject {
native_context: NativeContext;
global_proxy: JSGlobalProxy;
}
@ -976,7 +1059,10 @@ const UTF16:
const UTF32:
constexpr UnicodeEncoding generates 'UnicodeEncoding::UTF32';
extern class Foreign extends HeapObject { foreign_address: RawPtr; }
@apiExposedInstanceTypeValue(0x46)
extern class Foreign extends HeapObject {
foreign_address: RawPtr;
}
@generateCppClass
extern class InterceptorInfo extends Struct {
@ -1015,6 +1101,7 @@ extern class Cell extends HeapObject {
value: Object;
}
@abstract
extern class DataHandler extends Struct {
smi_handler: Smi | Code;
validity_cell: Smi | Cell;
@ -1026,6 +1113,9 @@ extern class DataHandler extends Struct {
@noVerifier weak data_3: Object;
}
extern class LoadHandler extends DataHandler;
extern class StoreHandler extends DataHandler;
@abstract
@dirtyInstantiatedAbstractClass
@generateCppClass
@ -1117,7 +1207,7 @@ extern class ClassPositions extends Struct {
end: Smi;
}
type WasmInstanceObject extends JSObject;
extern class WasmInstanceObject extends JSObject;
extern class WasmExportedFunctionData extends Struct {
wrapper_code: Code;
@ -1542,8 +1632,12 @@ extern class AccessorPair extends Struct {
setter: Object;
}
extern class BreakPoint extends Tuple2 {}
extern class BreakPointInfo extends Tuple2 {}
@hasSameInstanceTypeAsParent
extern class BreakPoint extends Tuple2 {
}
@hasSameInstanceTypeAsParent
extern class BreakPointInfo extends Tuple2 {
}
type CoverageInfo extends FixedArray;
@generateCppClass
@ -1584,7 +1678,9 @@ extern class FeedbackCell extends Struct {
interrupt_budget: int32;
}
type AllocationSite extends Struct;
extern class FeedbackMetadata extends HeapObject;
extern class AllocationSite extends Struct;
extern class AllocationMemento extends Struct {
allocation_site: AllocationSite;
}
@ -1683,6 +1779,29 @@ extern class BytecodeArray extends FixedArrayBase {
bytecode_age: int8;
}
extern class Filler extends HeapObject generates 'TNode<HeapObject>';
extern class CodeDataContainer extends HeapObject;
@abstract
extern class SmallOrderedHashTable extends HeapObject
generates 'TNode<HeapObject>';
extern class SmallOrderedHashMap extends SmallOrderedHashTable;
extern class SmallOrderedHashSet extends SmallOrderedHashTable;
extern class SmallOrderedNameDictionary extends SmallOrderedHashTable;
// Various logical subclasses of JSObject, which have their own instance types
// but not their own class definitions:
// Like JSObject, but created from API function.
@apiExposedInstanceTypeValue(0x420)
extern class JSApiObject extends JSObject generates 'TNode<JSObject>';
// Like JSApiObject, but requires access checks and/or has interceptors.
@apiExposedInstanceTypeValue(0x410)
extern class JSSpecialApiObject extends JSSpecialObject
generates 'TNode<JSSpecialObject>';
extern class JSContextExtensionObject extends JSObject
generates 'TNode<JSObject>';
extern class JSError extends JSObject generates 'TNode<JSObject>';
extern macro Is64(): constexpr bool;
extern macro SelectBooleanConstant(bool): Boolean;

View File

@ -7,7 +7,8 @@
// TODO(nicohartmann): Discuss whether types used by multiple builtins should be
// in global namespace
@noVerifier
extern class BigIntBase extends HeapObject generates 'TNode<BigInt>' {
extern class BigIntBase extends PrimitiveHeapObject
generates 'TNode<BigInt>' {
}
type BigInt extends BigIntBase;

View File

@ -6533,7 +6533,7 @@ TNode<BoolT> CodeStubAssembler::IsBigInt(SloppyTNode<HeapObject> object) {
TNode<BoolT> CodeStubAssembler::IsPrimitiveInstanceType(
SloppyTNode<Int32T> instance_type) {
return Int32LessThanOrEqual(instance_type,
Int32Constant(LAST_PRIMITIVE_TYPE));
Int32Constant(LAST_PRIMITIVE_HEAP_OBJECT_TYPE));
}
TNode<BoolT> CodeStubAssembler::IsPrivateSymbol(
@ -12140,7 +12140,7 @@ TNode<Oddball> CodeStubAssembler::StrictEqual(
BIND(&if_lhsisoddball);
{
STATIC_ASSERT(LAST_PRIMITIVE_TYPE == ODDBALL_TYPE);
STATIC_ASSERT(LAST_PRIMITIVE_HEAP_OBJECT_TYPE == ODDBALL_TYPE);
GotoIf(IsBooleanMap(rhs_map), &if_not_equivalent_types);
GotoIf(Int32LessThan(rhs_instance_type,
Int32Constant(ODDBALL_TYPE)),

View File

@ -31,9 +31,9 @@ bool CanInlinePropertyAccess(Handle<Map> map) {
// We can inline property access to prototypes of all primitives, except
// the special Oddball ones that have no wrapper counterparts (i.e. Null,
// Undefined and TheHole).
STATIC_ASSERT(ODDBALL_TYPE == LAST_PRIMITIVE_TYPE);
STATIC_ASSERT(ODDBALL_TYPE == LAST_PRIMITIVE_HEAP_OBJECT_TYPE);
if (map->IsBooleanMap()) return true;
if (map->instance_type() < LAST_PRIMITIVE_TYPE) return true;
if (map->instance_type() < LAST_PRIMITIVE_HEAP_OBJECT_TYPE) return true;
return map->IsJSObjectMap() && !map->is_dictionary_map() &&
!map->has_named_interceptor() &&
// TODO(verwaest): Whitelist contexts to which we have access.

View File

@ -1963,7 +1963,7 @@ Node* EffectControlLinearizer::LowerCheckReceiverOrNullOrUndefined(
__ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
// Rule out all primitives except oddballs (true, false, undefined, null).
STATIC_ASSERT(LAST_PRIMITIVE_TYPE == ODDBALL_TYPE);
STATIC_ASSERT(LAST_PRIMITIVE_HEAP_OBJECT_TYPE == ODDBALL_TYPE);
STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
Node* check0 = __ Uint32LessThanOrEqual(__ Uint32Constant(ODDBALL_TYPE),
value_instance_type);
@ -2972,10 +2972,11 @@ Node* EffectControlLinearizer::LowerObjectIsArrayBufferView(Node* node) {
Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
Node* value_instance_type =
__ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
STATIC_ASSERT(JS_TYPED_ARRAY_TYPE + 1 == JS_DATA_VIEW_TYPE);
Node* vfalse = __ Uint32LessThan(
__ Int32Sub(value_instance_type, __ Int32Constant(JS_TYPED_ARRAY_TYPE)),
__ Int32Constant(2));
__ Int32Sub(value_instance_type,
__ Int32Constant(FIRST_JS_ARRAY_BUFFER_VIEW_TYPE)),
__ Int32Constant(LAST_JS_ARRAY_BUFFER_VIEW_TYPE -
FIRST_JS_ARRAY_BUFFER_VIEW_TYPE + 1));
__ Goto(&done, vfalse);
__ Bind(&if_smi);

View File

@ -2900,7 +2900,7 @@ bool MapRef::IsFixedCowArrayMap() const {
}
bool MapRef::IsPrimitiveMap() const {
return instance_type() <= LAST_PRIMITIVE_TYPE;
return instance_type() <= LAST_PRIMITIVE_HEAP_OBJECT_TYPE;
}
MapRef MapRef::FindFieldOwner(InternalIndex descriptor_index) const {

View File

@ -365,7 +365,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_DEFINED_INSTANCE_TYPES(MAKE_TORQUE_CLASS_TYPE)
TORQUE_INTERNAL_INSTANCE_TYPES(MAKE_TORQUE_CLASS_TYPE)
#undef MAKE_TORQUE_CLASS_TYPE
UNREACHABLE();
}

View File

@ -6,8 +6,8 @@
#define V8_OBJECTS_BIGINT_H_
#include "src/common/globals.h"
#include "src/objects/heap-object.h"
#include "src/objects/objects.h"
#include "src/objects/primitive-heap-object.h"
#include "src/utils/utils.h"
// Has to be the last include (doesn't have include guards):
@ -28,7 +28,7 @@ class ValueSerializer;
// BigIntBase is just the raw data object underlying a BigInt. Use with care!
// Most code should be using BigInts instead.
class BigIntBase : public HeapObject {
class BigIntBase : public PrimitiveHeapObject {
public:
inline int length() const {
int32_t bitfield = RELAXED_READ_INT32_FIELD(*this, kBitfieldOffset);
@ -69,7 +69,7 @@ class BigIntBase : public HeapObject {
V(kHeaderSize, 0) \
V(kDigitsOffset, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, BIGINT_FIELDS)
DEFINE_FIELD_OFFSET_CONSTANTS(PrimitiveHeapObject::kHeaderSize, BIGINT_FIELDS)
#undef BIGINT_FIELDS
static constexpr bool HasOptionalPadding() {
@ -105,7 +105,7 @@ class BigIntBase : public HeapObject {
// Only serves to make macros happy; other code should use IsBigInt.
bool IsBigIntBase() const { return true; }
OBJECT_CONSTRUCTORS(BigIntBase, HeapObject);
OBJECT_CONSTRUCTORS(BigIntBase, PrimitiveHeapObject);
};
class FreshlyAllocatedBigInt : public BigIntBase {

View File

@ -480,18 +480,18 @@ class Context : public HeapObject {
TORQUE_GENERATED_CONTEXT_FIELDS)
// TODO(v8:8989): [torque] Support marker constants.
/* TODO(ishell): remove this fixedArray-like header size. */
static const int kHeaderSize = kScopeInfoOffset;
static const int kFixedArrayLikeHeaderSize = kScopeInfoOffset;
static const int kStartOfTaggedFieldsOffset = kScopeInfoOffset;
/* Header size. */ \
/* TODO(ishell): use this as header size once MIN_CONTEXT_SLOTS */ \
/* is removed in favour of offset-based access to common fields. */ \
static const int kTodoHeaderSize = kSize;
static const int kTodoHeaderSize = kHeaderSize;
// Garbage collection support.
V8_INLINE static constexpr int SizeFor(int length) {
// TODO(ishell): switch to kTodoHeaderSize based approach once we no longer
// reference common Context fields via index
return kHeaderSize + length * kTaggedSize;
return kFixedArrayLikeHeaderSize + length * kTaggedSize;
}
// Code Generation support.

View File

@ -41,7 +41,7 @@ class DataHandler : public Struct {
static const int kSizeWithData0 = kData1Offset;
static const int kSizeWithData1 = kData2Offset;
static const int kSizeWithData2 = kData3Offset;
static const int kSizeWithData3 = kSize;
static const int kSizeWithData3 = kHeaderSize;
DECL_CAST(DataHandler)

View File

@ -303,7 +303,6 @@ class WeakFixedArray : public HeapObject {
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
TORQUE_GENERATED_WEAK_FIXED_ARRAY_FIELDS)
static constexpr int kHeaderSize = kSize;
static const int kMaxLength =
(FixedArray::kMaxSize - kHeaderSize) / kTaggedSize;

View File

@ -7,8 +7,8 @@
#include "src/objects/heap-number.h"
#include "src/objects/heap-object-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/primitive-heap-object-inl.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@ -16,7 +16,7 @@
namespace v8 {
namespace internal {
OBJECT_CONSTRUCTORS_IMPL(HeapNumber, HeapObject)
OBJECT_CONSTRUCTORS_IMPL(HeapNumber, PrimitiveHeapObject)
CAST_ACCESSOR(HeapNumber)

View File

@ -5,7 +5,7 @@
#ifndef V8_OBJECTS_HEAP_NUMBER_H_
#define V8_OBJECTS_HEAP_NUMBER_H_
#include "src/objects/heap-object.h"
#include "src/objects/primitive-heap-object.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@ -15,7 +15,7 @@ namespace internal {
// The HeapNumber class describes heap allocated numbers that cannot be
// represented in a Smi (small integer).
class HeapNumber : public HeapObject {
class HeapNumber : public PrimitiveHeapObject {
public:
// [value]: number value.
inline double value() const;
@ -28,7 +28,7 @@ class HeapNumber : public HeapObject {
inline int get_sign();
// Layout description.
static const int kValueOffset = HeapObject::kHeaderSize;
static const int kValueOffset = PrimitiveHeapObject::kHeaderSize;
// IEEE doubles are two 32 bit words. The first is just mantissa, the second
// is a mixture of sign, exponent and mantissa. The offsets of two 32 bit
// words within double numbers are endian dependent and they are set
@ -59,7 +59,7 @@ class HeapNumber : public HeapObject {
DECL_CAST(HeapNumber)
V8_EXPORT_PRIVATE void HeapNumberPrint(std::ostream& os);
OBJECT_CONSTRUCTORS(HeapNumber, HeapObject);
OBJECT_CONSTRUCTORS(HeapNumber, PrimitiveHeapObject);
};
} // namespace internal

View File

@ -80,8 +80,8 @@ static inline bool IsShortcutCandidate(int type) {
enum InstanceType : uint16_t {
// String types.
INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kSeqStringTag |
kInternalizedTag, // FIRST_PRIMITIVE_TYPE
INTERNALIZED_STRING_TYPE =
kTwoByteStringTag | kSeqStringTag | kInternalizedTag,
ONE_BYTE_INTERNALIZED_STRING_TYPE =
kOneByteStringTag | kSeqStringTag | kInternalizedTag,
EXTERNAL_INTERNALIZED_STRING_TYPE =
@ -116,262 +116,41 @@ enum InstanceType : uint16_t {
THIN_ONE_BYTE_STRING_TYPE =
kOneByteStringTag | kThinStringTag | kNotInternalizedTag,
// Non-string names
SYMBOL_TYPE =
1 + (kIsNotInternalizedMask | kUncachedExternalStringMask |
kStringEncodingMask |
kStringRepresentationMask), // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE
// Other primitives (cannot contain non-map-word pointers to heap objects).
HEAP_NUMBER_TYPE,
BIGINT_TYPE,
ODDBALL_TYPE, // LAST_PRIMITIVE_TYPE
// Objects allocated in their own spaces (never in new space).
MAP_TYPE,
CODE_TYPE,
// "Data", objects that cannot contain non-map-word pointers to heap
// objects.
FOREIGN_TYPE,
BYTE_ARRAY_TYPE,
BYTECODE_ARRAY_TYPE,
FREE_SPACE_TYPE,
FIXED_DOUBLE_ARRAY_TYPE,
FEEDBACK_METADATA_TYPE,
FILLER_TYPE, // LAST_DATA_TYPE
// Structs.
ACCESS_CHECK_INFO_TYPE,
ACCESSOR_INFO_TYPE,
ACCESSOR_PAIR_TYPE,
ALIASED_ARGUMENTS_ENTRY_TYPE,
ALLOCATION_MEMENTO_TYPE,
ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
ASM_WASM_DATA_TYPE,
ASYNC_GENERATOR_REQUEST_TYPE,
CLASS_POSITIONS_TYPE,
DEBUG_INFO_TYPE,
ENUM_CACHE_TYPE,
FUNCTION_TEMPLATE_INFO_TYPE,
FUNCTION_TEMPLATE_RARE_DATA_TYPE,
INTERCEPTOR_INFO_TYPE,
INTERPRETER_DATA_TYPE,
OBJECT_TEMPLATE_INFO_TYPE,
PROMISE_CAPABILITY_TYPE,
PROMISE_REACTION_TYPE,
PROTOTYPE_INFO_TYPE,
SCRIPT_TYPE,
SOURCE_POSITION_TABLE_WITH_FRAME_CACHE_TYPE,
SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE,
STACK_FRAME_INFO_TYPE,
STACK_TRACE_FRAME_TYPE,
TEMPLATE_OBJECT_DESCRIPTION_TYPE,
TUPLE2_TYPE,
TUPLE3_TYPE,
WASM_CAPI_FUNCTION_DATA_TYPE,
WASM_DEBUG_INFO_TYPE,
WASM_EXCEPTION_TAG_TYPE,
WASM_EXPORTED_FUNCTION_DATA_TYPE,
WASM_INDIRECT_FUNCTION_TABLE_TYPE,
WASM_JS_FUNCTION_DATA_TYPE,
CALLABLE_TASK_TYPE, // FIRST_MICROTASK_TYPE
CALLBACK_TASK_TYPE,
PROMISE_FULFILL_REACTION_JOB_TASK_TYPE,
PROMISE_REJECT_REACTION_JOB_TASK_TYPE,
PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE, // LAST_MICROTASK_TYPE
#define MAKE_TORQUE_INSTANCE_TYPE(V) V,
TORQUE_DEFINED_INSTANCE_TYPES(MAKE_TORQUE_INSTANCE_TYPE)
// Most instance types are defined in Torque, with the exception of the string
// types above. They are ordered by inheritance hierarchy so that we can easily
// use range checks to determine whether an object is an instance of a subclass
// of any type. There are a few more constraints specified in the Torque type
// definitions:
// - Some instance types are exposed in v8.h, so they are locked to specific
// values to not unnecessarily change the ABI.
// - JSSpecialObject and JSCustomElementsObject are aligned with the beginning
// of the JSObject range, so that we can use a larger range check from
// FIRST_JS_RECEIVER_TYPE to the end of those ranges and include JSProxy too.
// - JSFunction is last, meaning we can use a single inequality check to
// determine whether an instance type is within the range for any class in the
// inheritance hierarchy of JSFunction. This includes commonly-checked classes
// JSObject and JSReceiver.
#define MAKE_TORQUE_INSTANCE_TYPE(TYPE, value) TYPE = value,
TORQUE_ASSIGNED_INSTANCE_TYPES(MAKE_TORQUE_INSTANCE_TYPE)
#undef MAKE_TORQUE_INSTANCE_TYPE
// Modules
SOURCE_TEXT_MODULE_TYPE, // FIRST_MODULE_TYPE
SYNTHETIC_MODULE_TYPE, // LAST_MODULE_TYPE
ALLOCATION_SITE_TYPE,
EMBEDDER_DATA_ARRAY_TYPE,
// FixedArrays.
FIXED_ARRAY_TYPE, // FIRST_FIXED_ARRAY_TYPE
OBJECT_BOILERPLATE_DESCRIPTION_TYPE,
CLOSURE_FEEDBACK_CELL_ARRAY_TYPE,
HASH_TABLE_TYPE, // FIRST_HASH_TABLE_TYPE
ORDERED_HASH_MAP_TYPE,
ORDERED_HASH_SET_TYPE,
ORDERED_NAME_DICTIONARY_TYPE,
NAME_DICTIONARY_TYPE,
GLOBAL_DICTIONARY_TYPE,
NUMBER_DICTIONARY_TYPE,
SIMPLE_NUMBER_DICTIONARY_TYPE,
STRING_TABLE_TYPE,
EPHEMERON_HASH_TABLE_TYPE, // LAST_HASH_TABLE_TYPE
SCOPE_INFO_TYPE,
SCRIPT_CONTEXT_TABLE_TYPE, // LAST_FIXED_ARRAY_TYPE,
// Contexts.
AWAIT_CONTEXT_TYPE, // FIRST_CONTEXT_TYPE
BLOCK_CONTEXT_TYPE,
CATCH_CONTEXT_TYPE,
DEBUG_EVALUATE_CONTEXT_TYPE,
EVAL_CONTEXT_TYPE,
FUNCTION_CONTEXT_TYPE,
MODULE_CONTEXT_TYPE,
NATIVE_CONTEXT_TYPE,
SCRIPT_CONTEXT_TYPE,
WITH_CONTEXT_TYPE, // LAST_CONTEXT_TYPE
WEAK_FIXED_ARRAY_TYPE, // FIRST_WEAK_FIXED_ARRAY_TYPE
TRANSITION_ARRAY_TYPE, // LAST_WEAK_FIXED_ARRAY_TYPE
// Misc.
CALL_HANDLER_INFO_TYPE,
CELL_TYPE,
CODE_DATA_CONTAINER_TYPE,
DESCRIPTOR_ARRAY_TYPE,
FEEDBACK_CELL_TYPE,
FEEDBACK_VECTOR_TYPE,
LOAD_HANDLER_TYPE,
PREPARSE_DATA_TYPE,
PROPERTY_ARRAY_TYPE,
PROPERTY_CELL_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SMALL_ORDERED_HASH_MAP_TYPE,
SMALL_ORDERED_HASH_SET_TYPE,
SMALL_ORDERED_NAME_DICTIONARY_TYPE,
STORE_HANDLER_TYPE,
UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE,
UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE,
WEAK_ARRAY_LIST_TYPE,
WEAK_CELL_TYPE,
// All the following types are subtypes of JSReceiver, which corresponds to
// objects in the JS sense. The first and the last type in this range are
// the two forms of function. This organization enables using the same
// compares for checking the JS_RECEIVER and the NONCALLABLE_JS_OBJECT range.
// Some of the following instance types are exposed in v8.h, so to not
// unnecessarily change the ABI when we introduce new instance types in the
// future, we leave some space between instance types.
JS_PROXY_TYPE = 0x0400, // FIRST_JS_RECEIVER_TYPE
JS_GLOBAL_OBJECT_TYPE, // FIRST_JS_OBJECT_TYPE
JS_GLOBAL_PROXY_TYPE,
JS_MODULE_NAMESPACE_TYPE,
// Like JS_API_OBJECT_TYPE, but requires access checks and/or has
// interceptors.
JS_SPECIAL_API_OBJECT_TYPE = 0x0410, // LAST_SPECIAL_RECEIVER_TYPE
JS_PRIMITIVE_WRAPPER_TYPE, // LAST_CUSTOM_ELEMENTS_RECEIVER
// Like JS_OBJECT_TYPE, but created from API function.
JS_API_OBJECT_TYPE = 0x0420,
JS_OBJECT_TYPE,
JS_ARGUMENTS_OBJECT_TYPE,
JS_ARRAY_BUFFER_TYPE,
JS_ARRAY_ITERATOR_TYPE,
JS_ARRAY_TYPE,
JS_ASYNC_FROM_SYNC_ITERATOR_TYPE,
JS_ASYNC_FUNCTION_OBJECT_TYPE,
JS_ASYNC_GENERATOR_OBJECT_TYPE,
JS_CONTEXT_EXTENSION_OBJECT_TYPE,
JS_DATE_TYPE,
JS_ERROR_TYPE,
JS_GENERATOR_OBJECT_TYPE,
JS_MAP_TYPE,
JS_MAP_KEY_ITERATOR_TYPE,
JS_MAP_KEY_VALUE_ITERATOR_TYPE,
JS_MAP_VALUE_ITERATOR_TYPE,
JS_MESSAGE_OBJECT_TYPE,
JS_PROMISE_TYPE,
JS_REG_EXP_TYPE,
JS_REG_EXP_STRING_ITERATOR_TYPE,
JS_SET_TYPE,
JS_SET_KEY_VALUE_ITERATOR_TYPE,
JS_SET_VALUE_ITERATOR_TYPE,
JS_STRING_ITERATOR_TYPE,
JS_WEAK_REF_TYPE,
JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE,
JS_FINALIZATION_GROUP_TYPE,
JS_WEAK_MAP_TYPE,
JS_WEAK_SET_TYPE,
JS_TYPED_ARRAY_TYPE,
JS_DATA_VIEW_TYPE,
#ifdef V8_INTL_SUPPORT
JS_V8_BREAK_ITERATOR_TYPE,
JS_COLLATOR_TYPE,
JS_DATE_TIME_FORMAT_TYPE,
JS_LIST_FORMAT_TYPE,
JS_LOCALE_TYPE,
JS_NUMBER_FORMAT_TYPE,
JS_PLURAL_RULES_TYPE,
JS_RELATIVE_TIME_FORMAT_TYPE,
JS_SEGMENT_ITERATOR_TYPE,
JS_SEGMENTER_TYPE,
#endif // V8_INTL_SUPPORT
WASM_EXCEPTION_OBJECT_TYPE,
WASM_GLOBAL_OBJECT_TYPE,
WASM_INSTANCE_OBJECT_TYPE,
WASM_MEMORY_OBJECT_TYPE,
WASM_MODULE_OBJECT_TYPE,
WASM_TABLE_OBJECT_TYPE,
JS_BOUND_FUNCTION_TYPE,
JS_FUNCTION_TYPE, // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE
// Pseudo-types
FIRST_TYPE = 0x0,
LAST_TYPE = JS_FUNCTION_TYPE,
FIRST_STRING_TYPE = FIRST_TYPE,
FIRST_NAME_TYPE = FIRST_STRING_TYPE,
LAST_NAME_TYPE = SYMBOL_TYPE,
FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
FIRST_PRIMITIVE_TYPE = FIRST_NAME_TYPE,
LAST_PRIMITIVE_TYPE = ODDBALL_TYPE,
FIRST_FUNCTION_TYPE = JS_BOUND_FUNCTION_TYPE,
LAST_FUNCTION_TYPE = JS_FUNCTION_TYPE,
// Boundaries for testing if given HeapObject is a subclass of FixedArray.
FIRST_FIXED_ARRAY_TYPE = FIXED_ARRAY_TYPE,
LAST_FIXED_ARRAY_TYPE = SCRIPT_CONTEXT_TABLE_TYPE,
// Boundaries for testing if given HeapObject is a subclass of HashTable
FIRST_HASH_TABLE_TYPE = HASH_TABLE_TYPE,
LAST_HASH_TABLE_TYPE = EPHEMERON_HASH_TABLE_TYPE,
// Boundaries for testing if given HeapObject is a subclass of WeakFixedArray.
FIRST_WEAK_FIXED_ARRAY_TYPE = WEAK_FIXED_ARRAY_TYPE,
LAST_WEAK_FIXED_ARRAY_TYPE = TRANSITION_ARRAY_TYPE,
// Boundaries for testing if given HeapObject is a Context
FIRST_CONTEXT_TYPE = AWAIT_CONTEXT_TYPE,
LAST_CONTEXT_TYPE = WITH_CONTEXT_TYPE,
// Boundaries for testing if given HeapObject is a subclass of Microtask.
FIRST_MICROTASK_TYPE = CALLABLE_TASK_TYPE,
LAST_MICROTASK_TYPE = PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE,
// Boundaries of module record types
FIRST_MODULE_TYPE = SOURCE_TEXT_MODULE_TYPE,
LAST_MODULE_TYPE = SYNTHETIC_MODULE_TYPE,
// Boundary for promotion to old space.
LAST_DATA_TYPE = FILLER_TYPE,
// Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
// Note that there is no range for JSObject or JSProxy, since their subtypes
// are not continuous in this enum! The enum ranges instead reflect the
// external class names, where proxies are treated as either ordinary objects,
// or functions.
FIRST_JS_RECEIVER_TYPE = JS_PROXY_TYPE,
LAST_JS_RECEIVER_TYPE = LAST_TYPE,
// Boundaries for testing the types represented as JSObject
FIRST_JS_OBJECT_TYPE = JS_GLOBAL_OBJECT_TYPE,
LAST_JS_OBJECT_TYPE = LAST_TYPE,
// Boundary for testing JSReceivers that need special property lookup handling
LAST_SPECIAL_RECEIVER_TYPE = JS_SPECIAL_API_OBJECT_TYPE,
LAST_SPECIAL_RECEIVER_TYPE = LAST_JS_SPECIAL_OBJECT_TYPE,
// Boundary case for testing JSReceivers that may have elements while having
// an empty fixed array as elements backing store. This is true for string
// wrappers.
LAST_CUSTOM_ELEMENTS_RECEIVER = JS_PRIMITIVE_WRAPPER_TYPE,
LAST_CUSTOM_ELEMENTS_RECEIVER = LAST_JS_CUSTOM_ELEMENTS_OBJECT_TYPE,
FIRST_JS_SET_ITERATOR_TYPE = JS_SET_KEY_VALUE_ITERATOR_TYPE,
LAST_JS_SET_ITERATOR_TYPE = JS_SET_VALUE_ITERATOR_TYPE,
FIRST_JS_MAP_ITERATOR_TYPE = JS_MAP_KEY_ITERATOR_TYPE,
LAST_JS_MAP_ITERATOR_TYPE = JS_MAP_VALUE_ITERATOR_TYPE,
// Convenient names for things where the generated name is awkward:
FIRST_TYPE = FIRST_HEAP_OBJECT_TYPE,
LAST_TYPE = LAST_HEAP_OBJECT_TYPE,
FIRST_FUNCTION_TYPE = FIRST_JS_FUNCTION_OR_BOUND_FUNCTION_TYPE,
LAST_FUNCTION_TYPE = LAST_JS_FUNCTION_OR_BOUND_FUNCTION_TYPE,
BIGINT_TYPE = BIG_INT_BASE_TYPE,
};
// This constant is defined outside of the InstanceType enum because the
@ -389,6 +168,40 @@ STATIC_ASSERT(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
STATIC_ASSERT(ODDBALL_TYPE == Internals::kOddballType);
STATIC_ASSERT(FOREIGN_TYPE == Internals::kForeignType);
// Verify that string types are all less than other types.
#define CHECK_STRING_RANGE(TYPE, ...) \
STATIC_ASSERT(TYPE < FIRST_NONSTRING_TYPE);
STRING_TYPE_LIST(CHECK_STRING_RANGE)
#undef CHECK_STRING_RANGE
#define CHECK_NONSTRING_RANGE(TYPE) STATIC_ASSERT(TYPE >= FIRST_NONSTRING_TYPE);
TORQUE_ASSIGNED_INSTANCE_TYPE_LIST(CHECK_NONSTRING_RANGE)
#undef CHECK_NONSTRING_RANGE
// Two ranges don't cleanly follow the inheritance hierarchy. Here we ensure
// that only expected types fall within these ranges.
// - From FIRST_JS_RECEIVER_TYPE to LAST_SPECIAL_RECEIVER_TYPE should correspond
// to the union type JSProxy | JSSpecialObject.
// - From FIRST_JS_RECEIVER_TYPE to LAST_CUSTOM_ELEMENTS_RECEIVER should
// correspond to the union type JSProxy | JSCustomElementsObject.
// Note in particular that these ranges include all subclasses of JSReceiver
// that are not also subclasses of JSObject (currently only JSProxy).
#define CHECK_INSTANCE_TYPE(TYPE) \
STATIC_ASSERT((TYPE >= FIRST_JS_RECEIVER_TYPE && \
TYPE <= LAST_SPECIAL_RECEIVER_TYPE) == \
(TYPE == JS_PROXY_TYPE || TYPE == JS_GLOBAL_OBJECT_TYPE || \
TYPE == JS_GLOBAL_PROXY_TYPE || \
TYPE == JS_MODULE_NAMESPACE_TYPE || \
TYPE == JS_SPECIAL_API_OBJECT_TYPE)); \
STATIC_ASSERT((TYPE >= FIRST_JS_RECEIVER_TYPE && \
TYPE <= LAST_CUSTOM_ELEMENTS_RECEIVER) == \
(TYPE == JS_PROXY_TYPE || TYPE == JS_GLOBAL_OBJECT_TYPE || \
TYPE == JS_GLOBAL_PROXY_TYPE || \
TYPE == JS_MODULE_NAMESPACE_TYPE || \
TYPE == JS_SPECIAL_API_OBJECT_TYPE || \
TYPE == JS_PRIMITIVE_WRAPPER_TYPE));
TORQUE_ASSIGNED_INSTANCE_TYPE_LIST(CHECK_INSTANCE_TYPE)
#undef CHECK_INSTANCE_TYPE
// Make sure it doesn't matter whether we sign-extend or zero-extend these
// values, because Torque treats InstanceType as signed.
STATIC_ASSERT(LAST_TYPE < 1 << 15);
@ -521,11 +334,18 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
V(Context, FIRST_CONTEXT_TYPE, LAST_CONTEXT_TYPE) \
V(FixedArray, FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE) \
V(HashTable, FIRST_HASH_TABLE_TYPE, LAST_HASH_TABLE_TYPE) \
V(JSCustomElementsObject, FIRST_JS_CUSTOM_ELEMENTS_OBJECT_TYPE, \
LAST_JS_CUSTOM_ELEMENTS_OBJECT_TYPE) \
V(JSFunctionOrBoundFunction, FIRST_FUNCTION_TYPE, LAST_FUNCTION_TYPE) \
V(JSMapIterator, FIRST_JS_MAP_ITERATOR_TYPE, LAST_JS_MAP_ITERATOR_TYPE) \
V(JSSetIterator, FIRST_JS_SET_ITERATOR_TYPE, LAST_JS_SET_ITERATOR_TYPE) \
V(JSSpecialObject, FIRST_JS_SPECIAL_OBJECT_TYPE, \
LAST_JS_SPECIAL_OBJECT_TYPE) \
V(Microtask, FIRST_MICROTASK_TYPE, LAST_MICROTASK_TYPE) \
V(Module, FIRST_MODULE_TYPE, LAST_MODULE_TYPE) \
V(Name, FIRST_NAME_TYPE, LAST_NAME_TYPE) \
V(PrimitiveHeapObject, FIRST_PRIMITIVE_HEAP_OBJECT_TYPE, \
LAST_PRIMITIVE_HEAP_OBJECT_TYPE) \
V(String, FIRST_STRING_TYPE, LAST_STRING_TYPE) \
V(WeakFixedArray, FIRST_WEAK_FIXED_ARRAY_TYPE, LAST_WEAK_FIXED_ARRAY_TYPE)

View File

@ -22,6 +22,10 @@ class JSCollectionIterator
public:
void JSCollectionIteratorPrint(std::ostream& os, const char* name);
// JSCollectionIterator is abstract, but also defines the size for all of its
// concrete subclasses.
static constexpr int kSize = kHeaderSize;
TQ_OBJECT_CONSTRUCTORS(JSCollectionIterator)
};

View File

@ -31,11 +31,14 @@ namespace internal {
OBJECT_CONSTRUCTORS_IMPL(JSReceiver, HeapObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSCustomElementsObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSSpecialObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSAsyncFromSyncIterator)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSFunctionOrBoundFunction)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSBoundFunction)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSDate)
OBJECT_CONSTRUCTORS_IMPL(JSFunction, JSObject)
OBJECT_CONSTRUCTORS_IMPL(JSGlobalObject, JSObject)
OBJECT_CONSTRUCTORS_IMPL(JSFunction, JSFunctionOrBoundFunction)
OBJECT_CONSTRUCTORS_IMPL(JSGlobalObject, JSSpecialObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSGlobalProxy)
JSIteratorResult::JSIteratorResult(Address ptr) : JSObject(ptr) {}
OBJECT_CONSTRUCTORS_IMPL(JSMessageObject, JSObject)

View File

@ -808,6 +808,29 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
TQ_OBJECT_CONSTRUCTORS(JSObject)
};
// An abstract superclass for JSObjects that may have elements while having an
// empty fixed array as elements backing store. It doesn't carry any
// functionality but allows function classes to be identified in the type
// system.
class JSCustomElementsObject
: public TorqueGeneratedJSCustomElementsObject<JSCustomElementsObject,
JSObject> {
public:
STATIC_ASSERT(kHeaderSize == JSObject::kHeaderSize);
TQ_OBJECT_CONSTRUCTORS(JSCustomElementsObject)
};
// An abstract superclass for JSObjects that require non-standard element
// access. It doesn't carry any functionality but allows function classes to be
// identified in the type system.
class JSSpecialObject
: public TorqueGeneratedJSSpecialObject<JSSpecialObject,
JSCustomElementsObject> {
public:
STATIC_ASSERT(kHeaderSize == JSObject::kHeaderSize);
TQ_OBJECT_CONSTRUCTORS(JSSpecialObject)
};
// JSAccessorPropertyDescriptor is just a JSObject with a specific initial
// map. This initial map adds in-object properties for "get", "set",
// "enumerable" and "configurable" properties, as assigned by the
@ -895,9 +918,21 @@ class JSIteratorResult : public JSObject {
OBJECT_CONSTRUCTORS(JSIteratorResult, JSObject);
};
// An abstract superclass for classes representing JavaScript function values.
// It doesn't carry any functionality but allows function classes to be
// identified in the type system.
class JSFunctionOrBoundFunction
: public TorqueGeneratedJSFunctionOrBoundFunction<JSFunctionOrBoundFunction,
JSObject> {
public:
STATIC_ASSERT(kHeaderSize == JSObject::kHeaderSize);
TQ_OBJECT_CONSTRUCTORS(JSFunctionOrBoundFunction)
};
// JSBoundFunction describes a bound function exotic object.
class JSBoundFunction
: public TorqueGeneratedJSBoundFunction<JSBoundFunction, JSObject> {
: public TorqueGeneratedJSBoundFunction<JSBoundFunction,
JSFunctionOrBoundFunction> {
public:
static MaybeHandle<String> GetName(Isolate* isolate,
Handle<JSBoundFunction> function);
@ -918,7 +953,7 @@ class JSBoundFunction
};
// JSFunction describes JavaScript functions.
class JSFunction : public JSObject {
class JSFunction : public JSFunctionOrBoundFunction {
public:
// [prototype_or_initial_map]:
DECL_ACCESSORS(prototype_or_initial_map, HeapObject)
@ -1121,13 +1156,13 @@ class JSFunction : public JSObject {
// ES6 section 19.2.3.5 Function.prototype.toString ( ).
static Handle<String> ToString(Handle<JSFunction> function);
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
DEFINE_FIELD_OFFSET_CONSTANTS(JSFunctionOrBoundFunction::kHeaderSize,
TORQUE_GENERATED_JS_FUNCTION_FIELDS)
static constexpr int kSizeWithoutPrototype = kPrototypeOrInitialMapOffset;
static constexpr int kSizeWithPrototype = kSize;
OBJECT_CONSTRUCTORS(JSFunction, JSObject);
OBJECT_CONSTRUCTORS(JSFunction, JSFunctionOrBoundFunction);
};
// JSGlobalProxy's prototype must be a JSGlobalObject or null,
@ -1139,7 +1174,7 @@ class JSFunction : public JSObject {
// Accessing a JSGlobalProxy requires security check.
class JSGlobalProxy
: public TorqueGeneratedJSGlobalProxy<JSGlobalProxy, JSObject> {
: public TorqueGeneratedJSGlobalProxy<JSGlobalProxy, JSSpecialObject> {
public:
inline bool IsDetachedFrom(JSGlobalObject global) const;
@ -1153,7 +1188,7 @@ class JSGlobalProxy
};
// JavaScript global object.
class JSGlobalObject : public JSObject {
class JSGlobalObject : public JSSpecialObject {
public:
// [native context]: the natives corresponding to this global object.
DECL_ACCESSORS(native_context, NativeContext)
@ -1181,15 +1216,16 @@ class JSGlobalObject : public JSObject {
DECL_VERIFIER(JSGlobalObject)
// Layout description.
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
DEFINE_FIELD_OFFSET_CONSTANTS(JSSpecialObject::kHeaderSize,
TORQUE_GENERATED_JS_GLOBAL_OBJECT_FIELDS)
OBJECT_CONSTRUCTORS(JSGlobalObject, JSObject);
OBJECT_CONSTRUCTORS(JSGlobalObject, JSSpecialObject);
};
// Representation for JS Wrapper objects, String, Number, Boolean, etc.
class JSPrimitiveWrapper
: public TorqueGeneratedJSPrimitiveWrapper<JSPrimitiveWrapper, JSObject> {
: public TorqueGeneratedJSPrimitiveWrapper<JSPrimitiveWrapper,
JSCustomElementsObject> {
public:
// Dispatched behavior.
DECL_PRINTER(JSPrimitiveWrapper)

View File

@ -588,7 +588,7 @@ bool Map::IsNullOrUndefinedMap() const {
}
bool Map::IsPrimitiveMap() const {
return instance_type() <= LAST_PRIMITIVE_TYPE;
return instance_type() <= LAST_PRIMITIVE_HEAP_OBJECT_TYPE;
}
LayoutDescriptor Map::layout_descriptor_gc_safe() const {

View File

@ -138,7 +138,8 @@ class Module : public HeapObject {
// JSModuleNamespace object (representing module "bar") is created and bound to
// the declared variable (foo). A module can have at most one namespace object.
class JSModuleNamespace
: public TorqueGeneratedJSModuleNamespace<JSModuleNamespace, JSObject> {
: public TorqueGeneratedJSModuleNamespace<JSModuleNamespace,
JSSpecialObject> {
public:
DECL_PRINTER(JSModuleNamespace)

View File

@ -9,6 +9,7 @@
#include "src/heap/heap-write-barrier-inl.h"
#include "src/objects/map-inl.h"
#include "src/objects/primitive-heap-object-inl.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

View File

@ -5,9 +5,8 @@
#ifndef V8_OBJECTS_NAME_H_
#define V8_OBJECTS_NAME_H_
#include "src/objects/heap-object.h"
#include "src/objects/objects.h"
#include "torque-generated/class-definitions-tq.h"
#include "src/objects/primitive-heap-object.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@ -17,7 +16,7 @@ namespace internal {
// The Name abstract class captures anything that can be used as a property
// name, i.e., strings and symbols. All names store a hash value.
class Name : public TorqueGeneratedName<Name, HeapObject> {
class Name : public TorqueGeneratedName<Name, PrimitiveHeapObject> {
public:
// Tells whether the hash code has been computed.
inline bool HasHashCode();

View File

@ -139,12 +139,14 @@ class ZoneForwardList;
V(JSCollection) \
V(JSCollectionIterator) \
V(JSContextExtensionObject) \
V(JSCustomElementsObject) \
V(JSDataView) \
V(JSDate) \
V(JSError) \
V(JSFinalizationGroup) \
V(JSFinalizationGroupCleanupIterator) \
V(JSFunction) \
V(JSFunctionOrBoundFunction) \
V(JSGeneratorObject) \
V(JSGlobalObject) \
V(JSGlobalProxy) \
@ -164,6 +166,7 @@ class ZoneForwardList;
V(JSSet) \
V(JSSetIterator) \
V(JSSloppyArgumentsObject) \
V(JSSpecialObject) \
V(JSStringIterator) \
V(JSTypedArray) \
V(JSWeakCollection) \
@ -189,6 +192,7 @@ class ZoneForwardList;
V(OrderedNameDictionary) \
V(OSROptimizedCodeCache) \
V(PreparseData) \
V(PrimitiveHeapObject) \
V(PromiseReactionJobTask) \
V(PropertyArray) \
V(PropertyCell) \

View File

@ -32,15 +32,7 @@ namespace internal {
// instance_types that are less than those of all other types:
// HeapObject::Size, HeapObject::IterateBody, the typeof operator, and
// Object::IsString.
//
// NOTE: Everything following JS_PRIMITIVE_WRAPPER_TYPE is considered a
// JSObject for GC purposes. The first four entries here have typeof
// 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
//
// NOTE: List had to be split into two, because of conditional item(s) from
// INTL namespace. They can't just be appended to the end, because of the
// checks we do in tests (expecting JS_FUNCTION_TYPE to be last).
#define INSTANCE_TYPE_LIST_BEFORE_INTL(V) \
#define INSTANCE_TYPE_LIST_BASE(V) \
V(INTERNALIZED_STRING_TYPE) \
V(EXTERNAL_INTERNALIZED_STRING_TYPE) \
V(ONE_BYTE_INTERNALIZED_STRING_TYPE) \
@ -58,191 +50,11 @@ namespace internal {
V(SLICED_ONE_BYTE_STRING_TYPE) \
V(THIN_ONE_BYTE_STRING_TYPE) \
V(UNCACHED_EXTERNAL_STRING_TYPE) \
V(UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE) \
\
V(SYMBOL_TYPE) \
V(HEAP_NUMBER_TYPE) \
V(BIGINT_TYPE) \
V(ODDBALL_TYPE) \
\
V(MAP_TYPE) \
V(CODE_TYPE) \
V(FOREIGN_TYPE) \
V(BYTE_ARRAY_TYPE) \
V(BYTECODE_ARRAY_TYPE) \
V(FREE_SPACE_TYPE) \
\
V(FIXED_DOUBLE_ARRAY_TYPE) \
V(FEEDBACK_METADATA_TYPE) \
V(FILLER_TYPE) \
\
V(ACCESS_CHECK_INFO_TYPE) \
V(ACCESSOR_INFO_TYPE) \
V(ACCESSOR_PAIR_TYPE) \
V(ALIASED_ARGUMENTS_ENTRY_TYPE) \
V(ALLOCATION_MEMENTO_TYPE) \
V(ARRAY_BOILERPLATE_DESCRIPTION_TYPE) \
V(ASM_WASM_DATA_TYPE) \
V(ASYNC_GENERATOR_REQUEST_TYPE) \
V(CLASS_POSITIONS_TYPE) \
V(DEBUG_INFO_TYPE) \
V(ENUM_CACHE_TYPE) \
V(FUNCTION_TEMPLATE_INFO_TYPE) \
V(FUNCTION_TEMPLATE_RARE_DATA_TYPE) \
V(INTERCEPTOR_INFO_TYPE) \
V(INTERPRETER_DATA_TYPE) \
V(OBJECT_TEMPLATE_INFO_TYPE) \
V(PROMISE_CAPABILITY_TYPE) \
V(PROMISE_REACTION_TYPE) \
V(PROTOTYPE_INFO_TYPE) \
V(SCRIPT_TYPE) \
V(SOURCE_POSITION_TABLE_WITH_FRAME_CACHE_TYPE) \
V(SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE) \
V(STACK_FRAME_INFO_TYPE) \
V(STACK_TRACE_FRAME_TYPE) \
V(TEMPLATE_OBJECT_DESCRIPTION_TYPE) \
V(TUPLE2_TYPE) \
V(TUPLE3_TYPE) \
V(WASM_CAPI_FUNCTION_DATA_TYPE) \
V(WASM_DEBUG_INFO_TYPE) \
V(WASM_EXCEPTION_TAG_TYPE) \
V(WASM_EXPORTED_FUNCTION_DATA_TYPE) \
V(WASM_INDIRECT_FUNCTION_TABLE_TYPE) \
V(WASM_JS_FUNCTION_DATA_TYPE) \
\
V(CALLABLE_TASK_TYPE) \
V(CALLBACK_TASK_TYPE) \
V(PROMISE_FULFILL_REACTION_JOB_TASK_TYPE) \
V(PROMISE_REJECT_REACTION_JOB_TASK_TYPE) \
V(PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE) \
\
TORQUE_DEFINED_INSTANCE_TYPES(V) \
\
V(SOURCE_TEXT_MODULE_TYPE) \
V(SYNTHETIC_MODULE_TYPE) \
\
V(ALLOCATION_SITE_TYPE) \
V(EMBEDDER_DATA_ARRAY_TYPE) \
\
V(FIXED_ARRAY_TYPE) \
V(OBJECT_BOILERPLATE_DESCRIPTION_TYPE) \
V(CLOSURE_FEEDBACK_CELL_ARRAY_TYPE) \
V(HASH_TABLE_TYPE) \
V(ORDERED_HASH_MAP_TYPE) \
V(ORDERED_HASH_SET_TYPE) \
V(ORDERED_NAME_DICTIONARY_TYPE) \
V(NAME_DICTIONARY_TYPE) \
V(GLOBAL_DICTIONARY_TYPE) \
V(NUMBER_DICTIONARY_TYPE) \
V(SIMPLE_NUMBER_DICTIONARY_TYPE) \
V(STRING_TABLE_TYPE) \
V(EPHEMERON_HASH_TABLE_TYPE) \
V(SCOPE_INFO_TYPE) \
V(SCRIPT_CONTEXT_TABLE_TYPE) \
\
V(AWAIT_CONTEXT_TYPE) \
V(BLOCK_CONTEXT_TYPE) \
V(CATCH_CONTEXT_TYPE) \
V(DEBUG_EVALUATE_CONTEXT_TYPE) \
V(EVAL_CONTEXT_TYPE) \
V(FUNCTION_CONTEXT_TYPE) \
V(MODULE_CONTEXT_TYPE) \
V(NATIVE_CONTEXT_TYPE) \
V(SCRIPT_CONTEXT_TYPE) \
V(WITH_CONTEXT_TYPE) \
\
V(WEAK_FIXED_ARRAY_TYPE) \
V(TRANSITION_ARRAY_TYPE) \
\
V(CALL_HANDLER_INFO_TYPE) \
V(CELL_TYPE) \
V(CODE_DATA_CONTAINER_TYPE) \
V(DESCRIPTOR_ARRAY_TYPE) \
V(FEEDBACK_CELL_TYPE) \
V(FEEDBACK_VECTOR_TYPE) \
V(LOAD_HANDLER_TYPE) \
V(PREPARSE_DATA_TYPE) \
V(PROPERTY_ARRAY_TYPE) \
V(PROPERTY_CELL_TYPE) \
V(SHARED_FUNCTION_INFO_TYPE) \
V(SMALL_ORDERED_HASH_MAP_TYPE) \
V(SMALL_ORDERED_HASH_SET_TYPE) \
V(SMALL_ORDERED_NAME_DICTIONARY_TYPE) \
V(STORE_HANDLER_TYPE) \
V(UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE) \
V(UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE) \
V(WEAK_ARRAY_LIST_TYPE) \
V(WEAK_CELL_TYPE) \
\
V(JS_PROXY_TYPE) \
V(JS_GLOBAL_OBJECT_TYPE) \
V(JS_GLOBAL_PROXY_TYPE) \
V(JS_MODULE_NAMESPACE_TYPE) \
V(JS_SPECIAL_API_OBJECT_TYPE) \
V(JS_PRIMITIVE_WRAPPER_TYPE) \
V(JS_API_OBJECT_TYPE) \
V(JS_OBJECT_TYPE) \
\
V(JS_ARGUMENTS_OBJECT_TYPE) \
V(JS_ARRAY_BUFFER_TYPE) \
V(JS_ARRAY_ITERATOR_TYPE) \
V(JS_ARRAY_TYPE) \
V(JS_ASYNC_FROM_SYNC_ITERATOR_TYPE) \
V(JS_ASYNC_FUNCTION_OBJECT_TYPE) \
V(JS_ASYNC_GENERATOR_OBJECT_TYPE) \
V(JS_CONTEXT_EXTENSION_OBJECT_TYPE) \
V(JS_DATE_TYPE) \
V(JS_ERROR_TYPE) \
V(JS_GENERATOR_OBJECT_TYPE) \
V(JS_MAP_TYPE) \
V(JS_MAP_KEY_ITERATOR_TYPE) \
V(JS_MAP_KEY_VALUE_ITERATOR_TYPE) \
V(JS_MAP_VALUE_ITERATOR_TYPE) \
V(JS_MESSAGE_OBJECT_TYPE) \
V(JS_PROMISE_TYPE) \
V(JS_REG_EXP_TYPE) \
V(JS_REG_EXP_STRING_ITERATOR_TYPE) \
V(JS_SET_TYPE) \
V(JS_SET_KEY_VALUE_ITERATOR_TYPE) \
V(JS_SET_VALUE_ITERATOR_TYPE) \
V(JS_STRING_ITERATOR_TYPE) \
V(JS_WEAK_REF_TYPE) \
V(JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE) \
V(JS_FINALIZATION_GROUP_TYPE) \
V(JS_WEAK_MAP_TYPE) \
V(JS_WEAK_SET_TYPE) \
V(JS_TYPED_ARRAY_TYPE) \
V(JS_DATA_VIEW_TYPE)
V(UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE)
#define INSTANCE_TYPE_LIST_AFTER_INTL(V) \
V(WASM_EXCEPTION_OBJECT_TYPE) \
V(WASM_GLOBAL_OBJECT_TYPE) \
V(WASM_INSTANCE_OBJECT_TYPE) \
V(WASM_MEMORY_OBJECT_TYPE) \
V(WASM_MODULE_OBJECT_TYPE) \
V(WASM_TABLE_OBJECT_TYPE) \
V(JS_BOUND_FUNCTION_TYPE) \
V(JS_FUNCTION_TYPE)
#ifdef V8_INTL_SUPPORT
#define INSTANCE_TYPE_LIST(V) \
INSTANCE_TYPE_LIST_BEFORE_INTL(V) \
V(JS_V8_BREAK_ITERATOR_TYPE) \
V(JS_COLLATOR_TYPE) \
V(JS_DATE_TIME_FORMAT_TYPE) \
V(JS_LIST_FORMAT_TYPE) \
V(JS_LOCALE_TYPE) \
V(JS_NUMBER_FORMAT_TYPE) \
V(JS_PLURAL_RULES_TYPE) \
V(JS_RELATIVE_TIME_FORMAT_TYPE) \
V(JS_SEGMENT_ITERATOR_TYPE) \
V(JS_SEGMENTER_TYPE) \
INSTANCE_TYPE_LIST_AFTER_INTL(V)
#else
#define INSTANCE_TYPE_LIST(V) \
INSTANCE_TYPE_LIST_BEFORE_INTL(V) \
INSTANCE_TYPE_LIST_AFTER_INTL(V)
#endif // V8_INTL_SUPPORT
#define INSTANCE_TYPE_LIST(V) \
INSTANCE_TYPE_LIST_BASE(V) \
TORQUE_ASSIGNED_INSTANCE_TYPE_LIST(V)
// Since string types are not consecutive, this macro is used to
// iterate over them.
@ -290,11 +102,20 @@ namespace internal {
// code for the class including allocation and garbage collection routines,
// casts and predicates. All you need to define is the class, methods and
// object verification routines. Easy, no?
//
// Note that for subtle reasons related to the ordering or numerical values of
// type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
// manually.
#define STRUCT_LIST_GENERATOR(V, _) \
#define STRUCT_LIST_GENERATOR_BASE(V, _) \
V(_, PROMISE_FULFILL_REACTION_JOB_TASK_TYPE, PromiseFulfillReactionJobTask, \
promise_fulfill_reaction_job_task) \
V(_, PROMISE_REJECT_REACTION_JOB_TASK_TYPE, PromiseRejectReactionJobTask, \
promise_reject_reaction_job_task) \
V(_, CALLABLE_TASK_TYPE, CallableTask, callable_task) \
V(_, CALLBACK_TASK_TYPE, CallbackTask, callback_task) \
V(_, PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE, PromiseResolveThenableJobTask, \
promise_resolve_thenable_job_task) \
V(_, FUNCTION_TEMPLATE_INFO_TYPE, FunctionTemplateInfo, \
function_template_info) \
V(_, OBJECT_TEMPLATE_INFO_TYPE, ObjectTemplateInfo, object_template_info) \
V(_, TUPLE2_TYPE, Tuple2, tuple2) \
V(_, TUPLE3_TYPE, Tuple3, tuple3) \
V(_, ACCESS_CHECK_INFO_TYPE, AccessCheckInfo, access_check_info) \
V(_, ACCESSOR_INFO_TYPE, AccessorInfo, accessor_info) \
V(_, ACCESSOR_PAIR_TYPE, AccessorPair, accessor_pair) \
@ -309,13 +130,10 @@ namespace internal {
V(_, CLASS_POSITIONS_TYPE, ClassPositions, class_positions) \
V(_, DEBUG_INFO_TYPE, DebugInfo, debug_info) \
V(_, ENUM_CACHE_TYPE, EnumCache, enum_cache) \
V(_, FUNCTION_TEMPLATE_INFO_TYPE, FunctionTemplateInfo, \
function_template_info) \
V(_, FUNCTION_TEMPLATE_RARE_DATA_TYPE, FunctionTemplateRareData, \
function_template_rare_data) \
V(_, INTERCEPTOR_INFO_TYPE, InterceptorInfo, interceptor_info) \
V(_, INTERPRETER_DATA_TYPE, InterpreterData, interpreter_data) \
V(_, OBJECT_TEMPLATE_INFO_TYPE, ObjectTemplateInfo, object_template_info) \
V(_, PROMISE_CAPABILITY_TYPE, PromiseCapability, promise_capability) \
V(_, PROMISE_REACTION_TYPE, PromiseReaction, promise_reaction) \
V(_, PROTOTYPE_INFO_TYPE, PrototypeInfo, prototype_info) \
@ -328,8 +146,6 @@ namespace internal {
V(_, STACK_TRACE_FRAME_TYPE, StackTraceFrame, stack_trace_frame) \
V(_, TEMPLATE_OBJECT_DESCRIPTION_TYPE, TemplateObjectDescription, \
template_object_description) \
V(_, TUPLE2_TYPE, Tuple2, tuple2) \
V(_, TUPLE3_TYPE, Tuple3, tuple3) \
V(_, WASM_CAPI_FUNCTION_DATA_TYPE, WasmCapiFunctionData, \
wasm_capi_function_data) \
V(_, WASM_DEBUG_INFO_TYPE, WasmDebugInfo, wasm_debug_info) \
@ -338,32 +154,24 @@ namespace internal {
wasm_exported_function_data) \
V(_, WASM_INDIRECT_FUNCTION_TABLE_TYPE, WasmIndirectFunctionTable, \
wasm_indirect_function_table) \
V(_, WASM_JS_FUNCTION_DATA_TYPE, WasmJSFunctionData, wasm_js_function_data) \
V(_, CALLABLE_TASK_TYPE, CallableTask, callable_task) \
V(_, CALLBACK_TASK_TYPE, CallbackTask, callback_task) \
V(_, PROMISE_FULFILL_REACTION_JOB_TASK_TYPE, PromiseFulfillReactionJobTask, \
promise_fulfill_reaction_job_task) \
V(_, PROMISE_REJECT_REACTION_JOB_TASK_TYPE, PromiseRejectReactionJobTask, \
promise_reject_reaction_job_task) \
V(_, PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE, PromiseResolveThenableJobTask, \
promise_resolve_thenable_job_task)
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, _)
// Adapts one STRUCT_LIST_GENERATOR entry to the STRUCT_LIST entry
#define STRUCT_LIST_ADAPTER(V, NAME, Name, name) V(NAME, Name, name)
// Produces (NAME, Name, name) entries.
#define STRUCT_LIST(V) \
STRUCT_LIST_GENERATOR(STRUCT_LIST_ADAPTER, V) \
TORQUE_STRUCT_LIST_GENERATOR(STRUCT_LIST_ADAPTER, V)
#define STRUCT_LIST(V) STRUCT_LIST_GENERATOR(STRUCT_LIST_ADAPTER, V)
// Adapts one STRUCT_LIST_GENERATOR entry to the STRUCT_MAPS_LIST entry
#define STRUCT_MAPS_LIST_ADAPTER(V, NAME, Name, name) \
V(Map, name##_map, Name##Map)
// Produces (Map, struct_name_map, StructNameMap) entries
#define STRUCT_MAPS_LIST(V) \
STRUCT_LIST_GENERATOR(STRUCT_MAPS_LIST_ADAPTER, V) \
TORQUE_STRUCT_LIST_GENERATOR(STRUCT_MAPS_LIST_ADAPTER, V)
#define STRUCT_MAPS_LIST(V) STRUCT_LIST_GENERATOR(STRUCT_MAPS_LIST_ADAPTER, V)
//
// The following macros define list of allocation size objects and list of

View File

@ -519,7 +519,7 @@ bool Object::IsMinusZero() const {
OBJECT_CONSTRUCTORS_IMPL(RegExpMatchInfo, FixedArray)
OBJECT_CONSTRUCTORS_IMPL(ScopeInfo, FixedArray)
OBJECT_CONSTRUCTORS_IMPL(BigIntBase, HeapObject)
OBJECT_CONSTRUCTORS_IMPL(BigIntBase, PrimitiveHeapObject)
OBJECT_CONSTRUCTORS_IMPL(BigInt, BigIntBase)
OBJECT_CONSTRUCTORS_IMPL(FreshlyAllocatedBigInt, BigIntBase)

View File

@ -46,19 +46,22 @@
// - JSArrayBufferView
// - JSTypedArray
// - JSDataView
// - JSBoundFunction
// - JSCollection
// - JSSet
// - JSMap
// - JSCustomElementsObject (may have elements despite empty FixedArray)
// - JSSpecialObject (requires custom property lookup handling)
// - JSGlobalObject
// - JSGlobalProxy
// - JSModuleNamespace
// - JSPrimitiveWrapper
// - JSDate
// - JSFunction
// - JSFunctionOrBoundFunction
// - JSBoundFunction
// - JSFunction
// - JSGeneratorObject
// - JSGlobalObject
// - JSGlobalProxy
// - JSMapIterator
// - JSMessageObject
// - JSModuleNamespace
// - JSPrimitiveWrapper
// - JSRegExp
// - JSSetIterator
// - JSStringIterator
@ -104,30 +107,32 @@
// - ScriptContextTable
// - ClosureFeedbackCellArray
// - FixedDoubleArray
// - Name
// - String
// - SeqString
// - SeqOneByteString
// - SeqTwoByteString
// - SlicedString
// - ConsString
// - ThinString
// - ExternalString
// - ExternalOneByteString
// - ExternalTwoByteString
// - InternalizedString
// - SeqInternalizedString
// - SeqOneByteInternalizedString
// - SeqTwoByteInternalizedString
// - ConsInternalizedString
// - ExternalInternalizedString
// - ExternalOneByteInternalizedString
// - ExternalTwoByteInternalizedString
// - Symbol
// - PrimitiveHeapObject
// - BigInt
// - HeapNumber
// - Name
// - String
// - SeqString
// - SeqOneByteString
// - SeqTwoByteString
// - SlicedString
// - ConsString
// - ThinString
// - ExternalString
// - ExternalOneByteString
// - ExternalTwoByteString
// - InternalizedString
// - SeqInternalizedString
// - SeqOneByteInternalizedString
// - SeqTwoByteInternalizedString
// - ConsInternalizedString
// - ExternalInternalizedString
// - ExternalOneByteInternalizedString
// - ExternalTwoByteInternalizedString
// - Symbol
// - Oddball
// - Context
// - NativeContext
// - HeapNumber
// - BigInt
// - Cell
// - DescriptorArray
// - PropertyCell
@ -135,7 +140,6 @@
// - Code
// - AbstractCode, a wrapper around Code or BytecodeArray
// - Map
// - Oddball
// - Foreign
// - SmallOrderedHashTable
// - SmallOrderedHashMap

View File

@ -5,8 +5,7 @@
#ifndef V8_OBJECTS_ODDBALL_H_
#define V8_OBJECTS_ODDBALL_H_
#include "src/objects/heap-object.h"
#include "torque-generated/class-definitions-tq.h"
#include "src/objects/primitive-heap-object.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@ -15,7 +14,7 @@ namespace v8 {
namespace internal {
// The Oddball describes objects null, undefined, true, and false.
class Oddball : public TorqueGeneratedOddball<Oddball, HeapObject> {
class Oddball : public TorqueGeneratedOddball<Oddball, PrimitiveHeapObject> {
public:
// [to_number_raw]: Cached raw to_number computed at startup.
inline void set_to_number_raw_as_bits(uint64_t bits);

View File

@ -0,0 +1,26 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_OBJECTS_PRIMITIVE_HEAP_OBJECT_INL_H_
#define V8_OBJECTS_PRIMITIVE_HEAP_OBJECT_INL_H_
#include "src/objects/primitive-heap-object.h"
#include "src/objects/heap-object-inl.h"
#include "torque-generated/class-definitions-tq-inl.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
TQ_OBJECT_CONSTRUCTORS_IMPL(PrimitiveHeapObject)
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_PRIMITIVE_HEAP_OBJECT_INL_H_

View File

@ -0,0 +1,33 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_OBJECTS_PRIMITIVE_HEAP_OBJECT_H_
#define V8_OBJECTS_PRIMITIVE_HEAP_OBJECT_H_
#include "src/objects/heap-object.h"
#include "torque-generated/class-definitions-tq.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
// An abstract superclass for classes representing JavaScript primitive values
// other than Smi. It doesn't carry any functionality but allows primitive
// classes to be identified in the type system.
class PrimitiveHeapObject
: public TorqueGeneratedPrimitiveHeapObject<PrimitiveHeapObject,
HeapObject> {
public:
STATIC_ASSERT(kHeaderSize == HeapObject::kHeaderSize);
TQ_OBJECT_CONSTRUCTORS(PrimitiveHeapObject)
};
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_PRIMITIVE_HEAP_OBJECT_H_

View File

@ -952,9 +952,10 @@ std::ostream& operator<<(std::ostream& os,
}
Handle<SourceTextModuleInfoEntry> SourceTextModuleInfoEntry::New(
Isolate* isolate, Handle<HeapObject> export_name,
Handle<HeapObject> local_name, Handle<HeapObject> import_name,
int module_request, int cell_index, int beg_pos, int end_pos) {
Isolate* isolate, Handle<PrimitiveHeapObject> export_name,
Handle<PrimitiveHeapObject> local_name,
Handle<PrimitiveHeapObject> import_name, int module_request, int cell_index,
int beg_pos, int end_pos) {
Handle<SourceTextModuleInfoEntry> result =
Handle<SourceTextModuleInfoEntry>::cast(isolate->factory()->NewStruct(
SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE, AllocationType::kOld));

View File

@ -251,9 +251,10 @@ class SourceTextModuleInfoEntry
DECL_INT_ACCESSORS(end_pos)
static Handle<SourceTextModuleInfoEntry> New(
Isolate* isolate, Handle<HeapObject> export_name,
Handle<HeapObject> local_name, Handle<HeapObject> import_name,
int module_request, int cell_index, int beg_pos, int end_pos);
Isolate* isolate, Handle<PrimitiveHeapObject> export_name,
Handle<PrimitiveHeapObject> local_name,
Handle<PrimitiveHeapObject> import_name, int module_request,
int cell_index, int beg_pos, int end_pos);
TQ_OBJECT_CONSTRUCTORS(SourceTextModuleInfoEntry)
};

View File

@ -16,12 +16,13 @@ namespace v8 {
namespace internal {
// An abstract superclass, a marker class really, for simple structure classes.
// It doesn't carry much functionality but allows struct classes to be
// It doesn't carry any functionality but allows struct classes to be
// identified in the type system.
class Struct : public TorqueGeneratedStruct<Struct, HeapObject> {
public:
inline void InitializeBody(int object_size);
void BriefPrintDetails(std::ostream& os);
STATIC_ASSERT(kHeaderSize == HeapObject::kHeaderSize);
TQ_OBJECT_CONSTRUCTORS(Struct)
};

View File

@ -90,7 +90,8 @@ namespace torque {
AST_STATEMENT_NODE_KIND_LIST(V) \
AST_DECLARATION_NODE_KIND_LIST(V) \
V(Identifier) \
V(LabelBlock)
V(LabelBlock) \
V(ClassBody)
struct AstNode {
public:
@ -792,6 +793,12 @@ struct TypeDeclaration : Declaration {
Identifier* name;
};
struct InstanceTypeConstraints {
InstanceTypeConstraints() : value(-1), num_flags_bits(-1) {}
int value;
int num_flags_bits;
};
struct AbstractTypeDeclaration : TypeDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(AbstractTypeDeclaration)
AbstractTypeDeclaration(SourcePosition pos, Identifier* name, bool transient,
@ -1069,24 +1076,38 @@ struct StructDeclaration : TypeDeclaration {
bool IsGeneric() const { return !generic_parameters.empty(); }
};
struct ClassBody : AstNode {
DEFINE_AST_NODE_LEAF_BOILERPLATE(ClassBody)
ClassBody(SourcePosition pos, std::vector<Declaration*> methods,
std::vector<ClassFieldExpression> fields)
: AstNode(kKind, pos),
methods(std::move(methods)),
fields(std::move(fields)) {}
std::vector<Declaration*> methods;
std::vector<ClassFieldExpression> fields;
};
struct ClassDeclaration : TypeDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(ClassDeclaration)
ClassDeclaration(SourcePosition pos, Identifier* name, ClassFlags flags,
base::Optional<TypeExpression*> super,
base::Optional<std::string> generates,
std::vector<Declaration*> methods,
std::vector<ClassFieldExpression> fields)
std::vector<ClassFieldExpression> fields,
InstanceTypeConstraints instance_type_constraints)
: TypeDeclaration(kKind, pos, name),
flags(flags),
super(super),
generates(std::move(generates)),
methods(std::move(methods)),
fields(std::move(fields)) {}
fields(std::move(fields)),
instance_type_constraints(std::move(instance_type_constraints)) {}
ClassFlags flags;
base::Optional<TypeExpression*> super;
base::Optional<std::string> generates;
std::vector<Declaration*> methods;
std::vector<ClassFieldExpression> fields;
InstanceTypeConstraints instance_type_constraints;
};
struct CppIncludeDeclaration : Declaration {

View File

@ -23,7 +23,7 @@ void GenerateClassDebugReader(const ClassType& type, std::ostream& h_contents,
std::ostream& cc_contents, std::ostream& visitor,
std::unordered_set<const ClassType*>* done) {
// Make sure each class only gets generated once.
if (!type.IsExtern() || !done->insert(&type).second) return;
if (!done->insert(&type).second) return;
const ClassType* super_type = type.GetSuperClass();
// We must emit the classes in dependency order. If the super class hasn't
@ -33,6 +33,10 @@ void GenerateClassDebugReader(const ClassType& type, std::ostream& h_contents,
done);
}
// Classes with undefined layout don't grant any particular value here and may
// not correspond with actual C++ classes, so skip them.
if (type.HasUndefinedLayout()) return;
const std::string name = type.name();
const std::string super_name =
super_type == nullptr ? "Object" : super_type->name();
@ -83,9 +87,10 @@ void GenerateClassDebugReader(const ClassType& type, std::ostream& h_contents,
if (is_field_tagged) {
field_value_type = "uintptr_t";
field_value_type_compressed = "i::Tagged_t";
field_cc_type = "v8::internal::" + (field_class_type.has_value()
? (*field_class_type)->name()
: "Object");
field_cc_type = "v8::internal::" +
(field_class_type.has_value()
? (*field_class_type)->GetGeneratedTNodeTypeName()
: "Object");
field_cc_type_compressed =
COMPRESS_POINTERS_BOOL ? "v8::internal::TaggedValue" : field_cc_type;
} else {
@ -204,6 +209,11 @@ void ImplementationVisitor::GenerateClassDebugReaders(
h_contents
<< "\n#include \"tools/debug_helper/debug-helper-internal.h\"\n\n";
h_contents << "// Unset a windgi.h macro that causes conflicts.\n";
h_contents << "#ifdef GetBValue\n";
h_contents << "#undef GetBValue\n";
h_contents << "#endif\n\n";
cc_contents << "#include \"torque-generated/" << file_name << ".h\"\n";
cc_contents << "#include \"include/v8-internal.h\"\n\n";
cc_contents << "namespace i = v8::internal;\n\n";

View File

@ -55,6 +55,25 @@ static const char* const REFERENCE_TYPE_STRING = "Reference";
static const char* const SLICE_TYPE_STRING = "Slice";
static const char* const STRUCT_NAMESPACE_STRING = "_struct";
static const char* const ANNOTATION_GENERATE_PRINT = "@generatePrint";
static const char* const ANNOTATION_NO_VERIFIER = "@noVerifier";
static const char* const ANNOTATION_ABSTRACT = "@abstract";
static const char* const ANNOTATION_INSTANTIATED_ABSTRACT_CLASS =
"@dirtyInstantiatedAbstractClass";
static const char* const ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT =
"@hasSameInstanceTypeAsParent";
static const char* const ANNOTATION_GENERATE_CPP_CLASS = "@generateCppClass";
static const char* const ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT =
"@highestInstanceTypeWithinParentClassRange";
static const char* const ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT =
"@lowestInstanceTypeWithinParentClassRange";
static const char* const ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE =
"@reserveBitsInInstanceType";
static const char* const ANNOTATION_INSTANCE_TYPE_VALUE =
"@apiExposedInstanceTypeValue";
static const char* const ANNOTATION_IF = "@if";
static const char* const ANNOTATION_IFNOT = "@ifnot";
inline bool IsConstexprName(const std::string& name) {
return name.substr(0, std::strlen(CONSTEXPR_TYPE_PREFIX)) ==
CONSTEXPR_TYPE_PREFIX;
@ -80,7 +99,10 @@ enum class ClassFlag {
kInstantiatedAbstractClass = 1 << 5,
kHasSameInstanceTypeAsParent = 1 << 6,
kGenerateCppClassDefinitions = 1 << 7,
kHasIndexedField = 1 << 8
kHasIndexedField = 1 << 8,
kHighestInstanceTypeWithinParent = 1 << 9,
kLowestInstanceTypeWithinParent = 1 << 10,
kUndefinedLayout = 1 << 11,
};
using ClassFlags = base::Flags<ClassFlag>;

View File

@ -83,6 +83,7 @@ enum class ParseResultHolderBase::TypeId {
kTypeswitchCase,
kStdVectorOfTypeswitchCase,
kStdVectorOfIdentifierPtr,
kOptionalClassBody,
kJsonValue,
kJsonMember,

View File

@ -2943,41 +2943,9 @@ class MacroFieldOffsetsGenerator : public FieldOffsetsGenerator {
private:
std::ostream& out_;
};
} // namespace
void ImplementationVisitor::GenerateInstanceTypes(
const std::string& output_directory) {
std::stringstream header;
std::string file_name = "instance-types-tq.h";
{
IncludeGuardScope(header, file_name);
header << "#define TORQUE_DEFINED_INSTANCE_TYPES(V) \\\n";
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
const ClassType* type = ClassType::DynamicCast(alias->type());
if (type->IsExtern()) continue;
std::string type_name =
CapifyStringWithUnderscores(type->name()) + "_TYPE";
header << " V(" << type_name << ") \\\n";
}
header << "\n\n";
header << "#define TORQUE_STRUCT_LIST_GENERATOR(V, _) \\\n";
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
const ClassType* type = ClassType::DynamicCast(alias->type());
if (type->IsExtern()) 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";
}
std::string output_header_path = output_directory + "/" + file_name;
WriteFile(output_header_path, header.str());
}
void ImplementationVisitor::GenerateCppForInternalClasses(
const std::string& output_directory) {
std::stringstream header;
@ -3197,7 +3165,7 @@ void CppClassGenerator::GenerateClassConstructors() {
if (type_->IsInstantiatedAbstractClass()) {
// This is a hack to prevent wrong instance type checks.
inl_ << " // Instance check omitted because class is annotated with "
"@dirtyInstantiatedAbstractClass.\n";
<< ANNOTATION_INSTANTIATED_ABSTRACT_CLASS << ".\n";
} else {
inl_ << " SLOW_DCHECK(this->Is" << name_ << "());\n";
}
@ -3290,7 +3258,8 @@ void CppClassGenerator::GenerateFieldAccessorForObject(const Field& f) {
const std::string offset = "k" + CamelifyString(name) + "Offset";
base::Optional<const ClassType*> class_type = field_type->ClassSupertype();
std::string type = class_type ? (*class_type)->name() : "Object";
std::string type =
class_type ? (*class_type)->GetGeneratedTNodeTypeName() : "Object";
// Generate declarations in header.
if (!class_type && field_type != TypeOracle::GetObjectType()) {
@ -3351,7 +3320,6 @@ void ImplementationVisitor::GenerateClassDefinitions(
{
IncludeGuardScope header_guard(header, basename + ".h");
header << "#include \"src/objects/heap-number.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";
@ -3398,7 +3366,7 @@ void ImplementationVisitor::GenerateClassDefinitions(
// Generate forward declarations for every class.
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
const ClassType* type = ClassType::DynamicCast(alias->type());
header << "class " << type->name() << ";\n";
header << "class " << type->GetGeneratedTNodeTypeName() << ";\n";
}
for (const TypeAlias* alias : GlobalContext::GetClasses()) {

View File

@ -0,0 +1,374 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/torque/implementation-visitor.h"
namespace v8 {
namespace internal {
namespace torque {
namespace {
// Contains all necessary state for a single class type during the process of
// assigning instance types, and provides a convenient way to access the list of
// types that inherit from this one.
struct InstanceTypeTree {
explicit InstanceTypeTree(const ClassType* type)
: type(type),
parent(nullptr),
start(INT_MAX),
end(INT_MIN),
value(-1),
num_values(0),
num_own_values(0) {}
const ClassType* type;
InstanceTypeTree* parent;
std::vector<std::unique_ptr<InstanceTypeTree>> children;
int start; // Start of range for this and subclasses, or INT_MAX.
int end; // End of range for this and subclasses, or INT_MIN.
int value; // Assigned value for this class itself, or -1 when unassigned.
int num_values; // Number of values assigned for this and subclasses.
int num_own_values; // How many values this needs (not including subclasses).
};
// Assembles all class types into a tree, but doesn't yet attempt to assign
// instance types for them.
std::unique_ptr<InstanceTypeTree> BuildInstanceTypeTree() {
// First, build InstanceTypeTree instances for every class but don't try to
// attach them to their subclasses yet.
std::unordered_map<const ClassType*, InstanceTypeTree*> map_by_type;
std::vector<std::unique_ptr<InstanceTypeTree>> unparented_types;
for (auto& p : GlobalContext::AllDeclarables()) {
if (const TypeAlias* alias = TypeAlias::DynamicCast(p.get())) {
const Type* type = alias->type();
const ClassType* class_type = ClassType::DynamicCast(type);
if (class_type == nullptr) {
continue;
}
auto& map_slot = map_by_type[class_type];
if (map_slot != nullptr) {
continue; // We already encountered this type.
}
std::unique_ptr<InstanceTypeTree> type_tree =
std::make_unique<InstanceTypeTree>(class_type);
map_slot = type_tree.get();
unparented_types.push_back(std::move(type_tree));
}
}
// Second, assemble them all into a tree following the inheritance hierarchy.
std::unique_ptr<InstanceTypeTree> root;
for (auto& type_tree : unparented_types) {
const ClassType* parent = type_tree->type->GetSuperClass();
if (parent == nullptr) {
if (root != nullptr)
Error("Expected only one root class type. Found: ", root->type->name(),
" and ", type_tree->type->name())
.Position(type_tree->type->GetPosition());
root = std::move(type_tree);
} else {
map_by_type[parent]->children.push_back(std::move(type_tree));
}
}
return root;
}
// Propagates constraints about instance types from children to their parents.
void PropagateInstanceTypeConstraints(InstanceTypeTree* root) {
for (auto& child : root->children) {
PropagateInstanceTypeConstraints(child.get());
if (child->start < root->start) root->start = child->start;
if (child->end > root->end) root->end = child->end;
root->num_values += child->num_values;
}
const InstanceTypeConstraints& constraints =
root->type->GetInstanceTypeConstraints();
if ((!root->type->IsAbstract() ||
root->type->IsInstantiatedAbstractClass()) &&
!root->type->HasSameInstanceTypeAsParent()) {
root->num_own_values = 1;
}
root->num_values += root->num_own_values;
if (constraints.num_flags_bits != -1) {
// Children won't get any types assigned; must be done manually in C++.
root->children.clear();
root->num_values = 1 << constraints.num_flags_bits;
root->num_own_values = root->num_values;
root->start = 0;
root->end = root->num_values - 1;
}
if (constraints.value != -1) {
if (root->num_own_values != 1) {
Error("Instance type value requested for abstract class ",
root->type->name())
.Position(root->type->GetPosition());
}
root->value = constraints.value;
if (constraints.value < root->start) root->start = constraints.value;
if (constraints.value > root->end) root->end = constraints.value;
}
}
// Assigns values for the type itself, not including any children. Returns the
// next available value.
int SelectOwnValues(InstanceTypeTree* root, int start_value) {
if (root->value == -1) {
root->value = start_value;
} else if (root->value < start_value) {
Error("Failed to assign instance type ", root->value, " to ",
root->type->name())
.Position(root->type->GetPosition());
}
return root->value + root->num_own_values;
}
// Sorting function for types that don't have specific values they must include.
// Prioritizes bigger type ranges (those with more subtypes) first, and
// then sorts alphabetically within each size category.
struct CompareUnconstrainedTypes {
constexpr bool operator()(const InstanceTypeTree* a,
const InstanceTypeTree* b) const {
return (a->num_values > b->num_values)
? true
: (a->num_values < b->num_values)
? false
: std::less<std::string>()(a->type->name(),
b->type->name());
}
};
// Assigns concrete values for every instance type range, and sorts the children
// at each layer of the tree into increasing order. Appends the newly-assigned
// tree to the destination vector. Returns the first unassigned value after
// those that have been used.
int SolveInstanceTypeConstraints(
std::unique_ptr<InstanceTypeTree> root, int start_value,
std::vector<std::unique_ptr<InstanceTypeTree>>* destination) {
if (root->start < start_value) {
Error("Failed to assign instance type ", root->start, " to ",
root->type->name())
.Position(root->type->GetPosition());
}
// First, separate the children into four groups:
// - The one child that must go first, if it exists;
// - Children with specific value requirements ("constrained");
// - Children without specific value requirements ("unconstrained");
// - The one child that must go last, if it exists.
std::unique_ptr<InstanceTypeTree> lowest_child;
std::unique_ptr<InstanceTypeTree> highest_child;
std::multimap<int, std::unique_ptr<InstanceTypeTree>>
constrained_children_by_start;
// Using std::map because you can't std::move out of a std::set until C++17.
std::map<InstanceTypeTree*, std::unique_ptr<InstanceTypeTree>,
CompareUnconstrainedTypes>
unconstrained_children_by_size;
for (auto& child : root->children) {
if (child->type->IsHighestInstanceTypeWithinParent()) {
if (highest_child) {
Error("Two classes requested to be the highest instance type: ",
highest_child->type->name(), " and ", child->type->name(),
" within range for parent class ", root->type->name())
.Position(child->type->GetPosition());
}
if (child->type->IsLowestInstanceTypeWithinParent()) {
Error(
"Class requested to be both highest and lowest instance type "
"within its parent range: ",
child->type->name())
.Position(child->type->GetPosition());
}
highest_child = std::move(child);
} else if (child->type->IsLowestInstanceTypeWithinParent()) {
if (lowest_child) {
Error("Two classes requested to be the lowest instance type: ",
lowest_child->type->name(), " and ", child->type->name(),
" within range for parent class ", root->type->name())
.Position(child->type->GetPosition());
}
lowest_child = std::move(child);
} else if (child->start > child->end) {
unconstrained_children_by_size.insert({child.get(), std::move(child)});
} else {
constrained_children_by_start.insert({child->start, std::move(child)});
}
}
root->children.clear();
bool own_type_pending = root->num_own_values > 0;
// Second, iterate and place the children in ascending order.
if (lowest_child != nullptr) {
start_value = SolveInstanceTypeConstraints(std::move(lowest_child),
start_value, &root->children);
}
for (auto& constrained_child_pair : constrained_children_by_start) {
// Select the next constrained child type in ascending order.
std::unique_ptr<InstanceTypeTree> constrained_child =
std::move(constrained_child_pair.second);
// Try to place the root type before the constrained child type if it fits.
if (own_type_pending) {
if ((root->value != -1 && root->value < constrained_child->start) ||
(root->value == -1 &&
start_value + root->num_own_values <= constrained_child->start)) {
start_value = SelectOwnValues(root.get(), start_value);
own_type_pending = false;
}
}
// Try to find any unconstrained children that fit before the constrained
// one. This simple greedy algorithm just puts the biggest unconstrained
// children in first, which might not fill the space as efficiently as
// possible but is good enough for our needs.
for (auto it = unconstrained_children_by_size.begin();
it != unconstrained_children_by_size.end();) {
if (it->second->num_values + start_value <= constrained_child->start) {
start_value = SolveInstanceTypeConstraints(
std::move(it->second), start_value, &root->children);
it = unconstrained_children_by_size.erase(it);
} else {
++it;
}
}
// Place the constrained child type.
start_value = SolveInstanceTypeConstraints(std::move(constrained_child),
start_value, &root->children);
}
if (own_type_pending) {
start_value = SelectOwnValues(root.get(), start_value);
own_type_pending = false;
}
for (auto& child_pair : unconstrained_children_by_size) {
start_value = SolveInstanceTypeConstraints(std::move(child_pair.second),
start_value, &root->children);
}
if (highest_child != nullptr) {
start_value = SolveInstanceTypeConstraints(std::move(highest_child),
start_value, &root->children);
}
// Finally, set the range for this class to include all placed subclasses.
root->end = start_value - 1;
root->start =
root->children.empty() ? start_value : root->children.front()->start;
if (root->value != -1 && root->value < root->start) {
root->start = root->value;
}
root->num_values = root->end - root->start + 1;
if (root->num_values > 0) {
destination->push_back(std::move(root));
}
return start_value;
}
std::unique_ptr<InstanceTypeTree> SolveInstanceTypeConstraints(
std::unique_ptr<InstanceTypeTree> root) {
std::vector<std::unique_ptr<InstanceTypeTree>> destination;
SolveInstanceTypeConstraints(std::move(root), 0, &destination);
return destination.empty() ? nullptr : std::move(destination.front());
}
std::unique_ptr<InstanceTypeTree> AssignInstanceTypes() {
std::unique_ptr<InstanceTypeTree> root = BuildInstanceTypeTree();
if (root != nullptr) {
PropagateInstanceTypeConstraints(root.get());
root = SolveInstanceTypeConstraints(std::move(root));
}
return root;
}
// Prints items in macro lists for the given type and its descendants.
// - definitions: This list is pairs of instance type name and assigned value,
// such as V(ODDBALL_TYPE, 67). It includes FIRST_* and LAST_* items for each
// type that has more than one associated InstanceType. Items within those
// ranges are indented for readability.
// - values: This list is just instance type names, like V(ODDBALL_TYPE). It
// does not include any FIRST_* and LAST_* range markers.
void PrintInstanceTypes(InstanceTypeTree* root, std::ostream& definitions,
std::ostream& values, const std::string& indent) {
std::string type_name =
CapifyStringWithUnderscores(root->type->name()) + "_TYPE";
std::string inner_indent = indent;
if (root->num_values > 1) {
definitions << indent << "V(FIRST_" << type_name << ", " << root->start
<< ") \\\n";
inner_indent += " ";
}
if (root->num_own_values == 1) {
definitions << inner_indent << "V(" << type_name << ", " << root->value
<< ") \\\n";
values << " V(" << type_name << ") \\\n";
}
for (auto& child : root->children) {
PrintInstanceTypes(child.get(), definitions, values, inner_indent);
}
// We can't emit LAST_STRING_TYPE because it's not a valid flags combination.
// So if the class type has multiple own values, which only happens when using
// ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE, then omit the end marker.
if (root->num_values > 1 && root->num_own_values <= 1) {
definitions << indent << "V(LAST_" << type_name << ", " << root->end
<< ") \\\n";
}
}
} // namespace
void ImplementationVisitor::GenerateInstanceTypes(
const std::string& output_directory) {
std::stringstream header;
std::string file_name = "instance-types-tq.h";
{
IncludeGuardScope guard(header, file_name);
header << "// Instance types for all classes except for those that use "
"InstanceType as flags.\n";
header << "#define TORQUE_ASSIGNED_INSTANCE_TYPES(V) \\\n";
std::unique_ptr<InstanceTypeTree> instance_types = AssignInstanceTypes();
std::stringstream values_list;
if (instance_types != nullptr) {
PrintInstanceTypes(instance_types.get(), header, values_list, " ");
}
header << "\n\n";
header << "// Instance types for all classes except for those that use "
"InstanceType as flags.\n";
header << "#define TORQUE_ASSIGNED_INSTANCE_TYPE_LIST(V) \\\n";
header << values_list.str();
header << "\n\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());
if (type->IsExtern()) continue;
std::string type_name =
CapifyStringWithUnderscores(type->name()) + "_TYPE";
header << " V(" << type_name << ") \\\n";
}
header << "\n\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());
if (type->IsExtern()) 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";
}
std::string output_header_path = output_directory + "/" + file_name;
WriteFile(output_header_path, header.str());
}
} // namespace torque
} // namespace internal
} // namespace v8

View File

@ -214,6 +214,10 @@ template <>
V8_EXPORT_PRIVATE const ParseResultTypeId
ParseResultHolder<std::vector<Identifier*>>::id =
ParseResultTypeId::kStdVectorOfIdentifierPtr;
template <>
V8_EXPORT_PRIVATE const ParseResultTypeId
ParseResultHolder<base::Optional<ClassBody*>>::id =
ParseResultTypeId::kOptionalClassBody;
namespace {
@ -675,7 +679,9 @@ class AnnotationSet {
Lint("Annotation ", a.name->value, error_message)
.Position(a.name->pos);
}
map_[a.name->value].push_back(*a.param);
if (!map_.insert({a.name->value, {*a.param, a.name->pos}}).second) {
Lint("Duplicate annotation ", a.name->value).Position(a.name->pos);
}
} else {
if (allowed_without_param.find(a.name->value) ==
allowed_without_param.end()) {
@ -693,41 +699,104 @@ class AnnotationSet {
}
}
bool Contains(const std::string& s) { return set_.find(s) != set_.end(); }
const std::vector<std::string>& GetParams(const std::string& s) {
return map_[s];
bool Contains(const std::string& s) const {
return set_.find(s) != set_.end();
}
base::Optional<std::pair<std::string, SourcePosition>> GetParam(
const std::string& s) const {
auto it = map_.find(s);
return it == map_.end()
? base::Optional<std::pair<std::string, SourcePosition>>()
: it->second;
}
private:
std::set<std::string> set_;
std::map<std::string, std::vector<std::string>> map_;
std::map<std::string, std::pair<std::string, SourcePosition>> map_;
};
int GetAnnotationValue(const AnnotationSet& annotations, const char* name,
int default_value) {
auto value_and_pos = annotations.GetParam(name);
if (!value_and_pos.has_value()) return default_value;
const std::string& value = value_and_pos->first;
SourcePosition pos = value_and_pos->second;
if (value.empty()) {
Error("Annotation ", name, " requires an integer parameter").Position(pos);
}
size_t num_chars_converted = 0;
int result = default_value;
try {
result = std::stoi(value, &num_chars_converted, 0);
} catch (const std::invalid_argument&) {
Error("Expected an integer for annotation ", name).Position(pos);
return result;
} catch (const std::out_of_range&) {
Error("Integer out of 32-bit range in annotation ", name).Position(pos);
return result;
}
if (num_chars_converted != value.size()) {
Error("Parameter for annotation ", name,
" must be an integer with no trailing characters")
.Position(pos);
}
return result;
}
InstanceTypeConstraints MakeInstanceTypeConstraints(
const AnnotationSet& annotations) {
InstanceTypeConstraints result;
result.value =
GetAnnotationValue(annotations, ANNOTATION_INSTANCE_TYPE_VALUE, -1);
result.num_flags_bits = GetAnnotationValue(
annotations, ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE, -1);
return result;
}
base::Optional<ParseResult> MakeClassBody(ParseResultIterator* child_results) {
auto methods = child_results->NextAs<std::vector<Declaration*>>();
auto fields = child_results->NextAs<std::vector<ClassFieldExpression>>();
base::Optional<ClassBody*> result =
MakeNode<ClassBody>(std::move(methods), std::move(fields));
return ParseResult(result);
}
base::Optional<ParseResult> MakeClassDeclaration(
ParseResultIterator* child_results) {
AnnotationSet annotations(
child_results,
{"@generatePrint", "@noVerifier", "@abstract",
"@dirtyInstantiatedAbstractClass", "@hasSameInstanceTypeAsParent",
"@generateCppClass"},
{});
{ANNOTATION_GENERATE_PRINT, ANNOTATION_NO_VERIFIER, ANNOTATION_ABSTRACT,
ANNOTATION_INSTANTIATED_ABSTRACT_CLASS,
ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT,
ANNOTATION_GENERATE_CPP_CLASS,
ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT,
ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT},
{ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE,
ANNOTATION_INSTANCE_TYPE_VALUE});
ClassFlags flags = ClassFlag::kNone;
bool generate_print = annotations.Contains("@generatePrint");
bool generate_print = annotations.Contains(ANNOTATION_GENERATE_PRINT);
if (generate_print) flags |= ClassFlag::kGeneratePrint;
bool generate_verify = !annotations.Contains("@noVerifier");
bool generate_verify = !annotations.Contains(ANNOTATION_NO_VERIFIER);
if (generate_verify) flags |= ClassFlag::kGenerateVerify;
if (annotations.Contains("@abstract")) {
if (annotations.Contains(ANNOTATION_ABSTRACT)) {
flags |= ClassFlag::kAbstract;
}
if (annotations.Contains("@dirtyInstantiatedAbstractClass")) {
if (annotations.Contains(ANNOTATION_INSTANTIATED_ABSTRACT_CLASS)) {
flags |= ClassFlag::kInstantiatedAbstractClass;
}
if (annotations.Contains("@hasSameInstanceTypeAsParent")) {
if (annotations.Contains(ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT)) {
flags |= ClassFlag::kHasSameInstanceTypeAsParent;
}
if (annotations.Contains("@generateCppClass")) {
if (annotations.Contains(ANNOTATION_GENERATE_CPP_CLASS)) {
flags |= ClassFlag::kGenerateCppClassDefinitions;
}
if (annotations.Contains(ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT)) {
flags |= ClassFlag::kHighestInstanceTypeWithinParent;
}
if (annotations.Contains(ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT)) {
flags |= ClassFlag::kLowestInstanceTypeWithinParent;
}
auto is_extern = child_results->NextAs<bool>();
if (is_extern) flags |= ClassFlag::kExtern;
auto transient = child_results->NextAs<bool>();
@ -741,8 +810,15 @@ base::Optional<ParseResult> MakeClassDeclaration(
ReportError("Expected type name in extends clause.");
}
auto generates = child_results->NextAs<base::Optional<std::string>>();
auto methods = child_results->NextAs<std::vector<Declaration*>>();
auto fields_raw = child_results->NextAs<std::vector<ClassFieldExpression>>();
auto body = child_results->NextAs<base::Optional<ClassBody*>>();
std::vector<Declaration*> methods;
std::vector<ClassFieldExpression> fields_raw;
if (body.has_value()) {
methods = (*body)->methods;
fields_raw = (*body)->fields;
} else {
flags |= ClassFlag::kUndefinedLayout;
}
// Filter to only include fields that should be present based on decoration.
std::vector<ClassFieldExpression> fields;
@ -751,8 +827,9 @@ base::Optional<ParseResult> MakeClassDeclaration(
[](const ClassFieldExpression& exp) {
for (const ConditionalAnnotation& condition : exp.conditions) {
if (condition.type == ConditionalAnnotationType::kPositive
? !BuildFlags::GetFlag(condition.condition, "@if")
: BuildFlags::GetFlag(condition.condition, "@ifnot")) {
? !BuildFlags::GetFlag(condition.condition, ANNOTATION_IF)
: BuildFlags::GetFlag(condition.condition,
ANNOTATION_IFNOT)) {
return false;
}
}
@ -761,7 +838,7 @@ base::Optional<ParseResult> MakeClassDeclaration(
Declaration* result = MakeNode<ClassDeclaration>(
name, flags, std::move(extends), std::move(generates), std::move(methods),
fields);
fields, MakeInstanceTypeConstraints(annotations));
return ParseResult{result};
}
@ -1358,14 +1435,21 @@ base::Optional<ParseResult> MakeAnnotation(ParseResultIterator* child_results) {
}
base::Optional<ParseResult> MakeClassField(ParseResultIterator* child_results) {
AnnotationSet annotations(child_results, {"@noVerifier"}, {"@if", "@ifnot"});
bool generate_verify = !annotations.Contains("@noVerifier");
AnnotationSet annotations(child_results, {ANNOTATION_NO_VERIFIER},
{ANNOTATION_IF, ANNOTATION_IFNOT});
bool generate_verify = !annotations.Contains(ANNOTATION_NO_VERIFIER);
std::vector<ConditionalAnnotation> conditions;
for (const std::string& condition : annotations.GetParams("@if")) {
conditions.push_back({condition, ConditionalAnnotationType::kPositive});
base::Optional<std::pair<std::string, SourcePosition>> if_condition =
annotations.GetParam(ANNOTATION_IF);
base::Optional<std::pair<std::string, SourcePosition>> ifnot_condition =
annotations.GetParam(ANNOTATION_IFNOT);
if (if_condition.has_value()) {
conditions.push_back(
{if_condition->first, ConditionalAnnotationType::kPositive});
}
for (const std::string& condition : annotations.GetParams("@ifnot")) {
conditions.push_back({condition, ConditionalAnnotationType::kNegative});
if (ifnot_condition.has_value()) {
conditions.push_back(
{ifnot_condition->first, ConditionalAnnotationType::kNegative});
}
auto weak = child_results->NextAs<bool>();
auto const_qualified = child_results->NextAs<bool>();
@ -1892,6 +1976,13 @@ struct TorqueGrammar : Grammar {
&block},
MakeMethodDeclaration)};
// Result: base::Optional<ClassBody*>
Symbol optionalClassBody = {
Rule({Token("{"), List<Declaration*>(&method),
List<ClassFieldExpression>(&classField), Token("}")},
MakeClassBody),
Rule({Token(";")}, YieldDefaultValue<base::Optional<ClassBody*>>)};
// Result: std::vector<Declaration*>
Symbol declaration = {
Rule({Token("const"), &name, Token(":"), &type, Token("="), expression,
@ -1905,8 +1996,7 @@ struct TorqueGrammar : Grammar {
Optional<TypeExpression*>(Sequence({Token("extends"), &type})),
Optional<std::string>(
Sequence({Token("generates"), &externalString})),
Token("{"), List<Declaration*>(&method),
List<ClassFieldExpression>(&classField), Token("}")},
&optionalClassBody},
AsSingletonVector<Declaration*, MakeClassDeclaration>()),
Rule({Token("struct"), &name,
TryOrDefault<GenericParameters>(&genericParameters), Token("{"),

View File

@ -165,6 +165,12 @@ const ClassType* TypeVisitor::ComputeType(ClassDeclaration* decl) {
"class \"", decl->name->value,
"\" must extend either Tagged 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);
}
}
std::string generates = decl->name->value;

View File

@ -50,7 +50,9 @@ bool Type::IsSubtypeOf(const Type* supertype) const {
base::Optional<const ClassType*> Type::ClassSupertype() const {
for (const Type* t = this; t != nullptr; t = t->parent()) {
if (auto* class_type = ClassType::DynamicCast(t)) return class_type;
if (auto* class_type = ClassType::DynamicCast(t)) {
return class_type;
}
}
return base::nullopt;
}
@ -404,11 +406,11 @@ void ClassType::Finalize() const {
if (const ClassType* super_class = ClassType::DynamicCast(parent())) {
if (super_class->HasIndexedField()) flags_ |= ClassFlag::kHasIndexedField;
if (!super_class->IsAbstract() && !HasSameInstanceTypeAsParent()) {
Error(
"Super class must either be abstract (annotate super class with "
"@abstract) "
"or this class must have the same instance type as the super class "
"(annotate this class with @hasSameInstanceTypeAsParent).")
Error("Super class must either be abstract (annotate super class with ",
ANNOTATION_ABSTRACT,
") or this class must have the same instance type as the super "
"class (annotate this class with ",
ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT, ").")
.Position(this->decl_->name->pos);
}
}

View File

@ -513,10 +513,12 @@ 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();
return (flags_ & ClassFlag::kGeneratePrint || !IsExtern()) &&
!HasUndefinedLayout();
}
bool ShouldGenerateVerify() const {
return flags_ & ClassFlag::kGenerateVerify || !IsExtern();
return (flags_ & ClassFlag::kGenerateVerify || !IsExtern()) &&
!HasUndefinedLayout();
}
bool IsTransient() const override { return flags_ & ClassFlag::kTransient; }
bool IsAbstract() const { return flags_ & ClassFlag::kAbstract; }
@ -548,6 +550,20 @@ class ClassType final : public AggregateType {
std::vector<Field> ComputeAllFields() const;
const InstanceTypeConstraints& GetInstanceTypeConstraints() const {
return decl_->instance_type_constraints;
}
bool IsHighestInstanceTypeWithinParent() const {
return flags_ & ClassFlag::kHighestInstanceTypeWithinParent;
}
bool IsLowestInstanceTypeWithinParent() const {
return flags_ & ClassFlag::kLowestInstanceTypeWithinParent;
}
bool HasUndefinedLayout() const {
return flags_ & ClassFlag::kUndefinedLayout;
}
SourcePosition GetPosition() const { return decl_->pos; }
private:
friend class TypeOracle;
friend class TypeVisitor;

View File

@ -72,25 +72,34 @@ TEST(Object, InstanceTypeListOrder) {
<< " vs. current = " << current_type; \
last = current;
INSTANCE_TYPE_LIST(TEST_INSTANCE_TYPE)
// Only test hand-written portion of instance type list. The generated portion
// doesn't run the same risk of getting out of order, and it does emit type
// names out of numerical order in one case: JS_OBJECT_TYPE is emitted before
// its subclass types, because types are emitted in depth-first pre-order
// traversal order, and some of its subclass types are numerically earlier.
INSTANCE_TYPE_LIST_BASE(TEST_INSTANCE_TYPE)
#undef TEST_INSTANCE_TYPE
}
TEST(Object, StructListOrder) {
int current = static_cast<int>(InstanceType::ACCESS_CHECK_INFO_TYPE);
int current = static_cast<int>(InstanceType::FIRST_STRUCT_TYPE);
int last = current - 1;
ASSERT_LT(0, last);
InstanceType current_type = static_cast<InstanceType>(current);
#define TEST_STRUCT(TYPE, class, name) \
current_type = InstanceType::TYPE; \
current = static_cast<int>(current_type); \
EXPECT_EQ(last + 1, current) \
EXPECT_LE(last + 1, current) \
<< " STRUCT_LIST is not ordered: " \
<< " last = " << static_cast<InstanceType>(last) \
<< " vs. current = " << current_type; \
last = current;
STRUCT_LIST(TEST_STRUCT)
// Only test the _BASE portion (the hand-coded part). Note that the values are
// not necessarily consecutive because some Structs that need special
// handling, such as those that have multiple Map instances associated, are
// omitted from this list.
STRUCT_LIST_GENERATOR_BASE(STRUCT_LIST_ADAPTER, TEST_STRUCT)
#undef TEST_STRUCT
}

View File

@ -386,8 +386,10 @@ def load_objects():
def load_objects_from_file(objfilename, checktypes):
objfile = open(objfilename, 'r');
in_insttype = False;
in_torque_insttype = False
typestr = '';
torque_typestr = ''
uncommented_file = ''
#
@ -401,16 +403,28 @@ def load_objects_from_file(objfilename, checktypes):
in_insttype = True;
continue;
if (line.startswith('#define TORQUE_ASSIGNED_INSTANCE_TYPE_LIST')):
in_torque_insttype = True
continue
if (in_insttype and line.startswith('};')):
in_insttype = False;
continue;
if (in_torque_insttype and (not line or line.isspace())):
in_torque_insttype = False
continue
line = re.sub('//.*', '', line.strip());
if (in_insttype):
typestr += line;
continue;
if (in_torque_insttype):
torque_typestr += line
continue
uncommented_file += '\n' + line
for match in re.finditer(r'\nclass(?:\s+V8_EXPORT(?:_PRIVATE)?)?'
@ -438,6 +452,9 @@ def load_objects_from_file(objfilename, checktypes):
entries = typestr.split(',');
for entry in entries:
types[re.sub('\s*=.*', '', entry).lstrip()] = True;
entries = torque_typestr.split('\\')
for entry in entries:
types[re.sub(r' *V\(|\) *', '', entry)] = True
#
# Infer class names for each type based on a systematic transformation.

View File

@ -33,7 +33,7 @@ def preprocess(input):
break;
input = re.sub(r'\bgenerates\s+\'([^\']+)\'\s*',
r' _GeNeRaTeS00_/*\1@*/', input)
r'_GeNeRaTeS00_/*\1@*/', input)
input = re.sub(r'\bconstexpr\s+\'([^\']+)\'\s*',
r' _CoNsExP_/*\1@*/', input)
input = re.sub(r'\notherwise',

View File

@ -26,249 +26,249 @@ INSTANCE_TYPES = {
50: "UNCACHED_EXTERNAL_STRING_TYPE",
58: "UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE",
64: "SYMBOL_TYPE",
65: "HEAP_NUMBER_TYPE",
66: "BIGINT_TYPE",
65: "BIG_INT_BASE_TYPE",
66: "HEAP_NUMBER_TYPE",
67: "ODDBALL_TYPE",
68: "MAP_TYPE",
69: "CODE_TYPE",
68: "SOURCE_TEXT_MODULE_TYPE",
69: "SYNTHETIC_MODULE_TYPE",
70: "FOREIGN_TYPE",
71: "BYTE_ARRAY_TYPE",
72: "BYTECODE_ARRAY_TYPE",
73: "FREE_SPACE_TYPE",
74: "FIXED_DOUBLE_ARRAY_TYPE",
75: "FEEDBACK_METADATA_TYPE",
76: "FILLER_TYPE",
77: "ACCESS_CHECK_INFO_TYPE",
78: "ACCESSOR_INFO_TYPE",
79: "ACCESSOR_PAIR_TYPE",
80: "ALIASED_ARGUMENTS_ENTRY_TYPE",
81: "ALLOCATION_MEMENTO_TYPE",
82: "ARRAY_BOILERPLATE_DESCRIPTION_TYPE",
83: "ASM_WASM_DATA_TYPE",
84: "ASYNC_GENERATOR_REQUEST_TYPE",
85: "CLASS_POSITIONS_TYPE",
86: "DEBUG_INFO_TYPE",
87: "ENUM_CACHE_TYPE",
88: "FUNCTION_TEMPLATE_INFO_TYPE",
89: "FUNCTION_TEMPLATE_RARE_DATA_TYPE",
90: "INTERCEPTOR_INFO_TYPE",
91: "INTERPRETER_DATA_TYPE",
92: "OBJECT_TEMPLATE_INFO_TYPE",
93: "PROMISE_CAPABILITY_TYPE",
94: "PROMISE_REACTION_TYPE",
95: "PROTOTYPE_INFO_TYPE",
96: "SCRIPT_TYPE",
97: "SOURCE_POSITION_TABLE_WITH_FRAME_CACHE_TYPE",
98: "SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE",
99: "STACK_FRAME_INFO_TYPE",
100: "STACK_TRACE_FRAME_TYPE",
101: "TEMPLATE_OBJECT_DESCRIPTION_TYPE",
102: "TUPLE2_TYPE",
103: "TUPLE3_TYPE",
104: "WASM_CAPI_FUNCTION_DATA_TYPE",
105: "WASM_DEBUG_INFO_TYPE",
106: "WASM_EXCEPTION_TAG_TYPE",
107: "WASM_EXPORTED_FUNCTION_DATA_TYPE",
108: "WASM_INDIRECT_FUNCTION_TABLE_TYPE",
109: "WASM_JS_FUNCTION_DATA_TYPE",
110: "CALLABLE_TASK_TYPE",
111: "CALLBACK_TASK_TYPE",
112: "PROMISE_FULFILL_REACTION_JOB_TASK_TYPE",
113: "PROMISE_REJECT_REACTION_JOB_TASK_TYPE",
114: "PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE",
115: "INTERNAL_CLASS_TYPE",
116: "SMI_PAIR_TYPE",
117: "SMI_BOX_TYPE",
118: "SORT_STATE_TYPE",
119: "SOURCE_TEXT_MODULE_TYPE",
120: "SYNTHETIC_MODULE_TYPE",
121: "ALLOCATION_SITE_TYPE",
122: "EMBEDDER_DATA_ARRAY_TYPE",
123: "FIXED_ARRAY_TYPE",
124: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE",
125: "CLOSURE_FEEDBACK_CELL_ARRAY_TYPE",
126: "HASH_TABLE_TYPE",
127: "ORDERED_HASH_MAP_TYPE",
128: "ORDERED_HASH_SET_TYPE",
129: "ORDERED_NAME_DICTIONARY_TYPE",
130: "NAME_DICTIONARY_TYPE",
131: "GLOBAL_DICTIONARY_TYPE",
132: "NUMBER_DICTIONARY_TYPE",
133: "SIMPLE_NUMBER_DICTIONARY_TYPE",
134: "STRING_TABLE_TYPE",
135: "EPHEMERON_HASH_TABLE_TYPE",
136: "SCOPE_INFO_TYPE",
137: "SCRIPT_CONTEXT_TABLE_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: "WEAK_FIXED_ARRAY_TYPE",
149: "TRANSITION_ARRAY_TYPE",
150: "CALL_HANDLER_INFO_TYPE",
151: "CELL_TYPE",
152: "CODE_DATA_CONTAINER_TYPE",
153: "DESCRIPTOR_ARRAY_TYPE",
154: "FEEDBACK_CELL_TYPE",
155: "FEEDBACK_VECTOR_TYPE",
156: "LOAD_HANDLER_TYPE",
157: "PREPARSE_DATA_TYPE",
158: "PROPERTY_ARRAY_TYPE",
159: "PROPERTY_CELL_TYPE",
160: "SHARED_FUNCTION_INFO_TYPE",
161: "SMALL_ORDERED_HASH_MAP_TYPE",
162: "SMALL_ORDERED_HASH_SET_TYPE",
163: "SMALL_ORDERED_NAME_DICTIONARY_TYPE",
164: "STORE_HANDLER_TYPE",
165: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE",
166: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE",
71: "PROMISE_FULFILL_REACTION_JOB_TASK_TYPE",
72: "PROMISE_REJECT_REACTION_JOB_TASK_TYPE",
73: "CALLABLE_TASK_TYPE",
74: "CALLBACK_TASK_TYPE",
75: "PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE",
76: "LOAD_HANDLER_TYPE",
77: "STORE_HANDLER_TYPE",
78: "FUNCTION_TEMPLATE_INFO_TYPE",
79: "OBJECT_TEMPLATE_INFO_TYPE",
80: "TUPLE2_TYPE",
81: "TUPLE3_TYPE",
82: "ACCESS_CHECK_INFO_TYPE",
83: "ACCESSOR_INFO_TYPE",
84: "ACCESSOR_PAIR_TYPE",
85: "ALIASED_ARGUMENTS_ENTRY_TYPE",
86: "ALLOCATION_MEMENTO_TYPE",
87: "ALLOCATION_SITE_TYPE",
88: "ARRAY_BOILERPLATE_DESCRIPTION_TYPE",
89: "ASM_WASM_DATA_TYPE",
90: "ASYNC_GENERATOR_REQUEST_TYPE",
91: "CALL_HANDLER_INFO_TYPE",
92: "CLASS_POSITIONS_TYPE",
93: "DEBUG_INFO_TYPE",
94: "ENUM_CACHE_TYPE",
95: "FEEDBACK_CELL_TYPE",
96: "FUNCTION_TEMPLATE_RARE_DATA_TYPE",
97: "INTERCEPTOR_INFO_TYPE",
98: "INTERNAL_CLASS_TYPE",
99: "INTERPRETER_DATA_TYPE",
100: "PROMISE_CAPABILITY_TYPE",
101: "PROMISE_REACTION_TYPE",
102: "PROTOTYPE_INFO_TYPE",
103: "SCRIPT_TYPE",
104: "SMI_BOX_TYPE",
105: "SMI_PAIR_TYPE",
106: "SORT_STATE_TYPE",
107: "SOURCE_POSITION_TABLE_WITH_FRAME_CACHE_TYPE",
108: "SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE",
109: "STACK_FRAME_INFO_TYPE",
110: "STACK_TRACE_FRAME_TYPE",
111: "TEMPLATE_OBJECT_DESCRIPTION_TYPE",
112: "WASM_CAPI_FUNCTION_DATA_TYPE",
113: "WASM_DEBUG_INFO_TYPE",
114: "WASM_EXCEPTION_TAG_TYPE",
115: "WASM_EXPORTED_FUNCTION_DATA_TYPE",
116: "WASM_INDIRECT_FUNCTION_TABLE_TYPE",
117: "WASM_JS_FUNCTION_DATA_TYPE",
118: "FIXED_ARRAY_TYPE",
119: "HASH_TABLE_TYPE",
120: "EPHEMERON_HASH_TABLE_TYPE",
121: "GLOBAL_DICTIONARY_TYPE",
122: "NAME_DICTIONARY_TYPE",
123: "NUMBER_DICTIONARY_TYPE",
124: "ORDERED_HASH_MAP_TYPE",
125: "ORDERED_HASH_SET_TYPE",
126: "ORDERED_NAME_DICTIONARY_TYPE",
127: "SIMPLE_NUMBER_DICTIONARY_TYPE",
128: "STRING_TABLE_TYPE",
129: "CLOSURE_FEEDBACK_CELL_ARRAY_TYPE",
130: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE",
131: "SCOPE_INFO_TYPE",
132: "SCRIPT_CONTEXT_TABLE_TYPE",
133: "BYTE_ARRAY_TYPE",
134: "BYTECODE_ARRAY_TYPE",
135: "FIXED_DOUBLE_ARRAY_TYPE",
136: "AWAIT_CONTEXT_TYPE",
137: "BLOCK_CONTEXT_TYPE",
138: "CATCH_CONTEXT_TYPE",
139: "DEBUG_EVALUATE_CONTEXT_TYPE",
140: "EVAL_CONTEXT_TYPE",
141: "FUNCTION_CONTEXT_TYPE",
142: "MODULE_CONTEXT_TYPE",
143: "NATIVE_CONTEXT_TYPE",
144: "SCRIPT_CONTEXT_TYPE",
145: "WITH_CONTEXT_TYPE",
146: "SMALL_ORDERED_HASH_MAP_TYPE",
147: "SMALL_ORDERED_HASH_SET_TYPE",
148: "SMALL_ORDERED_NAME_DICTIONARY_TYPE",
149: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE",
150: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE",
151: "WEAK_FIXED_ARRAY_TYPE",
152: "TRANSITION_ARRAY_TYPE",
153: "CELL_TYPE",
154: "CODE_TYPE",
155: "CODE_DATA_CONTAINER_TYPE",
156: "DESCRIPTOR_ARRAY_TYPE",
157: "EMBEDDER_DATA_ARRAY_TYPE",
158: "FEEDBACK_METADATA_TYPE",
159: "FEEDBACK_VECTOR_TYPE",
160: "FILLER_TYPE",
161: "FREE_SPACE_TYPE",
162: "MAP_TYPE",
163: "PREPARSE_DATA_TYPE",
164: "PROPERTY_ARRAY_TYPE",
165: "PROPERTY_CELL_TYPE",
166: "SHARED_FUNCTION_INFO_TYPE",
167: "WEAK_ARRAY_LIST_TYPE",
168: "WEAK_CELL_TYPE",
1024: "JS_PROXY_TYPE",
1025: "JS_GLOBAL_OBJECT_TYPE",
1026: "JS_GLOBAL_PROXY_TYPE",
1027: "JS_MODULE_NAMESPACE_TYPE",
169: "JS_PROXY_TYPE",
1057: "JS_OBJECT_TYPE",
170: "JS_GLOBAL_OBJECT_TYPE",
171: "JS_GLOBAL_PROXY_TYPE",
172: "JS_MODULE_NAMESPACE_TYPE",
1040: "JS_SPECIAL_API_OBJECT_TYPE",
1041: "JS_PRIMITIVE_WRAPPER_TYPE",
1042: "JS_MAP_KEY_ITERATOR_TYPE",
1043: "JS_MAP_KEY_VALUE_ITERATOR_TYPE",
1044: "JS_MAP_VALUE_ITERATOR_TYPE",
1045: "JS_SET_KEY_VALUE_ITERATOR_TYPE",
1046: "JS_SET_VALUE_ITERATOR_TYPE",
1047: "JS_GENERATOR_OBJECT_TYPE",
1048: "JS_ASYNC_FUNCTION_OBJECT_TYPE",
1049: "JS_ASYNC_GENERATOR_OBJECT_TYPE",
1050: "JS_DATA_VIEW_TYPE",
1051: "JS_TYPED_ARRAY_TYPE",
1052: "JS_MAP_TYPE",
1053: "JS_SET_TYPE",
1054: "JS_WEAK_MAP_TYPE",
1055: "JS_WEAK_SET_TYPE",
1056: "JS_API_OBJECT_TYPE",
1057: "JS_OBJECT_TYPE",
1058: "JS_ARGUMENTS_OBJECT_TYPE",
1059: "JS_ARRAY_BUFFER_TYPE",
1060: "JS_ARRAY_ITERATOR_TYPE",
1061: "JS_ARRAY_TYPE",
1059: "JS_ARRAY_TYPE",
1060: "JS_ARRAY_BUFFER_TYPE",
1061: "JS_ARRAY_ITERATOR_TYPE",
1062: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE",
1063: "JS_ASYNC_FUNCTION_OBJECT_TYPE",
1064: "JS_ASYNC_GENERATOR_OBJECT_TYPE",
1065: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
1066: "JS_DATE_TYPE",
1063: "JS_COLLATOR_TYPE",
1064: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
1065: "JS_DATE_TYPE",
1066: "JS_DATE_TIME_FORMAT_TYPE",
1067: "JS_ERROR_TYPE",
1068: "JS_GENERATOR_OBJECT_TYPE",
1069: "JS_MAP_TYPE",
1070: "JS_MAP_KEY_ITERATOR_TYPE",
1071: "JS_MAP_KEY_VALUE_ITERATOR_TYPE",
1072: "JS_MAP_VALUE_ITERATOR_TYPE",
1073: "JS_MESSAGE_OBJECT_TYPE",
1074: "JS_PROMISE_TYPE",
1075: "JS_REG_EXP_TYPE",
1076: "JS_REG_EXP_STRING_ITERATOR_TYPE",
1077: "JS_SET_TYPE",
1078: "JS_SET_KEY_VALUE_ITERATOR_TYPE",
1079: "JS_SET_VALUE_ITERATOR_TYPE",
1080: "JS_STRING_ITERATOR_TYPE",
1081: "JS_WEAK_REF_TYPE",
1082: "JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE",
1083: "JS_FINALIZATION_GROUP_TYPE",
1084: "JS_WEAK_MAP_TYPE",
1085: "JS_WEAK_SET_TYPE",
1086: "JS_TYPED_ARRAY_TYPE",
1087: "JS_DATA_VIEW_TYPE",
1088: "JS_V8_BREAK_ITERATOR_TYPE",
1089: "JS_COLLATOR_TYPE",
1090: "JS_DATE_TIME_FORMAT_TYPE",
1091: "JS_LIST_FORMAT_TYPE",
1092: "JS_LOCALE_TYPE",
1093: "JS_NUMBER_FORMAT_TYPE",
1094: "JS_PLURAL_RULES_TYPE",
1095: "JS_RELATIVE_TIME_FORMAT_TYPE",
1096: "JS_SEGMENT_ITERATOR_TYPE",
1097: "JS_SEGMENTER_TYPE",
1098: "WASM_EXCEPTION_OBJECT_TYPE",
1099: "WASM_GLOBAL_OBJECT_TYPE",
1100: "WASM_INSTANCE_OBJECT_TYPE",
1101: "WASM_MEMORY_OBJECT_TYPE",
1102: "WASM_MODULE_OBJECT_TYPE",
1103: "WASM_TABLE_OBJECT_TYPE",
1104: "JS_BOUND_FUNCTION_TYPE",
1105: "JS_FUNCTION_TYPE",
1068: "JS_FINALIZATION_GROUP_TYPE",
1069: "JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE",
1070: "JS_LIST_FORMAT_TYPE",
1071: "JS_LOCALE_TYPE",
1072: "JS_MESSAGE_OBJECT_TYPE",
1073: "JS_NUMBER_FORMAT_TYPE",
1074: "JS_PLURAL_RULES_TYPE",
1075: "JS_PROMISE_TYPE",
1076: "JS_REG_EXP_TYPE",
1077: "JS_REG_EXP_STRING_ITERATOR_TYPE",
1078: "JS_RELATIVE_TIME_FORMAT_TYPE",
1079: "JS_SEGMENT_ITERATOR_TYPE",
1080: "JS_SEGMENTER_TYPE",
1081: "JS_STRING_ITERATOR_TYPE",
1082: "JS_V8_BREAK_ITERATOR_TYPE",
1083: "JS_WEAK_REF_TYPE",
1084: "WASM_EXCEPTION_OBJECT_TYPE",
1085: "WASM_GLOBAL_OBJECT_TYPE",
1086: "WASM_INSTANCE_OBJECT_TYPE",
1087: "WASM_MEMORY_OBJECT_TYPE",
1088: "WASM_MODULE_OBJECT_TYPE",
1089: "WASM_TABLE_OBJECT_TYPE",
1090: "JS_BOUND_FUNCTION_TYPE",
1091: "JS_FUNCTION_TYPE",
}
# List of known V8 maps.
KNOWN_MAPS = {
("read_only_space", 0x00121): (73, "FreeSpaceMap"),
("read_only_space", 0x00169): (68, "MetaMap"),
("read_only_space", 0x00121): (161, "FreeSpaceMap"),
("read_only_space", 0x00169): (162, "MetaMap"),
("read_only_space", 0x001e1): (67, "NullMap"),
("read_only_space", 0x00241): (153, "DescriptorArrayMap"),
("read_only_space", 0x00299): (148, "WeakFixedArrayMap"),
("read_only_space", 0x002e1): (76, "OnePointerFillerMap"),
("read_only_space", 0x00329): (76, "TwoPointerFillerMap"),
("read_only_space", 0x00241): (156, "DescriptorArrayMap"),
("read_only_space", 0x00299): (151, "WeakFixedArrayMap"),
("read_only_space", 0x002e1): (160, "OnePointerFillerMap"),
("read_only_space", 0x00329): (160, "TwoPointerFillerMap"),
("read_only_space", 0x003a1): (67, "UninitializedMap"),
("read_only_space", 0x00409): (8, "OneByteInternalizedStringMap"),
("read_only_space", 0x004a1): (67, "UndefinedMap"),
("read_only_space", 0x004f9): (65, "HeapNumberMap"),
("read_only_space", 0x004f9): (66, "HeapNumberMap"),
("read_only_space", 0x00571): (67, "TheHoleMap"),
("read_only_space", 0x00611): (67, "BooleanMap"),
("read_only_space", 0x006e1): (71, "ByteArrayMap"),
("read_only_space", 0x00729): (123, "FixedArrayMap"),
("read_only_space", 0x00771): (123, "FixedCOWArrayMap"),
("read_only_space", 0x007b9): (126, "HashTableMap"),
("read_only_space", 0x006e1): (133, "ByteArrayMap"),
("read_only_space", 0x00729): (118, "FixedArrayMap"),
("read_only_space", 0x00771): (118, "FixedCOWArrayMap"),
("read_only_space", 0x007b9): (119, "HashTableMap"),
("read_only_space", 0x00801): (64, "SymbolMap"),
("read_only_space", 0x00849): (40, "OneByteStringMap"),
("read_only_space", 0x00891): (136, "ScopeInfoMap"),
("read_only_space", 0x008d9): (160, "SharedFunctionInfoMap"),
("read_only_space", 0x00921): (69, "CodeMap"),
("read_only_space", 0x00969): (143, "FunctionContextMap"),
("read_only_space", 0x009b1): (151, "CellMap"),
("read_only_space", 0x009f9): (159, "GlobalPropertyCellMap"),
("read_only_space", 0x00891): (131, "ScopeInfoMap"),
("read_only_space", 0x008d9): (166, "SharedFunctionInfoMap"),
("read_only_space", 0x00921): (154, "CodeMap"),
("read_only_space", 0x00969): (141, "FunctionContextMap"),
("read_only_space", 0x009b1): (153, "CellMap"),
("read_only_space", 0x009f9): (165, "GlobalPropertyCellMap"),
("read_only_space", 0x00a41): (70, "ForeignMap"),
("read_only_space", 0x00a89): (149, "TransitionArrayMap"),
("read_only_space", 0x00ad1): (155, "FeedbackVectorMap"),
("read_only_space", 0x00a89): (152, "TransitionArrayMap"),
("read_only_space", 0x00ad1): (159, "FeedbackVectorMap"),
("read_only_space", 0x00b69): (67, "ArgumentsMarkerMap"),
("read_only_space", 0x00c01): (67, "ExceptionMap"),
("read_only_space", 0x00c99): (67, "TerminationExceptionMap"),
("read_only_space", 0x00d39): (67, "OptimizedOutMap"),
("read_only_space", 0x00dd1): (67, "StaleRegisterMap"),
("read_only_space", 0x00e39): (145, "NativeContextMap"),
("read_only_space", 0x00e81): (144, "ModuleContextMap"),
("read_only_space", 0x00ec9): (142, "EvalContextMap"),
("read_only_space", 0x00f11): (146, "ScriptContextMap"),
("read_only_space", 0x00f59): (138, "AwaitContextMap"),
("read_only_space", 0x00fa1): (139, "BlockContextMap"),
("read_only_space", 0x00fe9): (140, "CatchContextMap"),
("read_only_space", 0x01031): (147, "WithContextMap"),
("read_only_space", 0x01079): (141, "DebugEvaluateContextMap"),
("read_only_space", 0x010c1): (137, "ScriptContextTableMap"),
("read_only_space", 0x01109): (125, "ClosureFeedbackCellArrayMap"),
("read_only_space", 0x01151): (75, "FeedbackMetadataArrayMap"),
("read_only_space", 0x01199): (123, "ArrayListMap"),
("read_only_space", 0x011e1): (66, "BigIntMap"),
("read_only_space", 0x01229): (124, "ObjectBoilerplateDescriptionMap"),
("read_only_space", 0x01271): (72, "BytecodeArrayMap"),
("read_only_space", 0x012b9): (152, "CodeDataContainerMap"),
("read_only_space", 0x01301): (74, "FixedDoubleArrayMap"),
("read_only_space", 0x01349): (131, "GlobalDictionaryMap"),
("read_only_space", 0x01391): (154, "ManyClosuresCellMap"),
("read_only_space", 0x013d9): (123, "ModuleInfoMap"),
("read_only_space", 0x01421): (130, "NameDictionaryMap"),
("read_only_space", 0x01469): (154, "NoClosuresCellMap"),
("read_only_space", 0x014b1): (132, "NumberDictionaryMap"),
("read_only_space", 0x014f9): (154, "OneClosureCellMap"),
("read_only_space", 0x01541): (127, "OrderedHashMapMap"),
("read_only_space", 0x01589): (128, "OrderedHashSetMap"),
("read_only_space", 0x015d1): (129, "OrderedNameDictionaryMap"),
("read_only_space", 0x01619): (157, "PreparseDataMap"),
("read_only_space", 0x01661): (158, "PropertyArrayMap"),
("read_only_space", 0x016a9): (150, "SideEffectCallHandlerInfoMap"),
("read_only_space", 0x016f1): (150, "SideEffectFreeCallHandlerInfoMap"),
("read_only_space", 0x01739): (150, "NextCallSideEffectFreeCallHandlerInfoMap"),
("read_only_space", 0x01781): (133, "SimpleNumberDictionaryMap"),
("read_only_space", 0x017c9): (123, "SloppyArgumentsElementsMap"),
("read_only_space", 0x01811): (161, "SmallOrderedHashMapMap"),
("read_only_space", 0x01859): (162, "SmallOrderedHashSetMap"),
("read_only_space", 0x018a1): (163, "SmallOrderedNameDictionaryMap"),
("read_only_space", 0x018e9): (119, "SourceTextModuleMap"),
("read_only_space", 0x01931): (134, "StringTableMap"),
("read_only_space", 0x01979): (120, "SyntheticModuleMap"),
("read_only_space", 0x019c1): (165, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x01a09): (166, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x00e39): (143, "NativeContextMap"),
("read_only_space", 0x00e81): (142, "ModuleContextMap"),
("read_only_space", 0x00ec9): (140, "EvalContextMap"),
("read_only_space", 0x00f11): (144, "ScriptContextMap"),
("read_only_space", 0x00f59): (136, "AwaitContextMap"),
("read_only_space", 0x00fa1): (137, "BlockContextMap"),
("read_only_space", 0x00fe9): (138, "CatchContextMap"),
("read_only_space", 0x01031): (145, "WithContextMap"),
("read_only_space", 0x01079): (139, "DebugEvaluateContextMap"),
("read_only_space", 0x010c1): (132, "ScriptContextTableMap"),
("read_only_space", 0x01109): (129, "ClosureFeedbackCellArrayMap"),
("read_only_space", 0x01151): (158, "FeedbackMetadataArrayMap"),
("read_only_space", 0x01199): (118, "ArrayListMap"),
("read_only_space", 0x011e1): (65, "BigIntMap"),
("read_only_space", 0x01229): (130, "ObjectBoilerplateDescriptionMap"),
("read_only_space", 0x01271): (134, "BytecodeArrayMap"),
("read_only_space", 0x012b9): (155, "CodeDataContainerMap"),
("read_only_space", 0x01301): (135, "FixedDoubleArrayMap"),
("read_only_space", 0x01349): (121, "GlobalDictionaryMap"),
("read_only_space", 0x01391): (95, "ManyClosuresCellMap"),
("read_only_space", 0x013d9): (118, "ModuleInfoMap"),
("read_only_space", 0x01421): (122, "NameDictionaryMap"),
("read_only_space", 0x01469): (95, "NoClosuresCellMap"),
("read_only_space", 0x014b1): (123, "NumberDictionaryMap"),
("read_only_space", 0x014f9): (95, "OneClosureCellMap"),
("read_only_space", 0x01541): (124, "OrderedHashMapMap"),
("read_only_space", 0x01589): (125, "OrderedHashSetMap"),
("read_only_space", 0x015d1): (126, "OrderedNameDictionaryMap"),
("read_only_space", 0x01619): (163, "PreparseDataMap"),
("read_only_space", 0x01661): (164, "PropertyArrayMap"),
("read_only_space", 0x016a9): (91, "SideEffectCallHandlerInfoMap"),
("read_only_space", 0x016f1): (91, "SideEffectFreeCallHandlerInfoMap"),
("read_only_space", 0x01739): (91, "NextCallSideEffectFreeCallHandlerInfoMap"),
("read_only_space", 0x01781): (127, "SimpleNumberDictionaryMap"),
("read_only_space", 0x017c9): (118, "SloppyArgumentsElementsMap"),
("read_only_space", 0x01811): (146, "SmallOrderedHashMapMap"),
("read_only_space", 0x01859): (147, "SmallOrderedHashSetMap"),
("read_only_space", 0x018a1): (148, "SmallOrderedNameDictionaryMap"),
("read_only_space", 0x018e9): (68, "SourceTextModuleMap"),
("read_only_space", 0x01931): (128, "StringTableMap"),
("read_only_space", 0x01979): (69, "SyntheticModuleMap"),
("read_only_space", 0x019c1): (150, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x01a09): (149, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x01a51): (167, "WeakArrayListMap"),
("read_only_space", 0x01a99): (135, "EphemeronHashTableMap"),
("read_only_space", 0x01ae1): (122, "EmbedderDataArrayMap"),
("read_only_space", 0x01a99): (120, "EphemeronHashTableMap"),
("read_only_space", 0x01ae1): (157, "EmbedderDataArrayMap"),
("read_only_space", 0x01b29): (168, "WeakCellMap"),
("read_only_space", 0x01b71): (58, "NativeSourceStringMap"),
("read_only_space", 0x01bb9): (32, "StringMap"),
@ -288,59 +288,59 @@ KNOWN_MAPS = {
("read_only_space", 0x01fa9): (26, "UncachedExternalOneByteInternalizedStringMap"),
("read_only_space", 0x01ff1): (58, "UncachedExternalOneByteStringMap"),
("read_only_space", 0x02039): (67, "SelfReferenceMarkerMap"),
("read_only_space", 0x02099): (87, "EnumCacheMap"),
("read_only_space", 0x02131): (82, "ArrayBoilerplateDescriptionMap"),
("read_only_space", 0x02319): (90, "InterceptorInfoMap"),
("read_only_space", 0x04c51): (77, "AccessCheckInfoMap"),
("read_only_space", 0x04c99): (78, "AccessorInfoMap"),
("read_only_space", 0x04ce1): (79, "AccessorPairMap"),
("read_only_space", 0x04d29): (80, "AliasedArgumentsEntryMap"),
("read_only_space", 0x04d71): (81, "AllocationMementoMap"),
("read_only_space", 0x04db9): (83, "AsmWasmDataMap"),
("read_only_space", 0x04e01): (84, "AsyncGeneratorRequestMap"),
("read_only_space", 0x04e49): (85, "ClassPositionsMap"),
("read_only_space", 0x04e91): (86, "DebugInfoMap"),
("read_only_space", 0x04ed9): (88, "FunctionTemplateInfoMap"),
("read_only_space", 0x04f21): (89, "FunctionTemplateRareDataMap"),
("read_only_space", 0x04f69): (91, "InterpreterDataMap"),
("read_only_space", 0x04fb1): (92, "ObjectTemplateInfoMap"),
("read_only_space", 0x04ff9): (93, "PromiseCapabilityMap"),
("read_only_space", 0x05041): (94, "PromiseReactionMap"),
("read_only_space", 0x05089): (95, "PrototypeInfoMap"),
("read_only_space", 0x050d1): (96, "ScriptMap"),
("read_only_space", 0x05119): (97, "SourcePositionTableWithFrameCacheMap"),
("read_only_space", 0x05161): (98, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x051a9): (99, "StackFrameInfoMap"),
("read_only_space", 0x051f1): (100, "StackTraceFrameMap"),
("read_only_space", 0x05239): (101, "TemplateObjectDescriptionMap"),
("read_only_space", 0x05281): (102, "Tuple2Map"),
("read_only_space", 0x052c9): (103, "Tuple3Map"),
("read_only_space", 0x05311): (104, "WasmCapiFunctionDataMap"),
("read_only_space", 0x05359): (105, "WasmDebugInfoMap"),
("read_only_space", 0x053a1): (106, "WasmExceptionTagMap"),
("read_only_space", 0x053e9): (107, "WasmExportedFunctionDataMap"),
("read_only_space", 0x05431): (108, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x05479): (109, "WasmJSFunctionDataMap"),
("read_only_space", 0x054c1): (110, "CallableTaskMap"),
("read_only_space", 0x05509): (111, "CallbackTaskMap"),
("read_only_space", 0x05551): (112, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x05599): (113, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x055e1): (114, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x05629): (115, "InternalClassMap"),
("read_only_space", 0x05671): (116, "SmiPairMap"),
("read_only_space", 0x056b9): (117, "SmiBoxMap"),
("read_only_space", 0x05701): (118, "SortStateMap"),
("read_only_space", 0x05749): (121, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x05791): (121, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x057d9): (156, "LoadHandler1Map"),
("read_only_space", 0x05821): (156, "LoadHandler2Map"),
("read_only_space", 0x05869): (156, "LoadHandler3Map"),
("read_only_space", 0x058b1): (164, "StoreHandler0Map"),
("read_only_space", 0x058f9): (164, "StoreHandler1Map"),
("read_only_space", 0x05941): (164, "StoreHandler2Map"),
("read_only_space", 0x05989): (164, "StoreHandler3Map"),
("read_only_space", 0x02099): (94, "EnumCacheMap"),
("read_only_space", 0x02131): (88, "ArrayBoilerplateDescriptionMap"),
("read_only_space", 0x02319): (97, "InterceptorInfoMap"),
("read_only_space", 0x04c51): (71, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x04c99): (72, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x04ce1): (73, "CallableTaskMap"),
("read_only_space", 0x04d29): (74, "CallbackTaskMap"),
("read_only_space", 0x04d71): (75, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x04db9): (78, "FunctionTemplateInfoMap"),
("read_only_space", 0x04e01): (79, "ObjectTemplateInfoMap"),
("read_only_space", 0x04e49): (80, "Tuple2Map"),
("read_only_space", 0x04e91): (81, "Tuple3Map"),
("read_only_space", 0x04ed9): (82, "AccessCheckInfoMap"),
("read_only_space", 0x04f21): (83, "AccessorInfoMap"),
("read_only_space", 0x04f69): (84, "AccessorPairMap"),
("read_only_space", 0x04fb1): (85, "AliasedArgumentsEntryMap"),
("read_only_space", 0x04ff9): (86, "AllocationMementoMap"),
("read_only_space", 0x05041): (89, "AsmWasmDataMap"),
("read_only_space", 0x05089): (90, "AsyncGeneratorRequestMap"),
("read_only_space", 0x050d1): (92, "ClassPositionsMap"),
("read_only_space", 0x05119): (93, "DebugInfoMap"),
("read_only_space", 0x05161): (96, "FunctionTemplateRareDataMap"),
("read_only_space", 0x051a9): (99, "InterpreterDataMap"),
("read_only_space", 0x051f1): (100, "PromiseCapabilityMap"),
("read_only_space", 0x05239): (101, "PromiseReactionMap"),
("read_only_space", 0x05281): (102, "PrototypeInfoMap"),
("read_only_space", 0x052c9): (103, "ScriptMap"),
("read_only_space", 0x05311): (107, "SourcePositionTableWithFrameCacheMap"),
("read_only_space", 0x05359): (108, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x053a1): (109, "StackFrameInfoMap"),
("read_only_space", 0x053e9): (110, "StackTraceFrameMap"),
("read_only_space", 0x05431): (111, "TemplateObjectDescriptionMap"),
("read_only_space", 0x05479): (112, "WasmCapiFunctionDataMap"),
("read_only_space", 0x054c1): (113, "WasmDebugInfoMap"),
("read_only_space", 0x05509): (114, "WasmExceptionTagMap"),
("read_only_space", 0x05551): (115, "WasmExportedFunctionDataMap"),
("read_only_space", 0x05599): (116, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x055e1): (117, "WasmJSFunctionDataMap"),
("read_only_space", 0x05629): (98, "InternalClassMap"),
("read_only_space", 0x05671): (105, "SmiPairMap"),
("read_only_space", 0x056b9): (104, "SmiBoxMap"),
("read_only_space", 0x05701): (106, "SortStateMap"),
("read_only_space", 0x05749): (87, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x05791): (87, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x057d9): (76, "LoadHandler1Map"),
("read_only_space", 0x05821): (76, "LoadHandler2Map"),
("read_only_space", 0x05869): (76, "LoadHandler3Map"),
("read_only_space", 0x058b1): (77, "StoreHandler0Map"),
("read_only_space", 0x058f9): (77, "StoreHandler1Map"),
("read_only_space", 0x05941): (77, "StoreHandler2Map"),
("read_only_space", 0x05989): (77, "StoreHandler3Map"),
("map_space", 0x00121): (1057, "ExternalMap"),
("map_space", 0x00169): (1073, "JSMessageObjectMap"),
("map_space", 0x00169): (1072, "JSMessageObjectMap"),
}
# List of known V8 objects.