Revert "[turbofan] Inline Number constructor in certain cases"

This reverts commit 9eca23e9ed.

Reason for revert: Clusterfuzz correctness issue

Original change's description:
> [turbofan] Inline Number constructor in certain cases
> 
> This CL adds inlining for the Number constructor if new.target is not
> present. The lowering is BigInt compatible, i.e. it converts BigInts to
> numbers.
> 
> Bug: v8:7904
> Change-Id: If03b9f872d82e50b6ded7709069181c33dc44e82
> Reviewed-on: https://chromium-review.googlesource.com/1118557
> Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
> Reviewed-by: Georg Neis <neis@chromium.org>
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#54454}

TBR=jarin@chromium.org,neis@chromium.org,sigurds@chromium.org,bmeurer@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: v8:7904
Change-Id: Ie5fa6c1262b8acc33edb672a0124f4458fcded86
Reviewed-on: https://chromium-review.googlesource.com/1142777
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54544}
This commit is contained in:
Sigurd Schneider 2018-07-19 08:28:41 +00:00 committed by Commit Bot
parent c941f11abd
commit c7a9af61e6
24 changed files with 16 additions and 208 deletions

View File

@ -142,14 +142,6 @@ TF_BUILTIN(ToNumber, CodeStubAssembler) {
Return(ToNumber(context, input));
}
// Like ToNumber, but also converts BigInts.
TF_BUILTIN(ToNumberConvertBigInt, CodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* input = Parameter(Descriptor::kArgument);
Return(ToNumber(context, input, BigIntHandling::kConvertToNumber));
}
// ES section #sec-tostring-applied-to-the-number-type
TF_BUILTIN(NumberToString, CodeStubAssembler) {
TNode<Number> input = CAST(Parameter(Descriptor::kArgument));

View File

@ -186,7 +186,6 @@ namespace internal {
TFC(NonNumberToNumber, TypeConversion, 1) \
TFC(NonNumberToNumeric, TypeConversion, 1) \
TFC(ToNumber, TypeConversion, 1) \
TFC(ToNumberConvertBigInt, TypeConversion, 1) \
TFC(ToNumeric, TypeConversion, 1) \
TFC(NumberToString, TypeConversion, 1) \
TFC(ToString, TypeConversion, 1) \

View File

@ -3675,8 +3675,6 @@ Reduction JSCallReducer::ReduceJSCall(Node* node,
return ReduceDatePrototypeGetTime(node);
case Builtins::kDateNow:
return ReduceDateNow(node);
case Builtins::kNumberConstructor:
return ReduceNumberConstructor(node);
default:
break;
}
@ -7184,26 +7182,6 @@ Reduction JSCallReducer::ReduceRegExpPrototypeTest(Node* node) {
return Changed(node);
}
// ES section #sec-number-constructor
Reduction JSCallReducer::ReduceNumberConstructor(Node* node) {
DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
CallParameters const& p = CallParametersOf(node->op());
if (p.arity() <= 2) {
ReplaceWithValue(node, jsgraph()->ZeroConstant());
}
// We don't have a new.target argument, so we can convert to number,
// but must also convert BigInts.
if (p.arity() == 3) {
Node* value = NodeProperties::GetValueInput(node, 2);
NodeProperties::ReplaceValueInputs(node, value);
NodeProperties::ChangeOp(node, javascript()->ToNumberConvertBigInt());
return Changed(node);
}
return NoChange();
}
Graph* JSCallReducer::graph() const { return jsgraph()->graph(); }
Isolate* JSCallReducer::isolate() const { return jsgraph()->isolate(); }

View File

@ -190,8 +190,6 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
Reduction ReduceDateNow(Node* node);
Reduction ReduceNumberParseInt(Node* node);
Reduction ReduceNumberConstructor(Node* node);
// Returns the updated {to} node, and updates control and effect along the
// way.
Node* DoFilterPostCallbackWork(ElementsKind kind, Node** control,

View File

@ -82,7 +82,6 @@ REPLACE_STUB_CALL(Equal)
REPLACE_STUB_CALL(ToInteger)
REPLACE_STUB_CALL(ToLength)
REPLACE_STUB_CALL(ToNumber)
REPLACE_STUB_CALL(ToNumberConvertBigInt)
REPLACE_STUB_CALL(ToNumeric)
REPLACE_STUB_CALL(ToName)
REPLACE_STUB_CALL(ToObject)

View File

@ -589,7 +589,6 @@ CompareOperationHint CompareOperationHintOf(const Operator* op) {
V(ToLength, Operator::kNoProperties, 1, 1) \
V(ToName, Operator::kNoProperties, 1, 1) \
V(ToNumber, Operator::kNoProperties, 1, 1) \
V(ToNumberConvertBigInt, Operator::kNoProperties, 1, 1) \
V(ToNumeric, Operator::kNoProperties, 1, 1) \
V(ToObject, Operator::kFoldable, 1, 1) \
V(ToString, Operator::kNoProperties, 1, 1) \

View File

@ -685,7 +685,6 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
const Operator* ToLength();
const Operator* ToName();
const Operator* ToNumber();
const Operator* ToNumberConvertBigInt();
const Operator* ToNumeric();
const Operator* ToObject();
const Operator* ToString();

View File

@ -2277,7 +2277,6 @@ Reduction JSTypedLowering::Reduce(Node* node) {
case IrOpcode::kJSToName:
return ReduceJSToName(node);
case IrOpcode::kJSToNumber:
case IrOpcode::kJSToNumberConvertBigInt:
case IrOpcode::kJSToNumeric:
return ReduceJSToNumberOrNumeric(node);
case IrOpcode::kJSToString:

View File

@ -240,8 +240,7 @@ InductionVariable* LoopVariableOptimizer::TryGetInductionVariable(Node* phi) {
// TODO(jarin) Support both sides.
Node* input = arith->InputAt(0);
if (input->opcode() == IrOpcode::kSpeculativeToNumber ||
input->opcode() == IrOpcode::kJSToNumber ||
input->opcode() == IrOpcode::kJSToNumberConvertBigInt) {
input->opcode() == IrOpcode::kJSToNumber) {
input = input->InputAt(0);
}
if (input != phi) return nullptr;

View File

@ -602,7 +602,6 @@ bool NodeProperties::CanBeNullOrUndefined(Isolate* isolate, Node* receiver,
case IrOpcode::kJSToLength:
case IrOpcode::kJSToName:
case IrOpcode::kJSToNumber:
case IrOpcode::kJSToNumberConvertBigInt:
case IrOpcode::kJSToNumeric:
case IrOpcode::kJSToString:
case IrOpcode::kToBoolean:

View File

@ -121,7 +121,6 @@
V(JSToLength) \
V(JSToName) \
V(JSToNumber) \
V(JSToNumberConvertBigInt) \
V(JSToNumeric) \
V(JSToObject) \
V(JSToString) \

View File

@ -265,9 +265,7 @@ Type OperationTyper::ConvertReceiver(Type type) {
return type;
}
// Returns the result type of converting {type} to number, if the
// result does not depend on conversion options.
base::Optional<Type> OperationTyper::ToNumberCommon(Type type) {
Type OperationTyper::ToNumberOrNumeric(Object::Conversion mode, Type type) {
if (type.Is(Type::Number())) return type;
if (type.Is(Type::NullOrUndefined())) {
if (type.Is(Type::Null())) return cache_.kSingletonZero;
@ -291,13 +289,6 @@ base::Optional<Type> OperationTyper::ToNumberCommon(Type type) {
}
return Type::Intersect(type, Type::Number(), zone());
}
return base::Optional<Type>();
}
Type OperationTyper::ToNumberOrNumeric(Object::Conversion mode, Type type) {
if (base::Optional<Type> maybe_result_type = ToNumberCommon(type)) {
return *maybe_result_type;
}
if (type.Is(Type::BigInt())) {
return mode == Object::Conversion::kToNumber ? Type::None() : type;
}
@ -309,13 +300,6 @@ Type OperationTyper::ToNumber(Type type) {
return ToNumberOrNumeric(Object::Conversion::kToNumber, type);
}
Type OperationTyper::ToNumberConvertBigInt(Type type) {
if (base::Optional<Type> maybe_result_type = ToNumberCommon(type)) {
return *maybe_result_type;
}
return Type::Number();
}
Type OperationTyper::ToNumeric(Type type) {
return ToNumberOrNumeric(Object::Conversion::kToNumeric, type);
}

View File

@ -35,7 +35,6 @@ class V8_EXPORT_PRIVATE OperationTyper {
Type ToPrimitive(Type type);
Type ToNumber(Type type);
Type ToNumberConvertBigInt(Type type);
Type ToNumeric(Type type);
Type ToBoolean(Type type);
@ -79,7 +78,6 @@ class V8_EXPORT_PRIVATE OperationTyper {
typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome;
Type ToNumberOrNumeric(Object::Conversion mode, Type type);
base::Optional<Type> ToNumberCommon(Type type);
ComparisonOutcome Invert(ComparisonOutcome);
Type Invert(Type);

View File

@ -93,7 +93,6 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
case IrOpcode::kJSToLength:
case IrOpcode::kJSToName:
case IrOpcode::kJSToNumber:
case IrOpcode::kJSToNumberConvertBigInt:
case IrOpcode::kJSToNumeric:
case IrOpcode::kJSToObject:
case IrOpcode::kJSToString:

View File

@ -1563,7 +1563,6 @@ class RepresentationSelector {
return;
}
case IrOpcode::kJSToNumber:
case IrOpcode::kJSToNumberConvertBigInt:
case IrOpcode::kJSToNumeric: {
VisitInputs(node);
// TODO(bmeurer): Optimize somewhat based on input type?
@ -3298,7 +3297,6 @@ void SimplifiedLowering::LowerAllNodes() {
void SimplifiedLowering::DoJSToNumberOrNumericTruncatesToFloat64(
Node* node, RepresentationSelector* selector) {
DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
node->opcode() == IrOpcode::kJSToNumeric);
Node* value = node->InputAt(0);
Node* context = node->InputAt(1);
@ -3322,17 +3320,11 @@ void SimplifiedLowering::DoJSToNumberOrNumericTruncatesToFloat64(
Node* efalse0 = effect;
Node* vfalse0;
{
Operator const* op =
node->opcode() == IrOpcode::kJSToNumber
? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
? ToNumberConvertBigIntOperator()
: ToNumberOperator())
: ToNumericOperator();
Node* code = node->opcode() == IrOpcode::kJSToNumber
? ToNumberCode()
: (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
? ToNumberConvertBigIntCode()
: ToNumericCode());
Operator const* op = node->opcode() == IrOpcode::kJSToNumber
? ToNumberOperator()
: ToNumericOperator();
Node* code = node->opcode() == IrOpcode::kJSToNumber ? ToNumberCode()
: ToNumericCode();
vfalse0 = efalse0 = if_false0 = graph()->NewNode(
op, code, value, context, frame_state, efalse0, if_false0);
@ -3400,7 +3392,6 @@ void SimplifiedLowering::DoJSToNumberOrNumericTruncatesToFloat64(
void SimplifiedLowering::DoJSToNumberOrNumericTruncatesToWord32(
Node* node, RepresentationSelector* selector) {
DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
node->opcode() == IrOpcode::kJSToNumeric);
Node* value = node->InputAt(0);
Node* context = node->InputAt(1);
@ -3421,17 +3412,11 @@ void SimplifiedLowering::DoJSToNumberOrNumericTruncatesToWord32(
Node* efalse0 = effect;
Node* vfalse0;
{
Operator const* op =
node->opcode() == IrOpcode::kJSToNumber
? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
? ToNumberConvertBigIntOperator()
: ToNumberOperator())
: ToNumericOperator();
Node* code = node->opcode() == IrOpcode::kJSToNumber
? ToNumberCode()
: (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
? ToNumberConvertBigIntCode()
: ToNumericCode());
Operator const* op = node->opcode() == IrOpcode::kJSToNumber
? ToNumberOperator()
: ToNumericOperator();
Node* code = node->opcode() == IrOpcode::kJSToNumber ? ToNumberCode()
: ToNumericCode();
vfalse0 = efalse0 = if_false0 = graph()->NewNode(
op, code, value, context, frame_state, efalse0, if_false0);
@ -3937,16 +3922,6 @@ Node* SimplifiedLowering::ToNumberCode() {
return to_number_code_.get();
}
Node* SimplifiedLowering::ToNumberConvertBigIntCode() {
if (!to_number_convert_big_int_code_.is_set()) {
Callable callable =
Builtins::CallableFor(isolate(), Builtins::kToNumberConvertBigInt);
to_number_convert_big_int_code_.set(
jsgraph()->HeapConstant(callable.code()));
}
return to_number_convert_big_int_code_.get();
}
Node* SimplifiedLowering::ToNumericCode() {
if (!to_numeric_code_.is_set()) {
Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumeric);
@ -3967,19 +3942,6 @@ Operator const* SimplifiedLowering::ToNumberOperator() {
return to_number_operator_.get();
}
Operator const* SimplifiedLowering::ToNumberConvertBigIntOperator() {
if (!to_number_convert_big_int_operator_.is_set()) {
Callable callable =
Builtins::CallableFor(isolate(), Builtins::kToNumberConvertBigInt);
CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
auto call_descriptor =
Linkage::GetStubCallDescriptor(graph()->zone(), callable.descriptor(),
0, flags, Operator::kNoProperties);
to_number_convert_big_int_operator_.set(common()->Call(call_descriptor));
}
return to_number_convert_big_int_operator_.get();
}
Operator const* SimplifiedLowering::ToNumericOperator() {
if (!to_numeric_operator_.is_set()) {
Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumeric);

View File

@ -52,10 +52,8 @@ class V8_EXPORT_PRIVATE SimplifiedLowering final {
Zone* const zone_;
TypeCache const& type_cache_;
SetOncePointer<Node> to_number_code_;
SetOncePointer<Node> to_number_convert_big_int_code_;
SetOncePointer<Node> to_numeric_code_;
SetOncePointer<Operator const> to_number_operator_;
SetOncePointer<Operator const> to_number_convert_big_int_operator_;
SetOncePointer<Operator const> to_numeric_operator_;
// TODO(danno): SimplifiedLowering shouldn't know anything about the source
@ -78,10 +76,8 @@ class V8_EXPORT_PRIVATE SimplifiedLowering final {
Node* Uint32Mod(Node* const node);
Node* ToNumberCode();
Node* ToNumberConvertBigIntCode();
Node* ToNumericCode();
Operator const* ToNumberOperator();
Operator const* ToNumberConvertBigIntOperator();
Operator const* ToNumericOperator();
friend class RepresentationSelector;

View File

@ -266,7 +266,6 @@ class Typer::Visitor : public Reducer {
static Type ToLength(Type, Typer*);
static Type ToName(Type, Typer*);
static Type ToNumber(Type, Typer*);
static Type ToNumberConvertBigInt(Type, Typer*);
static Type ToNumeric(Type, Typer*);
static Type ToObject(Type, Typer*);
static Type ToString(Type, Typer*);
@ -530,11 +529,6 @@ Type Typer::Visitor::ToNumber(Type type, Typer* t) {
return t->operation_typer_.ToNumber(type);
}
// static
Type Typer::Visitor::ToNumberConvertBigInt(Type type, Typer* t) {
return t->operation_typer_.ToNumberConvertBigInt(type);
}
// static
Type Typer::Visitor::ToNumeric(Type type, Typer* t) {
return t->operation_typer_.ToNumeric(type);
@ -1131,10 +1125,6 @@ Type Typer::Visitor::TypeJSToNumber(Node* node) {
return TypeUnaryOp(node, ToNumber);
}
Type Typer::Visitor::TypeJSToNumberConvertBigInt(Node* node) {
return TypeUnaryOp(node, ToNumberConvertBigInt);
}
Type Typer::Visitor::TypeJSToNumeric(Node* node) {
return TypeUnaryOp(node, ToNumeric);
}

View File

@ -629,7 +629,6 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
CheckTypeIs(node, Type::Name());
break;
case IrOpcode::kJSToNumber:
case IrOpcode::kJSToNumberConvertBigInt:
// Type is Number.
CheckTypeIs(node, Type::Number());
break;

View File

@ -605,8 +605,7 @@ static void CheckIsConvertedToNumber(Node* val, Node* converted) {
CHECK_EQ(val, converted);
} else {
if (converted->opcode() == IrOpcode::kNumberConstant) return;
CHECK(IrOpcode::kJSToNumber == converted->opcode() ||
IrOpcode::kJSToNumberConvertBigInt == converted->opcode());
CHECK_EQ(IrOpcode::kJSToNumber, converted->opcode());
CHECK_EQ(val, converted->InputAt(0));
}
}

View File

@ -1039,19 +1039,6 @@
{"name": "OneLineComments"},
{"name": "MultiLineComment"}
]
},
{
"name": "Numbers",
"path": ["Numbers"],
"main": "run.js",
"flags": ["--allow-natives-syntax"],
"resources": [ "toNumber.js"],
"results_regexp": "^%s\\-Numbers\\(Score\\): (.+)$",
"tests": [
{"name": "Constructor"},
{"name": "UnaryPlus"},
{"name": "ParseFloat"}
]
}
]
}

View File

@ -1,20 +0,0 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
load('../base.js');
load('toNumber.js');
function PrintResult(name, result) {
console.log(name);
console.log(name + '-Numbers(Score): ' + result);
}
function PrintError(name, error) {
PrintResult(name, error);
}
BenchmarkSuite.config.doWarmup = undefined;
BenchmarkSuite.config.doDeterministic = undefined;
BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
NotifyError: PrintError });

View File

@ -1,25 +0,0 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const A = [undefined, 12, "123"];
function NumberConstructor() {
Number.isNaN(Number(A[0]))
Number.isNaN(Number(A[1]))
Number.isNaN(Number(A[2]))
}
createSuite('Constructor', 1000, NumberConstructor, ()=>{});
function NumberPlus() {
Number.isNaN(+(A[0]))
Number.isNaN(+(A[1]))
Number.isNaN(+(A[2]))
}
createSuite('UnaryPlus', 1000, NumberPlus, ()=>{});
function NumberParseFloat() {
Number.isNaN(parseFloat(A[0]))
Number.isNaN(parseFloat(A[1]))
Number.isNaN(parseFloat(A[2]))
}
createSuite('ParseFloat', 1000, NumberParseFloat, ()=>{});

View File

@ -1,16 +0,0 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --harmony-bigint
function f(x, b) {
if (b) return Math.trunc(+(x))
else return Math.trunc(Number(x))
}
f("1", true);
f("2", true);
f("2", false);
%OptimizeFunctionOnNextCall(f);
f(3n);

View File

@ -31,7 +31,7 @@ function Test(f, ...cases) {
function V(input, expected_value) {
function check(result) {
assertFalse(result.exception, `unexpected exception ${result.value} on input ${input}`);
assertFalse(result.exception, input);
assertEquals(expected_value, result.value);
}
return {input, check};
@ -39,7 +39,7 @@ function V(input, expected_value) {
function E(input, expected_exception) {
function check(result) {
assertTrue(result.exception, `expected exception ${expected_exception.name} on input ${input}`);
assertTrue(result.exception, input);
assertInstanceof(result.value, expected_exception);
}
return {input, check};
@ -56,15 +56,10 @@ const six = {[Symbol.toPrimitive]() {return 6n}};
// inputs.
////////////////////////////////////////////////////////////////////////////////
Test(x => Number(x),
V(1n, 1), V(1, 1), V("", 0), V(1.4, 1.4), V(null, 0), V(six, 6));
Test(x => Math.trunc(+x),
E(1n, TypeError), V(1, 1), V("", 0), V(1.4, 1), V(null, 0), E(six, TypeError));
Test(x => Math.trunc(Number(x)),
V(1n, 1), V(1, 1), V("", 0), V(1.4, 1), V(null, 0), V(six, 6));
Test(x => String(x),
V(1n, "1"), V(1, "1"), V(1.4, "1.4"), V(null, "null"), V(six, "6"));