Skip to content
Permalink
Browse files

[torque]: Class declarations

Class declarations support structured heap data that is a subtype of
HeapObject. Only fields of Object subtypes (both strong and weak)
are currently supported (no scalar fields yet).

With this CL, both the field list macro used with the C++
DEFINE_FIELD_OFFSET_CONSTANTS macro (to make field offset constants) as
well as the Torque "operator '.field'" macros are generated for the
classes declared in Torque. This is a first step to removing the
substantial amount of duplication and boilerplate code
needed to declare heap object classes.

As a proof of concept, and handful of class field definitions,
including those for non trivial classes like JSFunction, have been
moved to Torque.

Bug: v8:7793
Change-Id: I2fa0b53db65fa6f5fe078fb94e1db3418f908753
Reviewed-on: https://chromium-review.googlesource.com/c/1373971
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58704}
  • Loading branch information...
dannoc authored and Commit Bot committed Jan 10, 2019
1 parent bb46048 commit d0e95c7a1a4be3bbab28e840a64aef3b275faa2c
@@ -17,7 +17,11 @@ type never;

type Tagged generates 'TNode<Object>' constexpr 'ObjectPtr';
type Smi extends Tagged generates 'TNode<Smi>' constexpr 'Smi';
type HeapObject extends Tagged generates 'TNode<HeapObject>';

class HeapObject extends Tagged {
map_untyped: Tagged;
}

type Object = Smi | HeapObject;
type int32 generates 'TNode<Int32T>' constexpr 'int32_t';
type uint32 generates 'TNode<Uint32T>' constexpr 'uint32_t';
@@ -36,8 +40,6 @@ type RawPtr generates 'TNode<RawPtrT>' constexpr 'void*';
type AbstractCode extends HeapObject generates 'TNode<AbstractCode>';
type Code extends AbstractCode generates 'TNode<Code>';
type BuiltinPtr extends Smi generates 'TNode<BuiltinPtr>';
type JSReceiver extends HeapObject generates 'TNode<JSReceiver>';
type Constructor extends JSReceiver generates 'TNode<JSReceiver>';
type Context extends HeapObject generates 'TNode<Context>';
type NativeContext extends Context generates 'TNode<Context>';
type String extends HeapObject generates 'TNode<String>';
@@ -46,12 +48,39 @@ type HeapNumber extends HeapObject generates 'TNode<HeapNumber>';
type Number = Smi | HeapNumber;
type BigInt extends HeapObject generates 'TNode<BigInt>';
type Numeric = Number | BigInt;

type Map extends HeapObject generates 'TNode<Map>';
// The accessors for HeapObject's map cannot be declared before Map
// is declared because forward declarations are not (yet) supported.
// TODO(danno): Make circular references in classes possible. One way to do that
// would be to pre-process all class declarations and create bindings for them
// with an uninitialized class type, and then process them later properly
extern operator '.map' macro LoadMap(HeapObject): Map;
extern transitioning operator '.map=' macro StoreMap(HeapObject, Map);

type FixedArrayBase extends HeapObject generates 'TNode<FixedArrayBase>';
type FixedArray extends FixedArrayBase generates 'TNode<FixedArray>';
type FixedDoubleArray extends FixedArrayBase
generates 'TNode<FixedDoubleArray>';

class JSReceiver extends HeapObject {
properties_or_hash: Object;
}

type Constructor extends JSReceiver generates 'TNode<JSReceiver>';
type JSProxy extends JSReceiver generates 'TNode<JSProxy>';
type JSObject extends JSReceiver generates 'TNode<JSObject>';
type JSArgumentsObjectWithLength extends JSObject
generates 'TNode<JSArgumentsObjectWithLength>';
type JSArray extends JSArgumentsObjectWithLength
generates 'TNode<JSArray>';

class JSObject extends JSReceiver {
elements: FixedArrayBase;
}

class JSArgumentsObjectWithLength extends JSObject {
length: Object;
}

class JSArray extends JSObject {
length: Number;
}

// A HeapObject with a JSArray map, and either fast packed elements, or fast
// holey elements when the global NoElementsProtector is not invalidated.
@@ -69,19 +98,24 @@ transient type FastJSArrayWithNoCustomIteration extends FastJSArray
type SharedFunctionInfo extends HeapObject
generates 'TNode<SharedFunctionInfo>';

type JSFunction extends JSObject generates 'TNode<JSFunction>';
extern operator '.shared_function_info'
macro LoadJSFunctionSharedFunctionInfo(JSFunction): SharedFunctionInfo;
class JSFunction extends JSObject {
shared_function_info: SharedFunctionInfo;
context: Context;
feedback_cell: Smi;
weak code: Code;
weak prototype_or_initial_map: JSReceiver | Map;
}

extern operator '.formal_parameter_count'
macro LoadSharedFunctionInfoFormalParameterCount(SharedFunctionInfo): int32;

type JSBoundFunction extends JSObject generates 'TNode<JSBoundFunction>';
class JSBoundFunction extends JSObject {
bound_target_function: JSReceiver;
bound_this: Object;
bound_arguments: FixedArray;
}

