Commit c0e24791 authored by Daniel Clifford's avatar Daniel Clifford Committed by Commit Bot

[torque] Make more classes eligible for direct map Cast<> checks

Also should address minor performance regressions for instance types
that should (and used to) use map compare rather than instance_type
comparison.

In the process, convert a bunch of IsXXX methods from the CSA into
exported Torque methods that call through to the Cast<> to ensure
there is only a single implementation of the type checkers. Also clean
up and remove duplicate/redundant code and unused Torque imports.

Bug: v8:7793, chromium:1098481
Change-Id: I3cd5146d913bb75bab4f73415b1b94bc30924725
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2270545
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68621}
parent 26626f87
......@@ -4,24 +4,114 @@
extern macro IsBigInt(HeapObject): bool;
extern macro IsConstructor(HeapObject): bool;
extern macro IsContext(HeapObject): bool;
extern macro IsCustomElementsReceiverInstanceType(int32): bool;
extern macro IsExtensibleMap(Map): bool;
extern macro IsFixedArray(HeapObject): bool;
extern macro IsHeapNumber(HeapObject): bool;
extern macro IsJSArrayMap(Map): bool;
extern macro IsJSProxy(HeapObject): bool;
extern macro IsName(HeapObject): bool;
extern macro IsNativeContext(HeapObject): bool;
extern macro IsNumberNormalized(Number): bool;
extern macro IsNumber(Object): bool;
extern macro IsPrivateSymbol(HeapObject): bool;
extern macro IsSafeInteger(Object): bool;
@export
macro IsAccessorInfo(o: HeapObject): bool {
return Is<AccessorInfo>(o);
}
@export
macro IsAccessorPair(o: HeapObject): bool {
return Is<AccessorPair>(o);
}
@export
macro IsAllocationSite(o: HeapObject): bool {
Cast<AllocationSite>(o) otherwise return false;
return true;
return Is<AllocationSite>(o);
}
@export
macro IsCell(o: HeapObject): bool {
return Is<Cell>(o);
}
@export
macro IsCode(o: HeapObject): bool {
return Is<Code>(o);
}
@export
macro IsContext(o: HeapObject): bool {
return Is<Context>(o);
}
@export
macro IsCoverageInfo(o: HeapObject): bool {
return Is<CoverageInfo>(o);
}
@export
macro IsDebugInfo(o: HeapObject): bool {
return Is<DebugInfo>(o);
}
@export
macro IsFixedDoubleArray(o: HeapObject): bool {
return Is<FixedDoubleArray>(o);
}
@export
macro IsFeedbackCell(o: HeapObject): bool {
return Is<FeedbackCell>(o);
}
@export
macro IsFeedbackVector(o: HeapObject): bool {
return Is<FeedbackVector>(o);
}
@export
macro IsHeapNumber(o: HeapObject): bool {
return Is<HeapNumber>(o);
}
@export
macro IsNativeContext(o: HeapObject): bool {
return Is<NativeContext>(o);
}
@export
macro IsNumber(o: Object): bool {
return Is<Number>(o);
}
@export
macro IsPrivateSymbol(o: HeapObject): bool {
return Is<PrivateSymbol>(o);
}
@export
macro IsPromiseCapability(o: HeapObject): bool {
return Is<PromiseCapability>(o);
}
@export
macro IsPromiseFulfillReactionJobTask(o: HeapObject): bool {
return Is<PromiseFulfillReactionJobTask>(o);
}
@export
macro IsPromiseReaction(o: HeapObject): bool {
return Is<PromiseReaction>(o);
}
@export
macro IsPromiseRejectReactionJobTask(o: HeapObject): bool {
return Is<PromiseRejectReactionJobTask>(o);
}
@export
macro IsSharedFunctionInfo(o: HeapObject): bool {
return Is<SharedFunctionInfo>(o);
}
@export
macro IsSymbol(o: HeapObject): bool {
return Is<Symbol>(o);
}
extern macro TaggedToHeapObject(Object): HeapObject
......@@ -39,8 +129,6 @@ extern macro HeapObjectToConstructor(HeapObject): Constructor
extern macro HeapObjectToJSFunctionWithPrototypeSlot(HeapObject):
JSFunctionWithPrototypeSlot
labels CastError;
extern macro TaggedToNumber(Object): Number
labels CastError;
macro Cast<A : type extends WeakHeapObject>(o: A|Object): A labels CastError {
if (!IsWeakOrCleared(o)) goto CastError;
......@@ -87,7 +175,17 @@ Cast<Zero>(o: Object): Zero labels CastError {
Cast<Number>(o: Object): Number
labels CastError {
return TaggedToNumber(o) otherwise CastError;
typeswitch (o) {
case (s: Smi): {
return s;
}
case (n: HeapNumber): {
return n;
}
case (Object): {
goto CastError;
}
}
}
Cast<Undefined>(o: Object): Undefined
......@@ -288,24 +386,21 @@ Cast<Undefined|Callable>(o: HeapObject): Undefined|Callable
}
macro Cast<T : type extends Symbol>(o: Symbol): T labels CastError;
Cast<PublicSymbol>(o: Symbol): PublicSymbol labels CastError {
if (IsPrivateSymbol(o)) goto CastError;
return %RawDownCast<PublicSymbol>(o);
Cast<PublicSymbol>(s: Symbol): PublicSymbol labels CastError {
if (s.flags.is_private) goto CastError;
return %RawDownCast<PublicSymbol>(s);
}
Cast<PrivateSymbol>(o: Symbol): PrivateSymbol labels CastError {
if (IsPrivateSymbol(o)) {
return %RawDownCast<PrivateSymbol>(o);
}
Cast<PrivateSymbol>(s: Symbol): PrivateSymbol labels CastError {
if (s.flags.is_private) return %RawDownCast<PrivateSymbol>(s);
goto CastError;
}
Cast<PublicSymbol>(o: HeapObject): PublicSymbol labels CastError {
const o = Cast<Symbol>(o) otherwise CastError;
return Cast<PublicSymbol>(o) otherwise CastError;
const s = Cast<Symbol>(o) otherwise CastError;
return Cast<PublicSymbol>(s) otherwise CastError;
}
Cast<PrivateSymbol>(o: HeapObject): PrivateSymbol labels CastError {
const o = Cast<Symbol>(o) otherwise CastError;
return Cast<PrivateSymbol>(o) otherwise CastError;
const s = Cast<Symbol>(o) otherwise CastError;
return Cast<PrivateSymbol>(s) otherwise CastError;
}
Cast<DirectString>(o: HeapObject): DirectString
......@@ -385,10 +480,10 @@ Cast<FastJSArray>(implicit context: Context)(o: HeapObject): FastJSArray
labels CastError {
if (IsForceSlowPath()) goto CastError;
const map: Map = o.map;
if (!IsJSArrayMap(map)) goto CastError;
if (!Is<JSArray>(o)) goto CastError;
// Bailout if receiver has slow elements.
const map: Map = o.map;
const elementsKind: ElementsKind = LoadMapElementsKind(map);
if (!IsFastElementsKind(elementsKind)) goto CastError;
......@@ -402,10 +497,10 @@ Cast<FastJSArray>(implicit context: Context)(o: HeapObject): FastJSArray
Cast<FastJSArrayForRead>(implicit context: Context)(o: HeapObject):
FastJSArrayForRead
labels CastError {
const map: Map = o.map;
if (!IsJSArrayMap(map)) goto CastError;
if (!Is<JSArray>(o)) goto CastError;
// Bailout if receiver has slow elements.
const map: Map = o.map;
const elementsKind: ElementsKind = LoadMapElementsKind(map);
if (!IsElementsKindLessThanOrEqual(
elementsKind, ElementsKind::LAST_ANY_NONEXTENSIBLE_ELEMENTS_KIND))
......
......@@ -16,7 +16,7 @@ ProxyDeleteProperty(implicit context: Context)(
PerformStackCheck();
// 1. Assert: IsPropertyKey(P) is true.
assert(TaggedIsNotSmi(name));
assert(IsName(name));
assert(Is<Name>(name));
assert(!IsPrivateSymbol(name));
try {
......
......@@ -18,7 +18,7 @@ ProxyGetProperty(implicit context: Context)(
PerformStackCheck();
// 1. Assert: IsPropertyKey(P) is true.
assert(TaggedIsNotSmi(name));
assert(IsName(name));
assert(Is<Name>(name));
assert(!IsPrivateSymbol(name));
// 2. Let handler be O.[[ProxyHandler]].
......
......@@ -10,12 +10,12 @@ namespace proxy {
// https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p
transitioning builtin ProxyHasProperty(implicit context: Context)(
proxy: JSProxy, name: PropertyKey): JSAny {
assert(IsJSProxy(proxy));
assert(Is<JSProxy>(proxy));
PerformStackCheck();
// 1. Assert: IsPropertyKey(P) is true.
assert(IsName(name));
assert(Is<Name>(name));
assert(!IsPrivateSymbol(name));
try {
......
......@@ -23,7 +23,7 @@ ProxySetProperty(implicit context: Context)(
receiverValue: JSAny): JSAny {
// 1. Assert: IsPropertyKey(P) is true.
assert(TaggedIsNotSmi(name));
assert(IsName(name));
assert(Is<Name>(name));
let key: PropertyKey;
typeswitch (name) {
......
......@@ -5635,14 +5635,6 @@ TNode<BoolT> CodeStubAssembler::IsCallableMap(SloppyTNode<Map> map) {
return IsSetWord32<Map::Bits1::IsCallableBit>(LoadMapBitField(map));
}
TNode<BoolT> CodeStubAssembler::IsCoverageInfo(TNode<HeapObject> object) {
return IsCoverageInfoMap(LoadMap(object));
}
TNode<BoolT> CodeStubAssembler::IsDebugInfo(TNode<HeapObject> object) {
return HasInstanceType(object, DEBUG_INFO_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsDeprecatedMap(SloppyTNode<Map> map) {
CSA_ASSERT(this, IsMap(map));
return IsSetWord32<Map::Bits3::IsDeprecatedBit>(LoadMapBitField3(map));
......@@ -5774,14 +5766,6 @@ TNode<BoolT> CodeStubAssembler::IsCallable(SloppyTNode<HeapObject> object) {
return IsCallableMap(LoadMap(object));
}
TNode<BoolT> CodeStubAssembler::IsCell(SloppyTNode<HeapObject> object) {
return TaggedEqual(LoadMap(object), CellMapConstant());
}
TNode<BoolT> CodeStubAssembler::IsCode(SloppyTNode<HeapObject> object) {
return HasInstanceType(object, CODE_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsConstructorMap(SloppyTNode<Map> map) {
CSA_ASSERT(this, IsMap(map));
return IsSetWord32<Map::Bits1::IsConstructorBit>(LoadMapBitField(map));
......@@ -5996,13 +5980,6 @@ TNode<BoolT> CodeStubAssembler::IsJSAsyncGeneratorObject(
return HasInstanceType(object, JS_ASYNC_GENERATOR_OBJECT_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsContext(SloppyTNode<HeapObject> object) {
TNode<Uint16T> instance_type = LoadInstanceType(object);
return UncheckedCast<BoolT>(Word32And(
Int32GreaterThanOrEqual(instance_type, Int32Constant(FIRST_CONTEXT_TYPE)),
Int32LessThanOrEqual(instance_type, Int32Constant(LAST_CONTEXT_TYPE))));
}
TNode<BoolT> CodeStubAssembler::IsFixedArray(SloppyTNode<HeapObject> object) {
return HasInstanceType(object, FIXED_ARRAY_TYPE);
}
......@@ -6026,21 +6003,11 @@ TNode<BoolT> CodeStubAssembler::IsNotWeakFixedArraySubclass(
Int32Constant(LAST_WEAK_FIXED_ARRAY_TYPE))));
}
TNode<BoolT> CodeStubAssembler::IsPromiseCapability(
SloppyTNode<HeapObject> object) {
return HasInstanceType(object, PROMISE_CAPABILITY_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsPropertyArray(
SloppyTNode<HeapObject> object) {
return HasInstanceType(object, PROPERTY_ARRAY_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsPromiseReaction(
SloppyTNode<HeapObject> object) {
return HasInstanceType(object, PROMISE_REACTION_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsPromiseReactionJobTask(
TNode<HeapObject> object) {
TNode<Uint16T> instance_type = LoadInstanceType(object);
......@@ -6048,16 +6015,6 @@ TNode<BoolT> CodeStubAssembler::IsPromiseReactionJobTask(
LAST_PROMISE_REACTION_JOB_TASK_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsPromiseRejectReactionJobTask(
SloppyTNode<HeapObject> object) {
return HasInstanceType(object, PROMISE_REJECT_REACTION_JOB_TASK_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsPromiseFulfillReactionJobTask(
SloppyTNode<HeapObject> object) {
return HasInstanceType(object, PROMISE_FULFILL_REACTION_JOB_TASK_TYPE);
}
// This complicated check is due to elements oddities. If a smi array is empty
// after Array.p.shift, it is replaced by the empty array constant. If it is
// later filled with a double element, we try to grow it but pass in a double
......@@ -6103,18 +6060,6 @@ TNode<BoolT> CodeStubAssembler::IsPropertyCell(SloppyTNode<HeapObject> object) {
return IsPropertyCellMap(LoadMap(object));
}
TNode<BoolT> CodeStubAssembler::IsAccessorInfo(SloppyTNode<HeapObject> object) {
return IsAccessorInfoMap(LoadMap(object));
}
TNode<BoolT> CodeStubAssembler::IsAccessorPair(SloppyTNode<HeapObject> object) {
return IsAccessorPairMap(LoadMap(object));
}
TNode<BoolT> CodeStubAssembler::IsHeapNumber(SloppyTNode<HeapObject> object) {
return IsHeapNumberMap(LoadMap(object));
}
TNode<BoolT> CodeStubAssembler::IsHeapNumberInstanceType(
SloppyTNode<Int32T> instance_type) {
return InstanceTypeEqual(instance_type, HEAP_NUMBER_TYPE);
......@@ -6129,15 +6074,6 @@ TNode<BoolT> CodeStubAssembler::IsOddballInstanceType(
return InstanceTypeEqual(instance_type, ODDBALL_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsFeedbackCell(SloppyTNode<HeapObject> object) {
return HasInstanceType(object, FEEDBACK_CELL_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsFeedbackVector(
SloppyTNode<HeapObject> object) {
return IsFeedbackVectorMap(LoadMap(object));
}
TNode<BoolT> CodeStubAssembler::IsName(SloppyTNode<HeapObject> object) {
return IsNameInstanceType(LoadInstanceType(object));
}
......@@ -6156,10 +6092,6 @@ TNode<BoolT> CodeStubAssembler::IsSymbolInstanceType(
return InstanceTypeEqual(instance_type, SYMBOL_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsSymbol(SloppyTNode<HeapObject> object) {
return IsSymbolMap(LoadMap(object));
}
TNode<BoolT> CodeStubAssembler::IsInternalizedStringInstanceType(
TNode<Int32T> instance_type) {
STATIC_ASSERT(kNotInternalizedTag != 0);
......@@ -6225,34 +6157,11 @@ TNode<BoolT> CodeStubAssembler::IsPrimitiveInstanceType(
Int32Constant(LAST_PRIMITIVE_HEAP_OBJECT_TYPE));
}
TNode<BoolT> CodeStubAssembler::IsPrivateSymbol(
SloppyTNode<HeapObject> object) {
return Select<BoolT>(
IsSymbol(object),
[=] {
TNode<Symbol> symbol = CAST(object);
TNode<Uint32T> flags =
LoadObjectField<Uint32T>(symbol, Symbol::kFlagsOffset);
return IsSetWord32<Symbol::IsPrivateBit>(flags);
},
[=] { return Int32FalseConstant(); });
}
TNode<BoolT> CodeStubAssembler::IsPrivateName(SloppyTNode<Symbol> symbol) {
TNode<Uint32T> flags = LoadObjectField<Uint32T>(symbol, Symbol::kFlagsOffset);
return IsSetWord32<Symbol::IsPrivateNameBit>(flags);
}
TNode<BoolT> CodeStubAssembler::IsNativeContext(
SloppyTNode<HeapObject> object) {
return HasInstanceType(object, NATIVE_CONTEXT_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsFixedDoubleArray(
SloppyTNode<HeapObject> object) {
return TaggedEqual(LoadMap(object), FixedDoubleArrayMapConstant());
}
TNode<BoolT> CodeStubAssembler::IsHashTable(SloppyTNode<HeapObject> object) {
TNode<Uint16T> instance_type = LoadInstanceType(object);
return UncheckedCast<BoolT>(
......@@ -6330,12 +6239,6 @@ TNode<BoolT> CodeStubAssembler::IsJSRegExp(SloppyTNode<HeapObject> object) {
return HasInstanceType(object, JS_REG_EXP_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsNumber(SloppyTNode<Object> object) {
return Select<BoolT>(
TaggedIsSmi(object), [=] { return Int32TrueConstant(); },
[=] { return IsHeapNumber(CAST(object)); });
}
TNode<BoolT> CodeStubAssembler::IsNumeric(SloppyTNode<Object> object) {
return Select<BoolT>(
TaggedIsSmi(object), [=] { return Int32TrueConstant(); },
......@@ -9663,7 +9566,7 @@ Node* CodeStubAssembler::PrepareValueForWriteToTypedArray(
// We can handle both HeapNumber and Oddball here, since Oddball has the
// same layout as the HeapNumber for the HeapNumber::value field. This
// way we can also properly optimize stores of oddballs to typed arrays.
GotoIf(IsHeapNumber(var_input.value()), &if_heapnumber_or_oddball);
GotoIf(IsHeapNumber(CAST(var_input.value())), &if_heapnumber_or_oddball);
STATIC_ASSERT_FIELD_OFFSETS_EQUAL(HeapNumber::kValueOffset,
Oddball::kToNumberRawOffset);
Branch(HasInstanceType(var_input.value(), ODDBALL_TYPE),
......
This diff is collapsed.
......@@ -245,7 +245,44 @@ TYPED_ARRAYS(TYPED_ARRAY_IS_TYPE_FUNCTION_DECL)
// This list must contain only maps that are shared by all objects of their
// instance type.
#define UNIQUE_INSTANCE_TYPE_MAP_LIST_GENERATOR(V, _) \
#define UNIQUE_INSTANCE_TYPE_MAP_LIST_GENERATOR(V, _) \
V(_, AccessorInfoMap, accessor_info_map, AccessorInfo) \
V(_, AccessorPairMap, accessor_pair_map, AccessorPair) \
V(_, AllocationMementoMap, allocation_memento_map, AllocationMemento) \
V(_, ArrayBoilerplateDescriptionMap, array_boilerplate_description_map, \
ArrayBoilerplateDescription) \
V(_, BreakPointMap, break_point_map, BreakPoint) \
V(_, BreakPointInfoMap, break_point_info_map, BreakPointInfo) \
V(_, CachedTemplateObjectMap, cached_template_object_map, \
CachedTemplateObject) \
V(_, CellMap, cell_map, Cell) \
V(_, CodeMap, code_map, Code) \
V(_, CoverageInfoMap, coverage_info_map, CoverageInfo) \
V(_, DebugInfoMap, debug_info_map, DebugInfo) \
V(_, FeedbackVectorMap, feedback_vector_map, FeedbackVector) \
V(_, FixedDoubleArrayMap, fixed_double_array_map, FixedDoubleArray) \
V(_, FunctionTemplateInfoMap, function_template_info_map, \
FunctionTemplateInfo) \
V(_, HeapNumberMap, heap_number_map, HeapNumber) \
V(_, MetaMap, meta_map, Map) \
V(_, PreparseDataMap, preparse_data_map, PreparseData) \
V(_, PrototypeInfoMap, prototype_info_map, PrototypeInfo) \
V(_, SharedFunctionInfoMap, shared_function_info_map, SharedFunctionInfo) \
V(_, SmallOrderedHashSetMap, small_ordered_hash_set_map, \
SmallOrderedHashSet) \
V(_, SmallOrderedHashMapMap, small_ordered_hash_map_map, \
SmallOrderedHashMap) \
V(_, SmallOrderedNameDictionaryMap, small_ordered_name_dictionary_map, \
SmallOrderedNameDictionary) \
V(_, SymbolMap, symbol_map, Symbol) \
V(_, TransitionArrayMap, transition_array_map, TransitionArray) \
V(_, Tuple2Map, tuple2_map, Tuple2) \
V(_, UncompiledDataWithoutPreparseDataMap, \
uncompiled_data_without_preparse_data_map, \
UncompiledDataWithoutPreparseData) \
V(_, UncompiledDataWithPreparseDataMap, \
uncompiled_data_with_preparse_data_map, UncompiledDataWithPreparseData) \
V(_, WeakFixedArrayMap, weak_fixed_array_map, WeakFixedArray) \
TORQUE_DEFINED_MAP_CSA_LIST_GENERATOR(V, _)
} // namespace internal
......
......@@ -2418,7 +2418,7 @@ TEST(IsSymbol) {
CodeAssemblerTester asm_tester(isolate, kNumParams);
CodeStubAssembler m(asm_tester.state());
Node* const symbol = m.Parameter(0);
TNode<HeapObject> const symbol = m.CAST(m.Parameter(0));
m.Return(m.SelectBooleanConstant(m.IsSymbol(symbol)));
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
......@@ -2437,7 +2437,7 @@ TEST(IsPrivateSymbol) {
CodeAssemblerTester asm_tester(isolate, kNumParams);
CodeStubAssembler m(asm_tester.state());
Node* const symbol = m.Parameter(0);
TNode<HeapObject> const symbol = m.CAST(m.Parameter(0));
m.Return(m.SelectBooleanConstant(m.IsPrivateSymbol(symbol)));
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment