Commit 7cbf9f84 authored by Peter Marshall's avatar Peter Marshall Committed by Commit Bot

[CSA] Add a static assert to find unnecessary CAST calls.

This will fire if the CAST is never useful. This is helpful if you add
a TNode return type to a function - its callers no longer need to cast
the result if the types are the same.

Change-Id: If0b04c615cb2dbfa91ba43d5d0d35ace5a31d4e7
Reviewed-on: https://chromium-review.googlesource.com/934449Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51599}
parent 8c123486
...@@ -208,7 +208,7 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) { ...@@ -208,7 +208,7 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) {
TypedArrayBuiltinsAssembler typedarray_asm(state()); TypedArrayBuiltinsAssembler typedarray_asm(state());
TNode<JSTypedArray> a = typedarray_asm.SpeciesCreateByLength( TNode<JSTypedArray> a = typedarray_asm.SpeciesCreateByLength(
CAST(context()), original_array, length, method_name); context(), original_array, length, method_name);
// In the Spec and our current implementation, the length check is already // In the Spec and our current implementation, the length check is already
// performed in TypedArraySpeciesCreate. // performed in TypedArraySpeciesCreate.
CSA_ASSERT(this, CSA_ASSERT(this,
...@@ -817,9 +817,9 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) { ...@@ -817,9 +817,9 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) {
// Respect the ElementsKind of the input array. // Respect the ElementsKind of the input array.
TNode<Int32T> elements_kind = LoadMapElementsKind(original_map); TNode<Int32T> elements_kind = LoadMapElementsKind(original_map);
GotoIfNot(IsFastElementsKind(elements_kind), &runtime); GotoIfNot(IsFastElementsKind(elements_kind), &runtime);
TNode<Context> native_context = CAST(LoadNativeContext(context())); TNode<Context> native_context = LoadNativeContext(context());
TNode<Map> array_map = TNode<Map> array_map =
CAST(LoadJSArrayElementsMap(elements_kind, native_context)); LoadJSArrayElementsMap(elements_kind, native_context);
TNode<JSArray> array = TNode<JSArray> array =
CAST(AllocateJSArray(GetInitialFastElementsKind(), array_map, len, len, CAST(AllocateJSArray(GetInitialFastElementsKind(), array_map, len, len,
nullptr, CodeStubAssembler::SMI_PARAMETERS)); nullptr, CodeStubAssembler::SMI_PARAMETERS));
...@@ -868,9 +868,9 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) { ...@@ -868,9 +868,9 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) {
// element in the input array (maybe the callback deletes an element). // element in the input array (maybe the callback deletes an element).
const ElementsKind elements_kind = const ElementsKind elements_kind =
GetHoleyElementsKind(GetInitialFastElementsKind()); GetHoleyElementsKind(GetInitialFastElementsKind());
TNode<Context> native_context = CAST(LoadNativeContext(context())); TNode<Context> native_context = LoadNativeContext(context());
TNode<Map> array_map = TNode<Map> array_map =
CAST(LoadJSArrayElementsMap(elements_kind, native_context)); LoadJSArrayElementsMap(elements_kind, native_context);
a_.Bind(AllocateJSArray(PACKED_SMI_ELEMENTS, array_map, len, len, nullptr, a_.Bind(AllocateJSArray(PACKED_SMI_ELEMENTS, array_map, len, len, nullptr,
CodeStubAssembler::SMI_PARAMETERS)); CodeStubAssembler::SMI_PARAMETERS));
...@@ -1358,7 +1358,7 @@ TF_BUILTIN(ArrayPrototypeSlice, ArrayPrototypeSliceCodeStubAssembler) { ...@@ -1358,7 +1358,7 @@ TF_BUILTIN(ArrayPrototypeSlice, ArrayPrototypeSliceCodeStubAssembler) {
// 5. Let relativeStart be ToInteger(start). // 5. Let relativeStart be ToInteger(start).
// 6. ReturnIfAbrupt(relativeStart). // 6. ReturnIfAbrupt(relativeStart).
TNode<Object> arg0 = CAST(args.GetOptionalArgumentValue(0, SmiConstant(0))); TNode<Object> arg0 = args.GetOptionalArgumentValue(0, SmiConstant(0));
Node* relative_start = ToInteger_Inline(context, arg0); Node* relative_start = ToInteger_Inline(context, arg0);
// 7. If relativeStart < 0, let k be max((len + relativeStart),0); // 7. If relativeStart < 0, let k be max((len + relativeStart),0);
...@@ -1377,8 +1377,7 @@ TF_BUILTIN(ArrayPrototypeSlice, ArrayPrototypeSliceCodeStubAssembler) { ...@@ -1377,8 +1377,7 @@ TF_BUILTIN(ArrayPrototypeSlice, ArrayPrototypeSliceCodeStubAssembler) {
// 8. If end is undefined, let relativeEnd be len; // 8. If end is undefined, let relativeEnd be len;
// else let relativeEnd be ToInteger(end). // else let relativeEnd be ToInteger(end).
// 9. ReturnIfAbrupt(relativeEnd). // 9. ReturnIfAbrupt(relativeEnd).
TNode<Object> end = TNode<Object> end = args.GetOptionalArgumentValue(1, UndefinedConstant());
CAST(args.GetOptionalArgumentValue(1, UndefinedConstant()));
Label end_undefined(this), end_done(this); Label end_undefined(this), end_done(this);
VARIABLE(relative_end, MachineRepresentation::kTagged); VARIABLE(relative_end, MachineRepresentation::kTagged);
GotoIf(WordEqual(end, UndefinedConstant()), &end_undefined); GotoIf(WordEqual(end, UndefinedConstant()), &end_undefined);
......
...@@ -394,7 +394,7 @@ TNode<Object> BaseCollectionsAssembler::GetAddFunction( ...@@ -394,7 +394,7 @@ TNode<Object> BaseCollectionsAssembler::GetAddFunction(
HeapConstant(add_func_name), collection); HeapConstant(add_func_name), collection);
BIND(&exit); BIND(&exit);
return CAST(add_func); return add_func;
} }
TNode<JSFunction> BaseCollectionsAssembler::GetConstructor( TNode<JSFunction> BaseCollectionsAssembler::GetConstructor(
......
...@@ -887,8 +887,8 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) { ...@@ -887,8 +887,8 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
// Enter the context of the {microtask}. // Enter the context of the {microtask}.
TNode<Context> microtask_context = TNode<Context> microtask_context =
LoadObjectField<Context>(microtask, CallableTask::kContextOffset); LoadObjectField<Context>(microtask, CallableTask::kContextOffset);
TNode<Context> native_context = TNode<Context> native_context = LoadNativeContext(microtask_context);
TNode<Context>::UncheckedCast(LoadNativeContext(microtask_context));
CSA_ASSERT(this, IsNativeContext(native_context)); CSA_ASSERT(this, IsNativeContext(native_context));
EnterMicrotaskContext(microtask_context); EnterMicrotaskContext(microtask_context);
SetCurrentContext(native_context); SetCurrentContext(native_context);
...@@ -931,8 +931,7 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) { ...@@ -931,8 +931,7 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
// Enter the context of the {microtask}. // Enter the context of the {microtask}.
TNode<Context> microtask_context = LoadObjectField<Context>( TNode<Context> microtask_context = LoadObjectField<Context>(
microtask, PromiseResolveThenableJobTask::kContextOffset); microtask, PromiseResolveThenableJobTask::kContextOffset);
TNode<Context> native_context = TNode<Context> native_context = LoadNativeContext(microtask_context);
TNode<Context>::UncheckedCast(LoadNativeContext(microtask_context));
CSA_ASSERT(this, IsNativeContext(native_context)); CSA_ASSERT(this, IsNativeContext(native_context));
EnterMicrotaskContext(microtask_context); EnterMicrotaskContext(microtask_context);
SetCurrentContext(native_context); SetCurrentContext(native_context);
...@@ -958,8 +957,7 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) { ...@@ -958,8 +957,7 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
// Enter the context of the {microtask}. // Enter the context of the {microtask}.
TNode<Context> microtask_context = LoadObjectField<Context>( TNode<Context> microtask_context = LoadObjectField<Context>(
microtask, PromiseReactionJobTask::kContextOffset); microtask, PromiseReactionJobTask::kContextOffset);
TNode<Context> native_context = TNode<Context> native_context = LoadNativeContext(microtask_context);
TNode<Context>::UncheckedCast(LoadNativeContext(microtask_context));
CSA_ASSERT(this, IsNativeContext(native_context)); CSA_ASSERT(this, IsNativeContext(native_context));
EnterMicrotaskContext(microtask_context); EnterMicrotaskContext(microtask_context);
SetCurrentContext(native_context); SetCurrentContext(native_context);
...@@ -992,8 +990,7 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) { ...@@ -992,8 +990,7 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
// Enter the context of the {microtask}. // Enter the context of the {microtask}.
TNode<Context> microtask_context = LoadObjectField<Context>( TNode<Context> microtask_context = LoadObjectField<Context>(
microtask, PromiseReactionJobTask::kContextOffset); microtask, PromiseReactionJobTask::kContextOffset);
TNode<Context> native_context = TNode<Context> native_context = LoadNativeContext(microtask_context);
TNode<Context>::UncheckedCast(LoadNativeContext(microtask_context));
CSA_ASSERT(this, IsNativeContext(native_context)); CSA_ASSERT(this, IsNativeContext(native_context));
EnterMicrotaskContext(microtask_context); EnterMicrotaskContext(microtask_context);
SetCurrentContext(native_context); SetCurrentContext(native_context);
......
...@@ -1659,7 +1659,7 @@ TF_BUILTIN(StringPrototypeSlice, StringBuiltinsAssembler) { ...@@ -1659,7 +1659,7 @@ TF_BUILTIN(StringPrototypeSlice, StringBuiltinsAssembler) {
CodeStubArguments args(this, argc); CodeStubArguments args(this, argc);
Node* const receiver = args.GetReceiver(); Node* const receiver = args.GetReceiver();
TNode<Object> start = args.GetOptionalArgumentValue(kStart); TNode<Object> start = args.GetOptionalArgumentValue(kStart);
TNode<Object> end = CAST(args.GetOptionalArgumentValue(kEnd)); TNode<Object> end = args.GetOptionalArgumentValue(kEnd);
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext)); TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
// 1. Let O be ? RequireObjectCoercible(this value). // 1. Let O be ? RequireObjectCoercible(this value).
...@@ -1808,7 +1808,7 @@ TF_BUILTIN(StringPrototypeSubstr, StringBuiltinsAssembler) { ...@@ -1808,7 +1808,7 @@ TF_BUILTIN(StringPrototypeSubstr, StringBuiltinsAssembler) {
Node* const receiver = args.GetReceiver(); Node* const receiver = args.GetReceiver();
TNode<Object> start = args.GetOptionalArgumentValue(kStartArg); TNode<Object> start = args.GetOptionalArgumentValue(kStartArg);
TNode<Object> length = CAST(args.GetOptionalArgumentValue(kLengthArg)); TNode<Object> length = args.GetOptionalArgumentValue(kLengthArg);
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext)); TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
Label out(this); Label out(this);
......
...@@ -415,8 +415,8 @@ void TypedArrayBuiltinsAssembler::ConstructByArrayBuffer( ...@@ -415,8 +415,8 @@ void TypedArrayBuiltinsAssembler::ConstructByArrayBuffer(
BIND(&call_init); BIND(&call_init);
{ {
TNode<Object> raw_length = CAST(CallBuiltin( TNode<Object> raw_length = CallBuiltin(
Builtins::kDivide, context, new_byte_length.value(), element_size)); Builtins::kDivide, context, new_byte_length.value(), element_size);
// Force the result into a Smi, or throw a range error if it doesn't fit. // Force the result into a Smi, or throw a range error if it doesn't fit.
TNode<Smi> new_length = ToSmiIndex(raw_length, context, &invalid_length); TNode<Smi> new_length = ToSmiIndex(raw_length, context, &invalid_length);
...@@ -651,9 +651,9 @@ TF_BUILTIN(TypedArrayConstructor_ConstructStub, TypedArrayBuiltinsAssembler) { ...@@ -651,9 +651,9 @@ TF_BUILTIN(TypedArrayConstructor_ConstructStub, TypedArrayBuiltinsAssembler) {
Node* argc = Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount)); ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc); CodeStubArguments args(this, argc);
TNode<Object> arg1 = CAST(args.GetOptionalArgumentValue(0)); TNode<Object> arg1 = args.GetOptionalArgumentValue(0);
TNode<Object> arg2 = CAST(args.GetOptionalArgumentValue(1)); TNode<Object> arg2 = args.GetOptionalArgumentValue(1);
TNode<Object> arg3 = CAST(args.GetOptionalArgumentValue(2)); TNode<Object> arg3 = args.GetOptionalArgumentValue(2);
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext)); TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset, Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
...@@ -1740,7 +1740,7 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) { ...@@ -1740,7 +1740,7 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) {
BIND(&from_array_like); BIND(&from_array_like);
{ {
Label if_length_not_smi(this, Label::kDeferred); Label if_length_not_smi(this, Label::kDeferred);
final_source = CAST(source); final_source = source;
// 10. Let len be ? ToLength(? Get(arrayLike, "length")). // 10. Let len be ? ToLength(? Get(arrayLike, "length")).
TNode<Object> raw_length = TNode<Object> raw_length =
......
...@@ -1436,7 +1436,7 @@ TNode<FixedArrayBase> CodeStubAssembler::LoadElements( ...@@ -1436,7 +1436,7 @@ TNode<FixedArrayBase> CodeStubAssembler::LoadElements(
TNode<Object> CodeStubAssembler::LoadJSArrayLength(SloppyTNode<JSArray> array) { TNode<Object> CodeStubAssembler::LoadJSArrayLength(SloppyTNode<JSArray> array) {
CSA_ASSERT(this, IsJSArray(array)); CSA_ASSERT(this, IsJSArray(array));
return CAST(LoadObjectField(array, JSArray::kLengthOffset)); return LoadObjectField(array, JSArray::kLengthOffset);
} }
TNode<Smi> CodeStubAssembler::LoadFastJSArrayLength( TNode<Smi> CodeStubAssembler::LoadFastJSArrayLength(
...@@ -1495,7 +1495,7 @@ TNode<DescriptorArray> CodeStubAssembler::LoadMapDescriptors( ...@@ -1495,7 +1495,7 @@ TNode<DescriptorArray> CodeStubAssembler::LoadMapDescriptors(
TNode<Object> CodeStubAssembler::LoadMapPrototype(SloppyTNode<Map> map) { TNode<Object> CodeStubAssembler::LoadMapPrototype(SloppyTNode<Map> map) {
CSA_SLOW_ASSERT(this, IsMap(map)); CSA_SLOW_ASSERT(this, IsMap(map));
return CAST(LoadObjectField(map, Map::kPrototypeOffset)); return LoadObjectField(map, Map::kPrototypeOffset);
} }
TNode<PrototypeInfo> CodeStubAssembler::LoadMapPrototypeInfo( TNode<PrototypeInfo> CodeStubAssembler::LoadMapPrototypeInfo(
......
...@@ -554,7 +554,7 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -554,7 +554,7 @@ class V8_EXPORT_PRIVATE CodeAssembler {
// Base Assembler // Base Assembler
// =========================================================================== // ===========================================================================
template <class PreviousType> template <class PreviousType, bool FromTyped>
class CheckedNode { class CheckedNode {
public: public:
#ifdef DEBUG #ifdef DEBUG
...@@ -572,6 +572,10 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -572,6 +572,10 @@ class V8_EXPORT_PRIVATE CodeAssembler {
static_assert(std::is_convertible<TNode<A>, TNode<Object>>::value, static_assert(std::is_convertible<TNode<A>, TNode<Object>>::value,
"Coercion to untagged values cannot be " "Coercion to untagged values cannot be "
"checked."); "checked.");
static_assert(
!FromTyped ||
!std::is_convertible<TNode<PreviousType>, TNode<A>>::value,
"Unnecessary CAST: types are convertible.");
#ifdef DEBUG #ifdef DEBUG
if (FLAG_debug_code) { if (FLAG_debug_code) {
Node* function = code_assembler_->ExternalConstant( Node* function = code_assembler_->ExternalConstant(
...@@ -621,13 +625,13 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -621,13 +625,13 @@ class V8_EXPORT_PRIVATE CodeAssembler {
return TNode<T>::UncheckedCast(value); return TNode<T>::UncheckedCast(value);
} }
CheckedNode<Object> Cast(Node* value, const char* location) { CheckedNode<Object, false> Cast(Node* value, const char* location) {
return CheckedNode<Object>(value, this, location); return {value, this, location};
} }
template <class T> template <class T>
CheckedNode<T> Cast(TNode<T> value, const char* location) { CheckedNode<T, true> Cast(TNode<T> value, const char* location) {
return CheckedNode<T>(value, this, location); return {value, this, location};
} }
#ifdef DEBUG #ifdef DEBUG
......
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