type Callable = JSFunction | JSBoundFunction | JSProxy;
type Map extends HeapObject generates 'TNode<Map>';
type FixedArrayBase extends HeapObject generates 'TNode<FixedArrayBase>';
type FixedArray extends FixedArrayBase generates 'TNode<FixedArray>';
type FixedDoubleArray extends FixedArrayBase
generates 'TNode<FixedDoubleArray>';
type FixedTypedArrayBase extends FixedArrayBase
generates 'TNode<FixedTypedArrayBase>';
type FixedTypedArray extends FixedTypedArrayBase
@@ -520,8 +554,6 @@ extern operator '!' macro ConstexprBoolNot(constexpr bool): constexpr bool;
extern operator '!' macro Word32BinaryNot(bool): bool;
extern operator '!' macro IsFalse(Boolean): bool;

extern operator '.map' macro LoadMap(HeapObject): Map;
extern transitioning operator '.map=' macro StoreMap(HeapObject, Map);
extern operator '.instanceType' macro LoadInstanceType(HeapObject):
InstanceType;

@@ -1018,15 +1050,8 @@ extern operator '.elements_kind' macro LoadMapElementsKind(Map): ElementsKind;
extern operator '.elements_kind' macro LoadElementsKind(JSTypedArray):
ElementsKind;

extern operator '.elements' macro LoadElements(JSObject): FixedArrayBase;
extern operator '.elements=' macro StoreElements(JSObject, FixedArrayBase);

extern operator '.length' macro LoadJSTypedArrayLength(JSTypedArray): Smi;
extern operator '.length' macro LoadJSArrayLength(JSArray): Number;
extern operator '.length' macro LoadJSArgumentsObjectWithLength(
JSArgumentsObjectWithLength): Object;
extern operator '.length' macro LoadFastJSArrayLength(FastJSArray): Smi;
extern operator '.length=' macro StoreJSArrayLength(JSArray, Smi);

