Commit 1e42a05a authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[sparkplug] Collect feedback for ToNumber/ToNumeric

Add (ToNumber|ToNumeric)_Baseline builtins which get the feedback vector
and context from the stack, perform ToNumber/ToNumeric, and update
feedback. These share C++ code with Builtins::kToNumber, but don't call
it directly, as they need to collect feedback as part of the conversion.

Bug: v8:11420, v8:11429
Change-Id: Idca1281004ec27096cbe9204653fdd72386ab52b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2692573
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72746}
parent 0b16593d
......@@ -1656,13 +1656,13 @@ void BaselineCompiler::VisitToName() {
}
void BaselineCompiler::VisitToNumber() {
// TODO(v8:11429,leszeks): Record feedback.
CallBuiltin(Builtins::kToNumber, kInterpreterAccumulatorRegister);
CallBuiltin(Builtins::kToNumber_Baseline, kInterpreterAccumulatorRegister,
Index(0));
}
void BaselineCompiler::VisitToNumeric() {
// TODO(v8:11429,leszeks): Record feedback.
CallBuiltin(Builtins::kToNumeric, kInterpreterAccumulatorRegister);
CallBuiltin(Builtins::kToNumeric_Baseline, kInterpreterAccumulatorRegister,
Index(0));
}
void BaselineCompiler::VisitToObject() {
......
......@@ -6,6 +6,7 @@
#include "src/builtins/builtins.h"
#include "src/codegen/code-factory.h"
#include "src/codegen/code-stub-assembler.h"
#include "src/codegen/tnode.h"
#include "src/objects/objects-inl.h"
#include "src/objects/oddball.h"
......@@ -20,6 +21,34 @@ TF_BUILTIN(ToNumber, CodeStubAssembler) {
Return(ToNumber(context, input));
}
TF_BUILTIN(ToNumber_Baseline, CodeStubAssembler) {
auto input = Parameter<Object>(Descriptor::kArgument);
auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
auto context = [this] { return LoadContextFromBaseline(); };
TVARIABLE(Smi, var_type_feedback);
TNode<Number> result = CAST(ToNumberOrNumeric(
context, input, &var_type_feedback, Object::Conversion::kToNumber));
auto feedback_vector = LoadFeedbackVectorFromBaseline();
UpdateFeedback(var_type_feedback.value(), feedback_vector, slot);
Return(result);
}
TF_BUILTIN(ToNumeric_Baseline, CodeStubAssembler) {
auto input = Parameter<Object>(Descriptor::kArgument);
auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
auto context = [this] { return LoadContextFromBaseline(); };
TVARIABLE(Smi, var_type_feedback);
TNode<Number> result = CAST(ToNumberOrNumeric(
context, input, &var_type_feedback, Object::Conversion::kToNumeric));
auto feedback_vector = LoadFeedbackVectorFromBaseline();
UpdateFeedback(var_type_feedback.value(), feedback_vector, slot);
Return(result);
}
TF_BUILTIN(PlainPrimitiveToNumber, CodeStubAssembler) {
auto input = Parameter<Object>(Descriptor::kArgument);
......
......@@ -202,6 +202,8 @@ namespace internal {
\
/* Type conversions */ \
TFC(ToNumber, TypeConversion) \
TFC(ToNumber_Baseline, TypeConversion_Baseline) \
TFC(ToNumeric_Baseline, TypeConversion_Baseline) \
TFC(PlainPrimitiveToNumber, TypeConversionNoContext) \
TFC(ToNumberConvertBigInt, TypeConversion) \
TFC(Typeof, Typeof) \
......
......@@ -7131,6 +7131,14 @@ TNode<Numeric> CodeStubAssembler::NonNumberToNumeric(TNode<Context> context,
Object::Conversion::kToNumeric);
}
TNode<Number> CodeStubAssembler::ToNumber(TNode<Context> context,
TNode<Object> input,
BigIntHandling bigint_handling) {
return CAST(ToNumberOrNumeric([context] { return context; }, input, nullptr,
Object::Conversion::kToNumber,
bigint_handling));
}
TNode<Number> CodeStubAssembler::ToNumber_Inline(TNode<Context> context,
SloppyTNode<Object> input) {
TVARIABLE(Number, var_result);
......@@ -7155,16 +7163,20 @@ TNode<Number> CodeStubAssembler::ToNumber_Inline(TNode<Context> context,
return var_result.value();
}
TNode<Number> CodeStubAssembler::ToNumber(TNode<Context> context,
SloppyTNode<Object> input,
BigIntHandling bigint_handling) {
TVARIABLE(Number, var_result);
TNode<Numeric> CodeStubAssembler::ToNumberOrNumeric(
LazyNode<Context> context, TNode<Object> input,
TVariable<Smi>* var_type_feedback, Object::Conversion mode,
BigIntHandling bigint_handling) {
TVARIABLE(Numeric, var_result);
Label end(this);
Label not_smi(this, Label::kDeferred);
GotoIfNot(TaggedIsSmi(input), &not_smi);
TNode<Smi> input_smi = CAST(input);
var_result = input_smi;
if (var_type_feedback) {
*var_type_feedback = SmiConstant(BinaryOperationFeedback::kSignedSmall);
}
Goto(&end);
BIND(&not_smi);
......@@ -7175,11 +7187,29 @@ TNode<Number> CodeStubAssembler::ToNumber(TNode<Context> context,
TNode<HeapNumber> input_hn = CAST(input_ho);
var_result = input_hn;
if (var_type_feedback) {
*var_type_feedback = SmiConstant(BinaryOperationFeedback::kNumber);
}
Goto(&end);
BIND(&not_heap_number);
{
var_result = NonNumberToNumber(context, input_ho, bigint_handling);
if (mode == Object::Conversion::kToNumeric) {
// Special case for collecting BigInt feedback.
Label not_bigint(this);
GotoIfNot(IsBigInt(input_ho), &not_bigint);
{
var_result = CAST(input_ho);
*var_type_feedback = SmiConstant(BinaryOperationFeedback::kBigInt);
Goto(&end);
}
BIND(&not_bigint);
}
var_result = NonNumberToNumberOrNumeric(context(), input_ho, mode,
bigint_handling);
if (var_type_feedback) {
*var_type_feedback = SmiConstant(BinaryOperationFeedback::kAny);
}
Goto(&end);
}
}
......
......@@ -2563,10 +2563,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
// With {bigint_handling} == kConvertToNumber, matches behavior of
// tc39.github.io/proposal-bigint/#sec-number-constructor-number-value.
TNode<Number> ToNumber(
TNode<Context> context, SloppyTNode<Object> input,
TNode<Context> context, TNode<Object> input,
BigIntHandling bigint_handling = BigIntHandling::kThrow);
TNode<Number> ToNumber_Inline(TNode<Context> context,
SloppyTNode<Object> input);
TNode<Numeric> ToNumberOrNumeric(
LazyNode<Context> context, TNode<Object> input,
TVariable<Smi>* var_type_feedback, Object::Conversion mode,
BigIntHandling bigint_handling = BigIntHandling::kThrow);
// Convert any plain primitive to a Number. No need to handle BigInts since
// they are not plain primitives.
TNode<Number> PlainPrimitiveToNumber(TNode<Object> input);
......
......@@ -382,6 +382,11 @@ void TypeConversionNoContextDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void TypeConversion_BaselineDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
DefaultInitializePlatformSpecific(data, kParameterCount);
}
void SingleParameterOnStackDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
data->InitializePlatformSpecific(0, nullptr);
......
......@@ -112,6 +112,7 @@ namespace internal {
V(StringSubstring) \
V(TypeConversion) \
V(TypeConversionNoContext) \
V(TypeConversion_Baseline) \
V(Typeof) \
V(UnaryOp_Baseline) \
V(UnaryOp_WithFeedback) \
......@@ -1048,6 +1049,13 @@ class TypeConversionNoContextDescriptor final : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(TypeConversionNoContextDescriptor, CallInterfaceDescriptor)
};
class TypeConversion_BaselineDescriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS_NO_CONTEXT(kArgument, kSlot)
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), MachineType::UintPtr())
DECLARE_DESCRIPTOR(TypeConversion_BaselineDescriptor, CallInterfaceDescriptor)
};
class SingleParameterOnStackDescriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kArgument)
......
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