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) {
TypedArrayBuiltinsAssembler typedarray_asm(state());
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
// performed in TypedArraySpeciesCreate.
CSA_ASSERT(this,
......@@ -817,9 +817,9 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) {
// Respect the ElementsKind of the input array.
TNode<Int32T> elements_kind = LoadMapElementsKind(original_map);
GotoIfNot(IsFastElementsKind(elements_kind), &runtime);
TNode<Context> native_context = CAST(LoadNativeContext(context()));
TNode<Context> native_context = LoadNativeContext(context());
TNode<Map> array_map =
CAST(LoadJSArrayElementsMap(elements_kind, native_context));
LoadJSArrayElementsMap(elements_kind, native_context);
TNode<JSArray> array =
CAST(AllocateJSArray(GetInitialFastElementsKind(), array_map, len, len,
nullptr, CodeStubAssembler::SMI_PARAMETERS));
......@@ -868,9 +868,9 @@ Node* ArrayBuiltinsAssembler::FindProcessor(Node* k_value, Node* k) {
// element in the input array (maybe the callback deletes an element).
const ElementsKind elements_kind =
GetHoleyElementsKind(GetInitialFastElementsKind());
TNode<Context> native_context = CAST(LoadNativeContext(context()));
TNode<Context> native_context = LoadNativeContext(context());
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,
CodeStubAssembler::SMI_PARAMETERS));
......@@ -1358,7 +1358,7 @@ TF_BUILTIN(ArrayPrototypeSlice, ArrayPrototypeSliceCodeStubAssembler) {
// 5. Let relativeStart be ToInteger(start).
// 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);
// 7. If relativeStart < 0, let k be max((len + relativeStart),0);
......@@ -1377,8 +1377,7 @@ TF_BUILTIN(ArrayPrototypeSlice, ArrayPrototypeSliceCodeStubAssembler) {
// 8. If end is undefined, let relativeEnd be len;
// else let relativeEnd be ToInteger(end).
// 9. ReturnIfAbrupt(relativeEnd).
TNode<Object> end =
CAST(args.GetOptionalArgumentValue(1, UndefinedConstant()));
TNode<Object> end = args.GetOptionalArgumentValue(1, UndefinedConstant());
Label end_undefined(this), end_done(this);
VARIABLE(relative_end, MachineRepresentation::kTagged);
GotoIf(WordEqual(end, UndefinedConstant()), &end_undefined);
......
......@@ -394,7 +394,7 @@ TNode<Object> BaseCollectionsAssembler::GetAddFunction(
HeapConstant(add_func_name), collection);
BIND(&exit);
return CAST(add_func);
return add_func;
}
TNode<JSFunction> BaseCollectionsAssembler::GetConstructor(
......
......@@ -887,8 +887,8 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
// Enter the context of the {microtask}.
TNode<Context> microtask_context =
LoadObjectField<Context>(microtask, CallableTask::kContextOffset);
TNode<Context> native_context =
TNode<Context>::UncheckedCast(LoadNativeContext(microtask_context));
TNode<Context> native_context = LoadNativeContext(microtask_context);
CSA_ASSERT(this, IsNativeContext(native_context));
EnterMicrotaskContext(microtask_context);
SetCurrentContext(native_context);
......@@ -931,8 +931,7 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
// Enter the context of the {microtask}.
TNode<Context> microtask_context = LoadObjectField<Context>(
microtask, PromiseResolveThenableJobTask::kContextOffset);
TNode<Context> native_context =
TNode<Context>::UncheckedCast(LoadNativeContext(microtask_context));
TNode<Context> native_context = LoadNativeContext(microtask_context);
CSA_ASSERT(this, IsNativeContext(native_context));
EnterMicrotaskContext(microtask_context);
SetCurrentContext(native_context);
......@@ -958,8 +957,7 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
// Enter the context of the {microtask}.
TNode<Context> microtask_context = LoadObjectField<Context>(
microtask, PromiseReactionJobTask::kContextOffset);
TNode<Context> native_context =
TNode<Context>::UncheckedCast(LoadNativeContext(microtask_context));
TNode<Context> native_context = LoadNativeContext(microtask_context);
CSA_ASSERT(this, IsNativeContext(native_context));
EnterMicrotaskContext(microtask_context);
SetCurrentContext(native_context);
......@@ -992,8 +990,7 @@ TF_BUILTIN(RunMicrotasks, InternalBuiltinsAssembler) {
// Enter the context of the {microtask}.
TNode<Context> microtask_context = LoadObjectField<Context>(
microtask, PromiseReactionJobTask::kContextOffset);
TNode<Context> native_context =
TNode<Context>::UncheckedCast(LoadNativeContext(microtask_context));
TNode<Context> native_context = LoadNativeContext(microtask_context);
CSA_ASSERT(this, IsNativeContext(native_context));
EnterMicrotaskContext(microtask_context);
SetCurrentContext(native_context);
......
......@@ -1659,7 +1659,7 @@ TF_BUILTIN(StringPrototypeSlice, StringBuiltinsAssembler) {
CodeStubArguments args(this, argc);
Node* const receiver = args.GetReceiver();
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));
// 1. Let O be ? RequireObjectCoercible(this value).
......@@ -1808,7 +1808,7 @@ TF_BUILTIN(StringPrototypeSubstr, StringBuiltinsAssembler) {
Node* const receiver = args.GetReceiver();
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));
Label out(this);
......
......@@ -415,8 +415,8 @@ void TypedArrayBuiltinsAssembler::ConstructByArrayBuffer(
BIND(&call_init);
{
TNode<Object> raw_length = CAST(CallBuiltin(
Builtins::kDivide, context, new_byte_length.value(), element_size));
TNode<Object> raw_length = CallBuiltin(
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.
TNode<Smi> new_length = ToSmiIndex(raw_length, context, &invalid_length);
......@@ -651,9 +651,9 @@ TF_BUILTIN(TypedArrayConstructor_ConstructStub, TypedArrayBuiltinsAssembler) {
Node* argc =
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
CodeStubArguments args(this, argc);
TNode<Object> arg1 = CAST(args.GetOptionalArgumentValue(0));
TNode<Object> arg2 = CAST(args.GetOptionalArgumentValue(1));
TNode<Object> arg3 = CAST(args.GetOptionalArgumentValue(2));
TNode<Object> arg1 = args.GetOptionalArgumentValue(0);
TNode<Object> arg2 = args.GetOptionalArgumentValue(1);
TNode<Object> arg3 = args.GetOptionalArgumentValue(2);
TNode<Context> context = CAST(Parameter(BuiltinDescriptor::kContext));
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
......@@ -1740,7 +1740,7 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) {
BIND(&from_array_like);
{
Label if_length_not_smi(this, Label::kDeferred);
final_source = CAST(source);
final_source = source;
// 10. Let len be ? ToLength(? Get(arrayLike, "length")).
TNode<Object> raw_length =
......
......@@ -1436,7 +1436,7 @@ TNode<FixedArrayBase> CodeStubAssembler::LoadElements(
TNode<Object> CodeStubAssembler::LoadJSArrayLength(SloppyTNode<JSArray> array) {
CSA_ASSERT(this, IsJSArray(array));
return CAST(LoadObjectField(array, JSArray::kLengthOffset));
return LoadObjectField(array, JSArray::kLengthOffset);
}
TNode<Smi> CodeStubAssembler::LoadFastJSArrayLength(
......@@ -1495,7 +1495,7 @@ TNode<DescriptorArray> CodeStubAssembler::LoadMapDescriptors(
TNode<Object> CodeStubAssembler::LoadMapPrototype(SloppyTNode<Map> map) {
CSA_SLOW_ASSERT(this, IsMap(map));
return CAST(LoadObjectField(map, Map::kPrototypeOffset));
return LoadObjectField(map, Map::kPrototypeOffset);
}
TNode<PrototypeInfo> CodeStubAssembler::LoadMapPrototypeInfo(
......
......@@ -554,7 +554,7 @@ class V8_EXPORT_PRIVATE CodeAssembler {
// Base Assembler
// ===========================================================================
template <class PreviousType>
template <class PreviousType, bool FromTyped>
class CheckedNode {
public:
#ifdef DEBUG
......@@ -572,6 +572,10 @@ class V8_EXPORT_PRIVATE CodeAssembler {
static_assert(std::is_convertible<TNode<A>, TNode<Object>>::value,
"Coercion to untagged values cannot be "
"checked.");
static_assert(
!FromTyped ||
!std::is_convertible<TNode<PreviousType>, TNode<A>>::value,
"Unnecessary CAST: types are convertible.");
#ifdef DEBUG
if (FLAG_debug_code) {
Node* function = code_assembler_->ExternalConstant(
......@@ -621,13 +625,13 @@ class V8_EXPORT_PRIVATE CodeAssembler {
return TNode<T>::UncheckedCast(value);
}
CheckedNode<Object> Cast(Node* value, const char* location) {
return CheckedNode<Object>(value, this, location);
CheckedNode<Object, false> Cast(Node* value, const char* location) {
return {value, this, location};
}
template <class T>
CheckedNode<T> Cast(TNode<T> value, const char* location) {
return CheckedNode<T>(value, this, location);
CheckedNode<T, true> Cast(TNode<T> value, const char* location) {
return {value, this, location};
}
#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