extern operator '.length' macro LoadFixedArrayBaseLength(FixedArrayBase): Smi;
extern operator '.length_intptr' macro LoadAndUntagFixedArrayBaseLength(
@@ -1055,9 +1080,6 @@ extern macro StoreFixedArrayElementSmi(

extern operator '.instance_type' macro LoadMapInstanceType(Map): int32;

extern operator '.prototype_or_initial_map' macro
LoadJSFunctionPrototypeOrInitialMap(JSFunction): Object;

extern macro LoadFixedDoubleArrayElement(FixedDoubleArray, Smi): float64;
extern macro Float64SilenceNaN(float64): float64;

@@ -1462,8 +1462,7 @@ TNode<BoolT> CodeStubAssembler::TaggedDoesntHaveInstanceType(
TNode<HeapObject> CodeStubAssembler::LoadFastProperties(
SloppyTNode<JSObject> object) {
CSA_SLOW_ASSERT(this, Word32BinaryNot(IsDictionaryMap(LoadMap(object))));
TNode<Object> properties =
LoadObjectField(object, JSObject::kPropertiesOrHashOffset);
TNode<Object> properties = LoadJSReceiverPropertiesOrHash(object);
return Select<HeapObject>(TaggedIsSmi(properties),
[=] { return EmptyFixedArrayConstant(); },
[=] { return CAST(properties); });
@@ -1472,18 +1471,12 @@ TNode<HeapObject> CodeStubAssembler::LoadFastProperties(
TNode<HeapObject> CodeStubAssembler::LoadSlowProperties(
SloppyTNode<JSObject> object) {
CSA_SLOW_ASSERT(this, IsDictionaryMap(LoadMap(object)));
TNode<Object> properties =
LoadObjectField(object, JSObject::kPropertiesOrHashOffset);
TNode<Object> properties = LoadJSReceiverPropertiesOrHash(object);
return Select<HeapObject>(TaggedIsSmi(properties),
[=] { return EmptyPropertyDictionaryConstant(); },
[=] { return CAST(properties); });
}

TNode<FixedArrayBase> CodeStubAssembler::LoadElements(
SloppyTNode<JSObject> object) {
return CAST(LoadObjectField(object, JSObject::kElementsOffset));
}

TNode<Number> CodeStubAssembler::LoadJSArrayLength(SloppyTNode<JSArray> array) {
CSA_ASSERT(this, IsJSArray(array));
return CAST(LoadObjectField(array, JSArray::kLengthOffset));
@@ -843,7 +843,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<HeapObject> LoadSlowProperties(SloppyTNode<JSObject> object);
TNode<HeapObject> LoadFastProperties(SloppyTNode<JSObject> object);
// Load the elements backing store of a JSObject.
TNode<FixedArrayBase> LoadElements(SloppyTNode<JSObject> object);
TNode<FixedArrayBase> LoadElements(SloppyTNode<JSObject> object) {
return LoadJSObjectElements(object);
}
// Load the length of a JSArray instance.
TNode<Object> LoadJSArgumentsObjectWithLength(
SloppyTNode<JSArgumentsObjectWithLength> array);
@@ -1167,17 +1169,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BytecodeArray> LoadSharedFunctionInfoBytecodeArray(
SloppyTNode<SharedFunctionInfo> shared);

TNode<Object> LoadJSFunctionPrototypeOrInitialMap(
TNode<JSFunction> function) {
return LoadObjectField(function, JSFunction::kPrototypeOrInitialMapOffset);
}

TNode<SharedFunctionInfo> LoadJSFunctionSharedFunctionInfo(
TNode<JSFunction> function) {
return CAST(
LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset));
}

TNode<Int32T> LoadSharedFunctionInfoFormalParameterCount(
TNode<SharedFunctionInfo> function) {
return TNode<Int32T>::UncheckedCast(LoadObjectField(
@@ -8,6 +8,7 @@
#include "src/objects/fixed-array.h"
#include "src/objects/js-objects.h"
#include "src/objects/struct.h"
#include "torque-generated/class-definitions-from-dsl.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -35,7 +36,7 @@ class JSArgumentsObjectWithLength : public JSArgumentsObject {
V(kSize, 0)

DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
JS_ARGUMENTS_OBJECT_WITH_LENGTH_FIELDS)
JSARGUMENTS_OBJECT_WITH_LENGTH_FIELDS)
#undef JS_ARGUMENTS_OBJECT_WITH_LENGTH_FIELDS

// Indices of in-object properties.
@@ -8,6 +8,7 @@
#include "src/objects/allocation-site.h"
#include "src/objects/fixed-array.h"
#include "src/objects/js-objects.h"
#include "torque-generated/class-definitions-from-dsl.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -104,13 +105,7 @@ class JSArray : public JSObject {
// Number of element slots to pre-allocate for an empty array.
static const int kPreallocatedArrayElements = 4;

// Layout description.
#define JS_ARRAY_FIELDS(V) \
V(kLengthOffset, kTaggedSize) \
/* Header size. */ \
V(kSize, 0)

DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_ARRAY_FIELDS)
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JSARRAY_FIELDS)
#undef JS_ARRAY_FIELDS

static const int kLengthDescriptorIndex = 0;
@@ -8,6 +8,7 @@
#include "src/objects.h"
#include "src/objects/embedder-data-slot.h"
#include "src/objects/property-array.h"
#include "torque-generated/class-definitions-from-dsl.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -256,14 +257,8 @@ class JSReceiver : public HeapObject {

static const int kHashMask = PropertyArray::HashField::kMask;

// Layout description.
#define JS_RECEIVER_FIELDS(V) \
V(kPropertiesOrHashOffset, kTaggedSize) \
/* Header size. */ \
V(kHeaderSize, 0)

DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, JS_RECEIVER_FIELDS)
#undef JS_RECEIVER_FIELDS
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, JSRECEIVER_FIELDS)
static const int kHeaderSize = kSize;

bool HasProxyInPrototype(Isolate* isolate);

@@ -936,15 +931,7 @@ class JSBoundFunction : public JSObject {
static Handle<String> ToString(Handle<JSBoundFunction> function);

// Layout description.
#define JS_BOUND_FUNCTION_FIELDS(V) \
V(kBoundTargetFunctionOffset, kTaggedSize) \
V(kBoundThisOffset, kTaggedSize) \
V(kBoundArgumentsOffset, kTaggedSize) \
/* Header size. */ \
V(kSize, 0)

DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_BOUND_FUNCTION_FIELDS)
#undef JS_BOUND_FUNCTION_FIELDS
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JSBOUND_FUNCTION_FIELDS)

OBJECT_CONSTRUCTORS(JSBoundFunction, JSObject);
};
@@ -1137,22 +1124,10 @@ class JSFunction : public JSObject {
// ES6 section 19.2.3.5 Function.prototype.toString ( ).
static Handle<String> ToString(Handle<JSFunction> function);

// Layout description.
#define JS_FUNCTION_FIELDS(V) \
/* Pointer fields. */ \
V(kSharedFunctionInfoOffset, kTaggedSize) \
V(kContextOffset, kTaggedSize) \
V(kFeedbackCellOffset, kTaggedSize) \
V(kEndOfStrongFieldsOffset, 0) \
V(kCodeOffset, kTaggedSize) \
/* Size of JSFunction object without prototype field. */ \
V(kSizeWithoutPrototype, 0) \
V(kPrototypeOrInitialMapOffset, kTaggedSize) \
/* Size of JSFunction object with prototype field. */ \
V(kSizeWithPrototype, 0)

DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_FUNCTION_FIELDS)
#undef JS_FUNCTION_FIELDS
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JSFUNCTION_FIELDS)

static constexpr int kSizeWithoutPrototype = kPrototypeOrInitialMapOffset;
static constexpr int kSizeWithPrototype = kSize;

OBJECT_CONSTRUCTORS(JSFunction, JSObject);
};

0 comments on commit d0e95c7

Please sign in to comment.
You can’t perform that action at this time.