[CSA][cleanup] TNodify builtins numbers gen

TNodify related methods in CSA:
 * TaggedToWord32OrBigInt
 * TaggedToWord32OrBigIntWithFeedback
 * TaggedToWord32OrBigIntImpl

Remove Sloppy-ness in RelationalComparison

Bug: v8:6949
Change-Id: I970a40a424f6e8cdc45544eb79c95291a5a5a608
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1807362
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Mythri Alle <mythria@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63861}
This commit is contained in:
Santiago Aboy Solanes 2019-09-17 16:08:33 +01:00 committed by Commit Bot
parent d7903dd3de
commit 26372107aa
3 changed files with 210 additions and 204 deletions

View File

@ -22,57 +22,58 @@ class NumberBuiltinsAssembler : public CodeStubAssembler {
protected:
template <typename Descriptor>
void EmitBitwiseOp(Operation op) {
Node* left = Parameter(Descriptor::kLeft);
Node* right = Parameter(Descriptor::kRight);
Node* context = Parameter(Descriptor::kContext);
TNode<Object> left = CAST(Parameter(Descriptor::kLeft));
TNode<Object> right = CAST(Parameter(Descriptor::kRight));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
VARIABLE(var_left_word32, MachineRepresentation::kWord32);
VARIABLE(var_right_word32, MachineRepresentation::kWord32);
VARIABLE(var_left_bigint, MachineRepresentation::kTagged, left);
VARIABLE(var_right_bigint, MachineRepresentation::kTagged);
TVARIABLE(Word32T, var_left_word32);
TVARIABLE(Word32T, var_right_word32);
TVARIABLE(Object, var_left_maybe_bigint, left);
TVARIABLE(Object, var_right_maybe_bigint);
Label if_left_number(this), do_number_op(this);
Label if_left_bigint(this), do_bigint_op(this);
TaggedToWord32OrBigInt(context, left, &if_left_number, &var_left_word32,
&if_left_bigint, &var_left_bigint);
&if_left_bigint, &var_left_maybe_bigint);
BIND(&if_left_number);
TaggedToWord32OrBigInt(context, right, &do_number_op, &var_right_word32,
&do_bigint_op, &var_right_bigint);
&do_bigint_op, &var_right_maybe_bigint);
BIND(&do_number_op);
Return(BitwiseOp(var_left_word32.value(), var_right_word32.value(), op));
// BigInt cases.
BIND(&if_left_bigint);
TaggedToNumeric(context, right, &do_bigint_op, &var_right_bigint);
TaggedToNumeric(context, right, &do_bigint_op, &var_right_maybe_bigint);
BIND(&do_bigint_op);
Return(CallRuntime(Runtime::kBigIntBinaryOp, context,
var_left_bigint.value(), var_right_bigint.value(),
SmiConstant(op)));
var_left_maybe_bigint.value(),
var_right_maybe_bigint.value(), SmiConstant(op)));
}
template <typename Descriptor>
void RelationalComparisonBuiltin(Operation op) {
Node* lhs = Parameter(Descriptor::kLeft);
Node* rhs = Parameter(Descriptor::kRight);
Node* context = Parameter(Descriptor::kContext);
TNode<Object> lhs = CAST(Parameter(Descriptor::kLeft));
TNode<Object> rhs = CAST(Parameter(Descriptor::kRight));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Return(RelationalComparison(op, lhs, rhs, context));
}
template <typename Descriptor>
void UnaryOp(Variable* var_input, Label* do_smi, Label* do_double,
Variable* var_input_double, Label* do_bigint);
void UnaryOp(TVariable<Object>* var_input, Label* do_smi, Label* do_double,
TVariable<Float64T>* var_input_double, Label* do_bigint);
template <typename Descriptor>
void BinaryOp(Label* smis, Variable* var_left, Variable* var_right,
Label* doubles, Variable* var_left_double,
Variable* var_right_double, Label* bigints);
void BinaryOp(Label* smis, TVariable<Object>* var_left,
TVariable<Object>* var_right, Label* doubles,
TVariable<Float64T>* var_left_double,
TVariable<Float64T>* var_right_double, Label* bigints);
};
// ES6 #sec-number.isfinite
TF_BUILTIN(NumberIsFinite, CodeStubAssembler) {
Node* number = Parameter(Descriptor::kNumber);
TNode<Object> number = CAST(Parameter(Descriptor::kNumber));
Label return_true(this), return_false(this);
@ -80,10 +81,11 @@ TF_BUILTIN(NumberIsFinite, CodeStubAssembler) {
GotoIf(TaggedIsSmi(number), &return_true);
// Check if {number} is a HeapNumber.
GotoIfNot(IsHeapNumber(number), &return_false);
TNode<HeapObject> number_heap_object = CAST(number);
GotoIfNot(IsHeapNumber(number_heap_object), &return_false);
// Check if {number} contains a finite, non-NaN value.
TNode<Float64T> number_value = LoadHeapNumberValue(number);
TNode<Float64T> number_value = LoadHeapNumberValue(number_heap_object);
BranchIfFloat64IsNaN(Float64Sub(number_value, number_value), &return_false,
&return_true);
@ -107,7 +109,7 @@ TF_BUILTIN(NumberIsInteger, CodeStubAssembler) {
// ES6 #sec-number.isnan
TF_BUILTIN(NumberIsNaN, CodeStubAssembler) {
Node* number = Parameter(Descriptor::kNumber);
TNode<Object> number = CAST(Parameter(Descriptor::kNumber));
Label return_true(this), return_false(this);
@ -115,10 +117,11 @@ TF_BUILTIN(NumberIsNaN, CodeStubAssembler) {
GotoIf(TaggedIsSmi(number), &return_false);
// Check if {number} is a HeapNumber.
GotoIfNot(IsHeapNumber(number), &return_false);
TNode<HeapObject> number_heap_object = CAST(number);
GotoIfNot(IsHeapNumber(number_heap_object), &return_false);
// Check if {number} contains a NaN value.
TNode<Float64T> number_value = LoadHeapNumberValue(number);
TNode<Float64T> number_value = LoadHeapNumberValue(number_heap_object);
BranchIfFloat64IsNaN(number_value, &return_true, &return_false);
BIND(&return_true);
@ -136,17 +139,16 @@ TF_BUILTIN(NumberIsSafeInteger, CodeStubAssembler) {
// ES6 #sec-number.parsefloat
TF_BUILTIN(NumberParseFloat, CodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
// We might need to loop once for ToString conversion.
VARIABLE(var_input, MachineRepresentation::kTagged,
Parameter(Descriptor::kString));
TVARIABLE(Object, var_input, CAST(Parameter(Descriptor::kString)));
Label loop(this, &var_input);
Goto(&loop);
BIND(&loop);
{
// Load the current {input} value.
Node* input = var_input.value();
TNode<Object> input = var_input.value();
// Check if the {input} is a HeapObject or a Smi.
Label if_inputissmi(this), if_inputisnotsmi(this);
@ -161,8 +163,9 @@ TF_BUILTIN(NumberParseFloat, CodeStubAssembler) {
BIND(&if_inputisnotsmi);
{
// The {input} is a HeapObject, check if it's already a String.
TNode<HeapObject> input_heap_object = CAST(input);
Label if_inputisstring(this), if_inputisnotstring(this);
TNode<Map> input_map = LoadMap(input);
TNode<Map> input_map = LoadMap(input_heap_object);
TNode<Uint16T> input_instance_type = LoadMapInstanceType(input_map);
Branch(IsStringInstanceType(input_instance_type), &if_inputisstring,
&if_inputisnotstring);
@ -172,7 +175,7 @@ TF_BUILTIN(NumberParseFloat, CodeStubAssembler) {
// The {input} is already a String, check if {input} contains
// a cached array index.
Label if_inputcached(this), if_inputnotcached(this);
TNode<Uint32T> input_hash = LoadNameHashField(input);
TNode<Uint32T> input_hash = LoadNameHashField(CAST(input));
Branch(IsClearWord32(input_hash,
Name::kDoesNotContainCachedArrayIndexMask),
&if_inputcached, &if_inputnotcached);
@ -204,7 +207,7 @@ TF_BUILTIN(NumberParseFloat, CodeStubAssembler) {
{
// The {input} is already a Number, take care of -0.
Label if_inputiszero(this), if_inputisnotzero(this);
TNode<Float64T> input_value = LoadHeapNumberValue(input);
TNode<Float64T> input_value = LoadHeapNumberValue(input_heap_object);
Branch(Float64Equal(input_value, Float64Constant(0.0)),
&if_inputiszero, &if_inputisnotzero);
@ -219,7 +222,7 @@ TF_BUILTIN(NumberParseFloat, CodeStubAssembler) {
{
// Need to convert the {input} to String first.
// TODO(bmeurer): This could be more efficient if necessary.
var_input.Bind(CallBuiltin(Builtins::kToString, context, input));
var_input = CallBuiltin(Builtins::kToString, context, input);
Goto(&loop);
}
}
@ -309,9 +312,9 @@ TF_BUILTIN(ParseInt, CodeStubAssembler) {
// ES6 #sec-number.parseint
TF_BUILTIN(NumberParseInt, CodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* input = Parameter(Descriptor::kString);
Node* radix = Parameter(Descriptor::kRadix);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> input = CAST(Parameter(Descriptor::kString));
TNode<Object> radix = CAST(Parameter(Descriptor::kRadix));
Return(CallBuiltin(Builtins::kParseInt, context, input, radix));
}
@ -331,27 +334,29 @@ class AddStubAssembler : public CodeStubAssembler {
: CodeStubAssembler(state) {}
protected:
void ConvertReceiverAndLoop(Variable* var_value, Label* loop, Node* context) {
TNode<Object> ConvertReceiver(TNode<JSReceiver> js_receiver,
TNode<Context> context) {
// Call ToPrimitive explicitly without hint (whereas ToNumber
// would pass a "number" hint).
Callable callable = CodeFactory::NonPrimitiveToPrimitive(isolate());
var_value->Bind(CallStub(callable, context, var_value->value()));
return CallStub(callable, context, js_receiver);
}
void ConvertNonReceiverAndLoop(TVariable<Object>* var_value, Label* loop,
TNode<Context> context) {
*var_value =
CallBuiltin(Builtins::kNonNumberToNumeric, context, var_value->value());
Goto(loop);
}
void ConvertNonReceiverAndLoop(Variable* var_value, Label* loop,
Node* context) {
var_value->Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context,
var_value->value()));
Goto(loop);
}
void ConvertAndLoop(Variable* var_value, Node* instance_type, Label* loop,
Node* context) {
void ConvertAndLoop(TVariable<Object>* var_value,
TNode<Uint16T> instance_type, Label* loop,
TNode<Context> context) {
Label is_not_receiver(this, Label::kDeferred);
GotoIfNot(IsJSReceiverInstanceType(instance_type), &is_not_receiver);
ConvertReceiverAndLoop(var_value, loop, context);
*var_value = ConvertReceiver(CAST(var_value->value()), context);
Goto(loop);
BIND(&is_not_receiver);
ConvertNonReceiverAndLoop(var_value, loop, context);
@ -359,30 +364,26 @@ class AddStubAssembler : public CodeStubAssembler {
};
TF_BUILTIN(Add, AddStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
VARIABLE(var_left, MachineRepresentation::kTagged,
Parameter(Descriptor::kLeft));
VARIABLE(var_right, MachineRepresentation::kTagged,
Parameter(Descriptor::kRight));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TVARIABLE(Object, var_left, CAST(Parameter(Descriptor::kLeft)));
TVARIABLE(Object, var_right, CAST(Parameter(Descriptor::kRight)));
// Shared entry for floating point addition.
Label do_double_add(this);
VARIABLE(var_left_double, MachineRepresentation::kFloat64);
VARIABLE(var_right_double, MachineRepresentation::kFloat64);
TVARIABLE(Float64T, var_left_double);
TVARIABLE(Float64T, var_right_double);
// We might need to loop several times due to ToPrimitive, ToString and/or
// ToNumeric conversions.
VARIABLE(var_result, MachineRepresentation::kTagged);
Variable* loop_vars[2] = {&var_left, &var_right};
Label loop(this, 2, loop_vars),
Label loop(this, {&var_left, &var_right}),
string_add_convert_left(this, Label::kDeferred),
string_add_convert_right(this, Label::kDeferred),
do_bigint_add(this, Label::kDeferred);
Goto(&loop);
BIND(&loop);
{
Node* left = var_left.value();
Node* right = var_right.value();
TNode<Object> left = var_left.value();
TNode<Object> right = var_right.value();
Label if_left_smi(this), if_left_heapobject(this);
Branch(TaggedIsSmi(left), &if_left_smi, &if_left_heapobject);
@ -395,27 +396,30 @@ TF_BUILTIN(Add, AddStubAssembler) {
BIND(&if_right_smi);
{
Label if_overflow(this);
TNode<Smi> result = TrySmiAdd(CAST(left), CAST(right), &if_overflow);
TNode<Smi> left_smi = CAST(left);
TNode<Smi> right_smi = CAST(right);
TNode<Smi> result = TrySmiAdd(left_smi, right_smi, &if_overflow);
Return(result);
BIND(&if_overflow);
{
var_left_double.Bind(SmiToFloat64(left));
var_right_double.Bind(SmiToFloat64(right));
var_left_double = SmiToFloat64(left_smi);
var_right_double = SmiToFloat64(right_smi);
Goto(&do_double_add);
}
} // if_right_smi
BIND(&if_right_heapobject);
{
TNode<Map> right_map = LoadMap(right);
TNode<HeapObject> right_heap_object = CAST(right);
TNode<Map> right_map = LoadMap(right_heap_object);
Label if_right_not_number(this, Label::kDeferred);
GotoIfNot(IsHeapNumberMap(right_map), &if_right_not_number);
// {right} is a HeapNumber.
var_left_double.Bind(SmiToFloat64(left));
var_right_double.Bind(LoadHeapNumberValue(right));
var_left_double = SmiToFloat64(CAST(left));
var_right_double = LoadHeapNumberValue(right_heap_object);
Goto(&do_double_add);
BIND(&if_right_not_number);
@ -431,7 +435,8 @@ TF_BUILTIN(Add, AddStubAssembler) {
BIND(&if_left_heapobject);
{
TNode<Map> left_map = LoadMap(left);
TNode<HeapObject> left_heap_object = CAST(left);
TNode<Map> left_map = LoadMap(left_heap_object);
Label if_right_smi(this), if_right_heapobject(this);
Branch(TaggedIsSmi(right), &if_right_smi, &if_right_heapobject);
@ -441,8 +446,8 @@ TF_BUILTIN(Add, AddStubAssembler) {
GotoIfNot(IsHeapNumberMap(left_map), &if_left_not_number);
// {left} is a HeapNumber, {right} is a Smi.
var_left_double.Bind(LoadHeapNumberValue(left));
var_right_double.Bind(SmiToFloat64(right));
var_left_double = LoadHeapNumberValue(left_heap_object);
var_right_double = SmiToFloat64(CAST(right));
Goto(&do_double_add);
BIND(&if_left_not_number);
@ -458,7 +463,8 @@ TF_BUILTIN(Add, AddStubAssembler) {
BIND(&if_right_heapobject);
{
TNode<Map> right_map = LoadMap(right);
TNode<HeapObject> right_heap_object = CAST(right);
TNode<Map> right_map = LoadMap(right_heap_object);
Label if_left_number(this), if_left_not_number(this, Label::kDeferred);
Branch(IsHeapNumberMap(left_map), &if_left_number, &if_left_not_number);
@ -469,8 +475,8 @@ TF_BUILTIN(Add, AddStubAssembler) {
GotoIfNot(IsHeapNumberMap(right_map), &if_right_not_number);
// Both {left} and {right} are HeapNumbers.
var_left_double.Bind(LoadHeapNumberValue(left));
var_right_double.Bind(LoadHeapNumberValue(right));
var_left_double = LoadHeapNumberValue(CAST(left));
var_right_double = LoadHeapNumberValue(right_heap_object);
Goto(&do_double_add);
BIND(&if_right_not_number);
@ -499,7 +505,8 @@ TF_BUILTIN(Add, AddStubAssembler) {
GotoIfNot(IsJSReceiverInstanceType(left_instance_type),
&if_left_not_receiver);
// {left} is a JSReceiver, convert it first.
ConvertReceiverAndLoop(&var_left, &loop, context);
var_left = ConvertReceiver(CAST(var_left.value()), context);
Goto(&loop);
BIND(&if_left_bigint);
{
@ -515,7 +522,8 @@ TF_BUILTIN(Add, AddStubAssembler) {
&if_right_not_receiver);
// {left} is a Primitive, but {right} is a JSReceiver, so convert
// {right} with priority.
ConvertReceiverAndLoop(&var_right, &loop, context);
var_right = ConvertReceiver(CAST(var_right.value()), context);
Goto(&loop);
BIND(&if_right_not_receiver);
// Neither {left} nor {right} are JSReceivers.
@ -553,54 +561,46 @@ TF_BUILTIN(Add, AddStubAssembler) {
}
template <typename Descriptor>
void NumberBuiltinsAssembler::UnaryOp(Variable* var_input, Label* do_smi,
Label* do_double,
Variable* var_input_double,
void NumberBuiltinsAssembler::UnaryOp(TVariable<Object>* var_input,
Label* do_smi, Label* do_double,
TVariable<Float64T>* var_input_double,
Label* do_bigint) {
DCHECK_EQ(var_input->rep(), MachineRepresentation::kTagged);
DCHECK_IMPLIES(var_input_double != nullptr,
var_input_double->rep() == MachineRepresentation::kFloat64);
Node* context = Parameter(Descriptor::kContext);
var_input->Bind(Parameter(Descriptor::kValue));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
*var_input = CAST(Parameter(Descriptor::kValue));
// We might need to loop for ToNumeric conversion.
Label loop(this, {var_input});
Goto(&loop);
BIND(&loop);
Node* input = var_input->value();
TNode<Object> input = var_input->value();
Label not_number(this);
GotoIf(TaggedIsSmi(input), do_smi);
GotoIfNot(IsHeapNumber(input), &not_number);
TNode<HeapObject> input_heap_object = CAST(input);
GotoIfNot(IsHeapNumber(input_heap_object), &not_number);
if (var_input_double != nullptr) {
var_input_double->Bind(LoadHeapNumberValue(input));
*var_input_double = LoadHeapNumberValue(input_heap_object);
}
Goto(do_double);
BIND(&not_number);
GotoIf(IsBigInt(input), do_bigint);
var_input->Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context, input));
GotoIf(IsBigInt(input_heap_object), do_bigint);
*var_input = CallBuiltin(Builtins::kNonNumberToNumeric, context, input);
Goto(&loop);
}
template <typename Descriptor>
void NumberBuiltinsAssembler::BinaryOp(Label* smis, Variable* var_left,
Variable* var_right, Label* doubles,
Variable* var_left_double,
Variable* var_right_double,
void NumberBuiltinsAssembler::BinaryOp(Label* smis, TVariable<Object>* var_left,
TVariable<Object>* var_right,
Label* doubles,
TVariable<Float64T>* var_left_double,
TVariable<Float64T>* var_right_double,
Label* bigints) {
DCHECK_EQ(var_left->rep(), MachineRepresentation::kTagged);
DCHECK_EQ(var_right->rep(), MachineRepresentation::kTagged);
DCHECK_IMPLIES(var_left_double != nullptr,
var_left_double->rep() == MachineRepresentation::kFloat64);
DCHECK_IMPLIES(var_right_double != nullptr,
var_right_double->rep() == MachineRepresentation::kFloat64);
DCHECK_EQ(var_left_double == nullptr, var_right_double == nullptr);
Node* context = Parameter(Descriptor::kContext);
var_left->Bind(Parameter(Descriptor::kLeft));
var_right->Bind(Parameter(Descriptor::kRight));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
*var_left = CAST(Parameter(Descriptor::kLeft));
*var_right = CAST(Parameter(Descriptor::kRight));
// We might need to loop for ToNumeric conversions.
Label loop(this, {var_left, var_right});
@ -613,32 +613,36 @@ void NumberBuiltinsAssembler::BinaryOp(Label* smis, Variable* var_left,
GotoIf(TaggedIsSmi(var_right->value()), smis);
// At this point, var_left is a Smi but var_right is not.
GotoIfNot(IsHeapNumber(var_right->value()), &right_not_number);
TNode<Smi> var_left_smi = CAST(var_left->value());
TNode<HeapObject> var_right_heap_object = CAST(var_right->value());
GotoIfNot(IsHeapNumber(var_right_heap_object), &right_not_number);
if (var_left_double != nullptr) {
var_left_double->Bind(SmiToFloat64(var_left->value()));
var_right_double->Bind(LoadHeapNumberValue(var_right->value()));
*var_left_double = SmiToFloat64(var_left_smi);
*var_right_double = LoadHeapNumberValue(var_right_heap_object);
}
Goto(doubles);
BIND(&left_not_smi);
{
GotoIfNot(IsHeapNumber(var_left->value()), &left_not_number);
TNode<HeapObject> var_left_heap_object = CAST(var_left->value());
GotoIfNot(IsHeapNumber(var_left_heap_object), &left_not_number);
GotoIfNot(TaggedIsSmi(var_right->value()), &right_not_smi);
// At this point, var_left is a HeapNumber and var_right is a Smi.
if (var_left_double != nullptr) {
var_left_double->Bind(LoadHeapNumberValue(var_left->value()));
var_right_double->Bind(SmiToFloat64(var_right->value()));
*var_left_double = LoadHeapNumberValue(var_left_heap_object);
*var_right_double = SmiToFloat64(CAST(var_right->value()));
}
Goto(doubles);
}
BIND(&right_not_smi);
{
GotoIfNot(IsHeapNumber(var_right->value()), &right_not_number);
TNode<HeapObject> var_right_heap_object = CAST(var_right->value());
GotoIfNot(IsHeapNumber(var_right_heap_object), &right_not_number);
if (var_left_double != nullptr) {
var_left_double->Bind(LoadHeapNumberValue(var_left->value()));
var_right_double->Bind(LoadHeapNumberValue(var_right->value()));
*var_left_double = LoadHeapNumberValue(CAST(var_left->value()));
*var_right_double = LoadHeapNumberValue(var_right_heap_object);
}
Goto(doubles);
}
@ -646,37 +650,38 @@ void NumberBuiltinsAssembler::BinaryOp(Label* smis, Variable* var_left,
BIND(&left_not_number);
{
Label left_bigint(this);
GotoIf(IsBigInt(var_left->value()), &left_bigint);
var_left->Bind(
CallBuiltin(Builtins::kNonNumberToNumeric, context, var_left->value()));
GotoIf(IsBigInt(CAST(var_left->value())), &left_bigint);
*var_left =
CallBuiltin(Builtins::kNonNumberToNumeric, context, var_left->value());
Goto(&loop);
BIND(&left_bigint);
{
// Jump to {bigints} if {var_right} is already a Numeric.
GotoIf(TaggedIsSmi(var_right->value()), bigints);
GotoIf(IsBigInt(var_right->value()), bigints);
GotoIf(IsHeapNumber(var_right->value()), bigints);
var_right->Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context,
var_right->value()));
TNode<HeapObject> var_right_heap_object = CAST(var_right->value());
GotoIf(IsBigInt(var_right_heap_object), bigints);
GotoIf(IsHeapNumber(var_right_heap_object), bigints);
*var_right = CallBuiltin(Builtins::kNonNumberToNumeric, context,
var_right->value());
Goto(&loop);
}
}
BIND(&right_not_number);
{
GotoIf(IsBigInt(var_right->value()), bigints);
var_right->Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context,
var_right->value()));
GotoIf(IsBigInt(CAST(var_right->value())), bigints);
*var_right =
CallBuiltin(Builtins::kNonNumberToNumeric, context, var_right->value());
Goto(&loop);
}
}
TF_BUILTIN(Subtract, NumberBuiltinsAssembler) {
VARIABLE(var_left, MachineRepresentation::kTagged);
VARIABLE(var_right, MachineRepresentation::kTagged);
VARIABLE(var_left_double, MachineRepresentation::kFloat64);
VARIABLE(var_right_double, MachineRepresentation::kFloat64);
TVARIABLE(Object, var_left);
TVARIABLE(Object, var_right);
TVARIABLE(Float64T, var_left_double);
TVARIABLE(Float64T, var_right_double);
Label do_smi_sub(this), do_double_sub(this), do_bigint_sub(this);
BinaryOp<Descriptor>(&do_smi_sub, &var_left, &var_right, &do_double_sub,
@ -685,14 +690,15 @@ TF_BUILTIN(Subtract, NumberBuiltinsAssembler) {
BIND(&do_smi_sub);
{
Label if_overflow(this);
TNode<Smi> result = TrySmiSub(CAST(var_left.value()),
CAST(var_right.value()), &if_overflow);
TNode<Smi> var_left_smi = CAST(var_left.value());
TNode<Smi> var_right_smi = CAST(var_right.value());
TNode<Smi> result = TrySmiSub(var_left_smi, var_right_smi, &if_overflow);
Return(result);
BIND(&if_overflow);
{
var_left_double.Bind(SmiToFloat64(var_left.value()));
var_right_double.Bind(SmiToFloat64(var_right.value()));
var_left_double = SmiToFloat64(var_left_smi);
var_right_double = SmiToFloat64(var_right_smi);
Goto(&do_double_sub);
}
}
@ -706,15 +712,15 @@ TF_BUILTIN(Subtract, NumberBuiltinsAssembler) {
BIND(&do_bigint_sub);
{
Node* context = Parameter(Descriptor::kContext);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(),
var_right.value(), SmiConstant(Operation::kSubtract)));
}
}
TF_BUILTIN(BitwiseNot, NumberBuiltinsAssembler) {
Node* context = Parameter(Descriptor::kContext);
VARIABLE(var_input, MachineRepresentation::kTagged);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TVARIABLE(Object, var_input);
Label do_number(this), do_bigint(this);
UnaryOp<Descriptor>(&var_input, &do_number, &do_number, nullptr, &do_bigint);
@ -733,8 +739,8 @@ TF_BUILTIN(BitwiseNot, NumberBuiltinsAssembler) {
}
TF_BUILTIN(Decrement, NumberBuiltinsAssembler) {
Node* context = Parameter(Descriptor::kContext);
VARIABLE(var_input, MachineRepresentation::kTagged);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TVARIABLE(Object, var_input);
Label do_number(this), do_bigint(this);
UnaryOp<Descriptor>(&var_input, &do_number, &do_number, nullptr, &do_bigint);
@ -753,8 +759,8 @@ TF_BUILTIN(Decrement, NumberBuiltinsAssembler) {
}
TF_BUILTIN(Increment, NumberBuiltinsAssembler) {
Node* context = Parameter(Descriptor::kContext);
VARIABLE(var_input, MachineRepresentation::kTagged);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TVARIABLE(Object, var_input);
Label do_number(this), do_bigint(this);
UnaryOp<Descriptor>(&var_input, &do_number, &do_number, nullptr, &do_bigint);
@ -772,8 +778,8 @@ TF_BUILTIN(Increment, NumberBuiltinsAssembler) {
}
TF_BUILTIN(Negate, NumberBuiltinsAssembler) {
VARIABLE(var_input, MachineRepresentation::kTagged);
VARIABLE(var_input_double, MachineRepresentation::kFloat64);
TVARIABLE(Object, var_input);
TVARIABLE(Float64T, var_input_double);
Label do_smi(this), do_double(this), do_bigint(this);
UnaryOp<Descriptor>(&var_input, &do_smi, &do_double, &var_input_double,
@ -791,17 +797,17 @@ TF_BUILTIN(Negate, NumberBuiltinsAssembler) {
BIND(&do_bigint);
{
Node* context = Parameter(Descriptor::kContext);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Return(CallRuntime(Runtime::kBigIntUnaryOp, context, var_input.value(),
SmiConstant(Operation::kNegate)));
}
}
TF_BUILTIN(Multiply, NumberBuiltinsAssembler) {
VARIABLE(var_left, MachineRepresentation::kTagged);
VARIABLE(var_right, MachineRepresentation::kTagged);
VARIABLE(var_left_double, MachineRepresentation::kFloat64);
VARIABLE(var_right_double, MachineRepresentation::kFloat64);
TVARIABLE(Object, var_left);
TVARIABLE(Object, var_right);
TVARIABLE(Float64T, var_left_double);
TVARIABLE(Float64T, var_right_double);
Label do_smi_mul(this), do_double_mul(this), do_bigint_mul(this);
BinaryOp<Descriptor>(&do_smi_mul, &var_left, &var_right, &do_double_mul,
@ -818,17 +824,17 @@ TF_BUILTIN(Multiply, NumberBuiltinsAssembler) {
BIND(&do_bigint_mul);
{
Node* context = Parameter(Descriptor::kContext);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(),
var_right.value(), SmiConstant(Operation::kMultiply)));
}
}
TF_BUILTIN(Divide, NumberBuiltinsAssembler) {
VARIABLE(var_left, MachineRepresentation::kTagged);
VARIABLE(var_right, MachineRepresentation::kTagged);
VARIABLE(var_left_double, MachineRepresentation::kFloat64);
VARIABLE(var_right_double, MachineRepresentation::kFloat64);
TVARIABLE(Object, var_left);
TVARIABLE(Object, var_right);
TVARIABLE(Float64T, var_left_double);
TVARIABLE(Float64T, var_right_double);
Label do_smi_div(this), do_double_div(this), do_bigint_div(this);
BinaryOp<Descriptor>(&do_smi_div, &var_left, &var_right, &do_double_div,
@ -889,8 +895,8 @@ TF_BUILTIN(Divide, NumberBuiltinsAssembler) {
// division.
BIND(&bailout);
{
var_left_double.Bind(SmiToFloat64(dividend));
var_right_double.Bind(SmiToFloat64(divisor));
var_left_double = SmiToFloat64(dividend);
var_right_double = SmiToFloat64(divisor);
Goto(&do_double_div);
}
}
@ -904,17 +910,17 @@ TF_BUILTIN(Divide, NumberBuiltinsAssembler) {
BIND(&do_bigint_div);
{
Node* context = Parameter(Descriptor::kContext);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(),
var_right.value(), SmiConstant(Operation::kDivide)));
}
}
TF_BUILTIN(Modulus, NumberBuiltinsAssembler) {
VARIABLE(var_left, MachineRepresentation::kTagged);
VARIABLE(var_right, MachineRepresentation::kTagged);
VARIABLE(var_left_double, MachineRepresentation::kFloat64);
VARIABLE(var_right_double, MachineRepresentation::kFloat64);
TVARIABLE(Object, var_left);
TVARIABLE(Object, var_right);
TVARIABLE(Float64T, var_left_double);
TVARIABLE(Float64T, var_right_double);
Label do_smi_mod(this), do_double_mod(this), do_bigint_mod(this);
BinaryOp<Descriptor>(&do_smi_mod, &var_left, &var_right, &do_double_mod,
@ -930,17 +936,17 @@ TF_BUILTIN(Modulus, NumberBuiltinsAssembler) {
BIND(&do_bigint_mod);
{
Node* context = Parameter(Descriptor::kContext);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(),
var_right.value(), SmiConstant(Operation::kModulus)));
}
}
TF_BUILTIN(Exponentiate, NumberBuiltinsAssembler) {
VARIABLE(var_left, MachineRepresentation::kTagged);
VARIABLE(var_right, MachineRepresentation::kTagged);
TVARIABLE(Object, var_left);
TVARIABLE(Object, var_right);
Label do_number_exp(this), do_bigint_exp(this);
Node* context = Parameter(Descriptor::kContext);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
BinaryOp<Descriptor>(&do_number_exp, &var_left, &var_right, &do_number_exp,
nullptr, nullptr, &do_bigint_exp);
@ -997,9 +1003,9 @@ TF_BUILTIN(GreaterThanOrEqual, NumberBuiltinsAssembler) {
}
TF_BUILTIN(Equal, CodeStubAssembler) {
Node* lhs = Parameter(Descriptor::kLeft);
Node* rhs = Parameter(Descriptor::kRight);
Node* context = Parameter(Descriptor::kContext);
TNode<Object> lhs = CAST(Parameter(Descriptor::kLeft));
TNode<Object> rhs = CAST(Parameter(Descriptor::kRight));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Return(Equal(lhs, rhs, context));
}

View File

@ -5629,48 +5629,43 @@ TNode<Float64T> CodeStubAssembler::TruncateTaggedToFloat64(
TNode<Word32T> CodeStubAssembler::TruncateTaggedToWord32(
SloppyTNode<Context> context, SloppyTNode<Object> value) {
VARIABLE(var_result, MachineRepresentation::kWord32);
TVARIABLE(Word32T, var_result);
Label done(this);
TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumber>(context, value,
&done, &var_result);
BIND(&done);
return UncheckedCast<Word32T>(var_result.value());
return var_result.value();
}
// Truncate {value} to word32 and jump to {if_number} if it is a Number,
// or find that it is a BigInt and jump to {if_bigint}.
void CodeStubAssembler::TaggedToWord32OrBigInt(Node* context, Node* value,
Label* if_number,
Variable* var_word32,
Label* if_bigint,
Variable* var_bigint) {
void CodeStubAssembler::TaggedToWord32OrBigInt(
TNode<Context> context, TNode<Object> value, Label* if_number,
TVariable<Word32T>* var_word32, Label* if_bigint,
TVariable<Object>* var_maybe_bigint) {
TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>(
context, value, if_number, var_word32, if_bigint, var_bigint);
context, value, if_number, var_word32, if_bigint, var_maybe_bigint);
}
// Truncate {value} to word32 and jump to {if_number} if it is a Number,
// or find that it is a BigInt and jump to {if_bigint}. In either case,
// store the type feedback in {var_feedback}.
void CodeStubAssembler::TaggedToWord32OrBigIntWithFeedback(
Node* context, Node* value, Label* if_number, Variable* var_word32,
Label* if_bigint, Variable* var_bigint, Variable* var_feedback) {
TNode<Context> context, TNode<Object> value, Label* if_number,
TVariable<Word32T>* var_word32, Label* if_bigint,
TVariable<Object>* var_maybe_bigint, TVariable<Smi>* var_feedback) {
TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>(
context, value, if_number, var_word32, if_bigint, var_bigint,
context, value, if_number, var_word32, if_bigint, var_maybe_bigint,
var_feedback);
}
template <Object::Conversion conversion>
void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
Node* context, Node* value, Label* if_number, Variable* var_word32,
Label* if_bigint, Variable* var_bigint, Variable* var_feedback) {
DCHECK(var_word32->rep() == MachineRepresentation::kWord32);
DCHECK(var_bigint == nullptr ||
var_bigint->rep() == MachineRepresentation::kTagged);
DCHECK(var_feedback == nullptr ||
var_feedback->rep() == MachineRepresentation::kTaggedSigned);
TNode<Context> context, TNode<Object> value, Label* if_number,
TVariable<Word32T>* var_word32, Label* if_bigint,
TVariable<Object>* var_maybe_bigint, TVariable<Smi>* var_feedback) {
// We might need to loop after conversion.
VARIABLE(var_value, MachineRepresentation::kTagged, value);
TVARIABLE(Object, var_value, value);
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kNone);
Variable* loop_vars[] = {&var_value, var_feedback};
int num_vars =
@ -5685,12 +5680,13 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
GotoIf(TaggedIsNotSmi(value), &not_smi);
// {value} is a Smi.
var_word32->Bind(SmiToInt32(value));
*var_word32 = SmiToInt32(CAST(value));
CombineFeedback(var_feedback, BinaryOperationFeedback::kSignedSmall);
Goto(if_number);
BIND(&not_smi);
TNode<Map> map = LoadMap(value);
TNode<HeapObject> value_heap_object = CAST(value);
TNode<Map> map = LoadMap(value_heap_object);
GotoIf(IsHeapNumberMap(map), &is_heap_number);
TNode<Uint16T> instance_type = LoadMapInstanceType(map);
if (conversion == Object::Conversion::kToNumeric) {
@ -5703,7 +5699,7 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
// We do not require an Or with earlier feedback here because once we
// convert the value to a Numeric, we cannot reach this path. We can
// only reach this path on the first pass when the feedback is kNone.
CSA_ASSERT(this, SmiEqual(CAST(var_feedback->value()),
CSA_ASSERT(this, SmiEqual(var_feedback->value(),
SmiConstant(BinaryOperationFeedback::kNone)));
}
GotoIf(InstanceTypeEqual(instance_type, ODDBALL_TYPE), &is_oddball);
@ -5711,25 +5707,25 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
auto builtin = conversion == Object::Conversion::kToNumeric
? Builtins::kNonNumberToNumeric
: Builtins::kNonNumberToNumber;
var_value.Bind(CallBuiltin(builtin, context, value));
var_value = CallBuiltin(builtin, context, value);
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kAny);
Goto(&loop);
BIND(&is_oddball);
var_value.Bind(LoadObjectField(value, Oddball::kToNumberOffset));
var_value = LoadObjectField(value_heap_object, Oddball::kToNumberOffset);
OverwriteFeedback(var_feedback,
BinaryOperationFeedback::kNumberOrOddball);
Goto(&loop);
}
BIND(&is_heap_number);
var_word32->Bind(TruncateHeapNumberValueToWord32(CAST(value)));
*var_word32 = TruncateHeapNumberValueToWord32(CAST(value));
CombineFeedback(var_feedback, BinaryOperationFeedback::kNumber);
Goto(if_number);
if (conversion == Object::Conversion::kToNumeric) {
BIND(&is_bigint);
var_bigint->Bind(value);
*var_maybe_bigint = value;
CombineFeedback(var_feedback, BinaryOperationFeedback::kBigInt);
Goto(if_bigint);
}
@ -11547,8 +11543,8 @@ Operation Reverse(Operation op) {
} // anonymous namespace
TNode<Oddball> CodeStubAssembler::RelationalComparison(
Operation op, SloppyTNode<Object> left, SloppyTNode<Object> right,
SloppyTNode<Context> context, TVariable<Smi>* var_type_feedback) {
Operation op, TNode<Object> left, TNode<Object> right,
TNode<Context> context, TVariable<Smi>* var_type_feedback) {
Label return_true(this), return_false(this), do_float_comparison(this),
end(this);
TVARIABLE(Oddball, var_result); // Actually only "true" or "false".

View File

@ -2305,12 +2305,16 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
SloppyTNode<Object> value);
TNode<Word32T> TruncateTaggedToWord32(SloppyTNode<Context> context,
SloppyTNode<Object> value);
void TaggedToWord32OrBigInt(Node* context, Node* value, Label* if_number,
Variable* var_word32, Label* if_bigint,
Variable* var_bigint);
void TaggedToWord32OrBigIntWithFeedback(
Node* context, Node* value, Label* if_number, Variable* var_word32,
Label* if_bigint, Variable* var_bigint, Variable* var_feedback);
void TaggedToWord32OrBigInt(TNode<Context> context, TNode<Object> value,
Label* if_number, TVariable<Word32T>* var_word32,
Label* if_bigint,
TVariable<Object>* var_maybe_bigint);
void TaggedToWord32OrBigIntWithFeedback(TNode<Context> context,
TNode<Object> value, Label* if_number,
TVariable<Word32T>* var_word32,
Label* if_bigint,
TVariable<Object>* var_maybe_bigint,
TVariable<Smi>* var_feedback);
// Truncate the floating point value of a HeapNumber to an Int32.
TNode<Int32T> TruncateHeapNumberValueToWord32(TNode<HeapNumber> object);
@ -3409,9 +3413,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<IntPtrT> end_offset, RootIndex root);
TNode<Oddball> RelationalComparison(
Operation op, SloppyTNode<Object> left, SloppyTNode<Object> right,
SloppyTNode<Context> context,
TVariable<Smi>* var_type_feedback = nullptr);
Operation op, TNode<Object> left, TNode<Object> right,
TNode<Context> context, TVariable<Smi>* var_type_feedback = nullptr);
void BranchIfNumberRelationalComparison(Operation op,
SloppyTNode<Number> left,
@ -3811,11 +3814,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
Variable* var_numeric, Variable* var_feedback);
template <Object::Conversion conversion>
void TaggedToWord32OrBigIntImpl(Node* context, Node* value, Label* if_number,
Variable* var_word32,
void TaggedToWord32OrBigIntImpl(TNode<Context> context, TNode<Object> value,
Label* if_number,
TVariable<Word32T>* var_word32,
Label* if_bigint = nullptr,
Variable* var_bigint = nullptr,
Variable* var_feedback = nullptr);
TVariable<Object>* var_maybe_bigint = nullptr,
TVariable<Smi>* var_feedback = nullptr);
private:
// Low-level accessors for Descriptor arrays.