From 0bedf6f0614198d914d826e3a8def240fdf2bac8 Mon Sep 17 00:00:00 2001 From: bmeurer Date: Tue, 22 Mar 2016 08:42:24 -0700 Subject: [PATCH] [stubs] Introduce AddStub and SubtractStub. This adds two new stubs, AddStub and SubtractStub, for the plus and the minus operators, and hooks them up with TurboFan and Ignition. Especially the addition case is very heavy and we might want to look into splitting that up further into specialized stubs (similar to what we did with ToNumberStub recently). R=epertoso@chromium.org Review URL: https://codereview.chromium.org/1823083002 Cr-Commit-Position: refs/heads/master@{#34994} --- src/code-factory.cc | 12 + src/code-factory.h | 2 + src/code-stubs.cc | 534 +++++++++++++++++++++++++++ src/code-stubs.h | 18 + src/compiler/code-stub-assembler.cc | 10 + src/compiler/code-stub-assembler.h | 7 + src/compiler/js-generic-lowering.cc | 4 +- src/compiler/raw-machine-assembler.h | 2 + src/interpreter/interpreter.cc | 4 +- 9 files changed, 589 insertions(+), 4 deletions(-) diff --git a/src/code-factory.cc b/src/code-factory.cc index 12645512c8..1553e08da6 100644 --- a/src/code-factory.cc +++ b/src/code-factory.cc @@ -206,6 +206,18 @@ Callable CodeFactory::RegExpExec(Isolate* isolate) { return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); } +// static +Callable CodeFactory::Add(Isolate* isolate) { + AddStub stub(isolate); + return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); +} + +// static +Callable CodeFactory::Subtract(Isolate* isolate) { + SubtractStub stub(isolate); + return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); +} + // static Callable CodeFactory::LessThan(Isolate* isolate) { LessThanStub stub(isolate); diff --git a/src/code-factory.h b/src/code-factory.h index 9d2bce6aea..67e9a37bc9 100644 --- a/src/code-factory.h +++ b/src/code-factory.h @@ -79,6 +79,8 @@ class CodeFactory final { static Callable RegExpConstructResult(Isolate* isolate); static Callable RegExpExec(Isolate* isolate); + static Callable Add(Isolate* isolate); + static Callable Subtract(Isolate* isolate); static Callable LessThan(Isolate* isolate); static Callable LessThanOrEqual(Isolate* isolate); static Callable GreaterThan(Isolate* isolate); diff --git a/src/code-stubs.cc b/src/code-stubs.cc index 423cafdf3a..fb5f8881dd 100644 --- a/src/code-stubs.cc +++ b/src/code-stubs.cc @@ -515,6 +515,540 @@ void StringLengthStub::GenerateAssembly( assembler->Return(result); } +void AddStub::GenerateAssembly(compiler::CodeStubAssembler* assembler) const { + typedef compiler::CodeStubAssembler::Label Label; + typedef compiler::Node Node; + typedef compiler::CodeStubAssembler::Variable Variable; + + Node* context = assembler->Parameter(2); + + // Shared entry for floating point addition. + Label do_fadd(assembler); + Variable var_fadd_lhs(assembler, MachineRepresentation::kFloat64), + var_fadd_rhs(assembler, MachineRepresentation::kFloat64); + + // We might need to loop several times due to ToPrimitive, ToString and/or + // ToNumber conversions. + Variable var_lhs(assembler, MachineRepresentation::kTagged), + var_rhs(assembler, MachineRepresentation::kTagged); + Variable* loop_vars[2] = {&var_lhs, &var_rhs}; + Label loop(assembler, 2, loop_vars); + var_lhs.Bind(assembler->Parameter(0)); + var_rhs.Bind(assembler->Parameter(1)); + assembler->Goto(&loop); + assembler->Bind(&loop); + { + // Load the current {lhs} and {rhs} values. + Node* lhs = var_lhs.value(); + Node* rhs = var_rhs.value(); + + // Check if the {lhs} is a Smi or a HeapObject. + Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); + assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); + + assembler->Bind(&if_lhsissmi); + { + // Check if the {rhs} is also a Smi. + Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); + assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, + &if_rhsisnotsmi); + + assembler->Bind(&if_rhsissmi); + { + // TODO(bmeurer): Properly fuse Int64AddWithOverflow on x64 + Node* pair = assembler->SmiAddWithOverflow(lhs, rhs); + Node* result = assembler->Projection(0, pair); + Node* overflow = assembler->Projection(1, pair); + + Label if_overflow(assembler), if_notoverflow(assembler); + assembler->Branch(overflow, &if_overflow, &if_notoverflow); + + assembler->Bind(&if_overflow); + { + var_fadd_lhs.Bind(assembler->SmiToFloat64(lhs)); + var_fadd_rhs.Bind(assembler->SmiToFloat64(rhs)); + assembler->Goto(&do_fadd); + } + + assembler->Bind(&if_notoverflow); + assembler->Return(result); + } + + assembler->Bind(&if_rhsisnotsmi); + { + // Load the map of {rhs}. + Node* rhs_map = assembler->LoadObjectField(rhs, HeapObject::kMapOffset); + + // Check if the {rhs} is a HeapNumber. + Label if_rhsisnumber(assembler), + if_rhsisnotnumber(assembler, Label::kDeferred); + Node* number_map = assembler->HeapNumberMapConstant(); + assembler->Branch(assembler->WordEqual(rhs_map, number_map), + &if_rhsisnumber, &if_rhsisnotnumber); + + assembler->Bind(&if_rhsisnumber); + { + var_fadd_lhs.Bind(assembler->SmiToFloat64(lhs)); + var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); + assembler->Goto(&do_fadd); + } + + assembler->Bind(&if_rhsisnotnumber); + { + // Load the instance type of {rhs}. + Node* rhs_instance_type = assembler->LoadMapInstanceType(rhs_map); + + // Check if the {rhs} is a String. + Label if_rhsisstring(assembler, Label::kDeferred), + if_rhsisnotstring(assembler, Label::kDeferred); + assembler->Branch(assembler->Int32LessThan( + rhs_instance_type, + assembler->Int32Constant(FIRST_NONSTRING_TYPE)), + &if_rhsisstring, &if_rhsisnotstring); + + assembler->Bind(&if_rhsisstring); + { + // Convert {lhs}, which is a Smi, to a String and concatenate the + // resulting string with the String {rhs}. + Callable callable = CodeFactory::StringAdd( + assembler->isolate(), STRING_ADD_CONVERT_LEFT, NOT_TENURED); + assembler->TailCallStub(callable, context, lhs, rhs); + } + + assembler->Bind(&if_rhsisnotstring); + { + // Check if {rhs} is a JSReceiver. + Label if_rhsisreceiver(assembler, Label::kDeferred), + if_rhsisnotreceiver(assembler, Label::kDeferred); + assembler->Branch( + assembler->Int32LessThanOrEqual( + assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE), + rhs_instance_type), + &if_rhsisreceiver, &if_rhsisnotreceiver); + + assembler->Bind(&if_rhsisreceiver); + { + // Convert {rhs} to a primitive first passing no hint. + // TODO(bmeurer): Hook up ToPrimitiveStub here, once it's there. + var_rhs.Bind( + assembler->CallRuntime(Runtime::kToPrimitive, context, rhs)); + assembler->Goto(&loop); + } + + assembler->Bind(&if_rhsisnotreceiver); + { + // Convert {rhs} to a Number first. + Callable callable = + CodeFactory::NonNumberToNumber(assembler->isolate()); + var_rhs.Bind(assembler->CallStub(callable, context, rhs)); + assembler->Goto(&loop); + } + } + } + } + } + + assembler->Bind(&if_lhsisnotsmi); + { + // Load the map and instance type of {lhs}. + Node* lhs_instance_type = assembler->LoadInstanceType(lhs); + + // Check if {lhs} is a String. + Label if_lhsisstring(assembler), if_lhsisnotstring(assembler); + assembler->Branch(assembler->Int32LessThan( + lhs_instance_type, + assembler->Int32Constant(FIRST_NONSTRING_TYPE)), + &if_lhsisstring, &if_lhsisnotstring); + + assembler->Bind(&if_lhsisstring); + { + // Convert {rhs} to a String (using the sequence of ToPrimitive with + // no hint followed by ToString) and concatenate the strings. + Callable callable = CodeFactory::StringAdd( + assembler->isolate(), STRING_ADD_CONVERT_RIGHT, NOT_TENURED); + assembler->TailCallStub(callable, context, lhs, rhs); + } + + assembler->Bind(&if_lhsisnotstring); + { + // Check if {rhs} is a Smi. + Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); + assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, + &if_rhsisnotsmi); + + assembler->Bind(&if_rhsissmi); + { + // Check if {lhs} is a Number. + Label if_lhsisnumber(assembler), + if_lhsisnotnumber(assembler, Label::kDeferred); + assembler->Branch(assembler->Word32Equal( + lhs_instance_type, + assembler->Int32Constant(HEAP_NUMBER_TYPE)), + &if_lhsisnumber, &if_lhsisnotnumber); + + assembler->Bind(&if_lhsisnumber); + { + // The {lhs} is a HeapNumber, the {rhs} is a Smi, just add them. + var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); + var_fadd_rhs.Bind(assembler->SmiToFloat64(rhs)); + assembler->Goto(&do_fadd); + } + + assembler->Bind(&if_lhsisnotnumber); + { + // The {lhs} is neither a Number nor a String, and the {rhs} is a + // Smi. + Label if_lhsisreceiver(assembler, Label::kDeferred), + if_lhsisnotreceiver(assembler, Label::kDeferred); + assembler->Branch( + assembler->Int32LessThanOrEqual( + assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE), + lhs_instance_type), + &if_lhsisreceiver, &if_lhsisnotreceiver); + + assembler->Bind(&if_lhsisreceiver); + { + // Convert {lhs} to a primitive first passing no hint. + // TODO(bmeurer): Hook up ToPrimitiveStub here, once it's there. + var_lhs.Bind( + assembler->CallRuntime(Runtime::kToPrimitive, context, lhs)); + assembler->Goto(&loop); + } + + assembler->Bind(&if_lhsisnotreceiver); + { + // Convert {lhs} to a Number first. + Callable callable = + CodeFactory::NonNumberToNumber(assembler->isolate()); + var_lhs.Bind(assembler->CallStub(callable, context, lhs)); + assembler->Goto(&loop); + } + } + } + + assembler->Bind(&if_rhsisnotsmi); + { + // Load the instance type of {rhs}. + Node* rhs_instance_type = assembler->LoadInstanceType(rhs); + + // Check if {rhs} is a String. + Label if_rhsisstring(assembler), if_rhsisnotstring(assembler); + assembler->Branch(assembler->Int32LessThan( + rhs_instance_type, + assembler->Int32Constant(FIRST_NONSTRING_TYPE)), + &if_rhsisstring, &if_rhsisnotstring); + + assembler->Bind(&if_rhsisstring); + { + // Convert {lhs} to a String (using the sequence of ToPrimitive with + // no hint followed by ToString) and concatenate the strings. + Callable callable = CodeFactory::StringAdd( + assembler->isolate(), STRING_ADD_CONVERT_LEFT, NOT_TENURED); + assembler->TailCallStub(callable, context, lhs, rhs); + } + + assembler->Bind(&if_rhsisnotstring); + { + // Check if {lhs} is a HeapNumber. + Label if_lhsisnumber(assembler), if_lhsisnotnumber(assembler); + assembler->Branch(assembler->Word32Equal( + lhs_instance_type, + assembler->Int32Constant(HEAP_NUMBER_TYPE)), + &if_lhsisnumber, &if_lhsisnotnumber); + + assembler->Bind(&if_lhsisnumber); + { + // Check if {rhs} is also a HeapNumber. + Label if_rhsisnumber(assembler), + if_rhsisnotnumber(assembler, Label::kDeferred); + assembler->Branch(assembler->Word32Equal( + rhs_instance_type, + assembler->Int32Constant(HEAP_NUMBER_TYPE)), + &if_rhsisnumber, &if_rhsisnotnumber); + + assembler->Bind(&if_rhsisnumber); + { + // Perform a floating point addition. + var_fadd_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); + var_fadd_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); + assembler->Goto(&do_fadd); + } + + assembler->Bind(&if_rhsisnotnumber); + { + // Check if {rhs} is a JSReceiver. + Label if_rhsisreceiver(assembler, Label::kDeferred), + if_rhsisnotreceiver(assembler, Label::kDeferred); + assembler->Branch( + assembler->Int32LessThanOrEqual( + assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE), + rhs_instance_type), + &if_rhsisreceiver, &if_rhsisnotreceiver); + + assembler->Bind(&if_rhsisreceiver); + { + // Convert {rhs} to a primitive first passing no hint. + // TODO(bmeurer): Hook up ToPrimitiveStub here too. + var_rhs.Bind(assembler->CallRuntime(Runtime::kToPrimitive, + context, rhs)); + assembler->Goto(&loop); + } + + assembler->Bind(&if_rhsisnotreceiver); + { + // Convert {rhs} to a Number first. + Callable callable = + CodeFactory::NonNumberToNumber(assembler->isolate()); + var_rhs.Bind(assembler->CallStub(callable, context, rhs)); + assembler->Goto(&loop); + } + } + } + + assembler->Bind(&if_lhsisnotnumber); + { + // Check if {lhs} is a JSReceiver. + Label if_lhsisreceiver(assembler, Label::kDeferred), + if_lhsisnotreceiver(assembler); + assembler->Branch( + assembler->Int32LessThanOrEqual( + assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE), + lhs_instance_type), + &if_lhsisreceiver, &if_lhsisnotreceiver); + + assembler->Bind(&if_lhsisreceiver); + { + // Convert {lhs} to a primitive first passing no hint. + // TODO(bmeurer): Hook up ToPrimitiveStub here, once it's there. + var_lhs.Bind(assembler->CallRuntime(Runtime::kToPrimitive, + context, lhs)); + assembler->Goto(&loop); + } + + assembler->Bind(&if_lhsisnotreceiver); + { + // Check if {rhs} is a JSReceiver. + Label if_rhsisreceiver(assembler, Label::kDeferred), + if_rhsisnotreceiver(assembler, Label::kDeferred); + assembler->Branch( + assembler->Int32LessThanOrEqual( + assembler->Int32Constant(FIRST_JS_RECEIVER_TYPE), + rhs_instance_type), + &if_rhsisreceiver, &if_rhsisnotreceiver); + + assembler->Bind(&if_rhsisreceiver); + { + // Convert {rhs} to a primitive first passing no hint. + // TODO(bmeurer): Hook up ToPrimitiveStub here too. + var_rhs.Bind(assembler->CallRuntime(Runtime::kToPrimitive, + context, rhs)); + assembler->Goto(&loop); + } + + assembler->Bind(&if_rhsisnotreceiver); + { + // Convert {lhs} to a Number first. + Callable callable = + CodeFactory::NonNumberToNumber(assembler->isolate()); + var_lhs.Bind(assembler->CallStub(callable, context, lhs)); + assembler->Goto(&loop); + } + } + } + } + } + } + } + } + + assembler->Bind(&do_fadd); + { + Node* lhs_value = var_fadd_lhs.value(); + Node* rhs_value = var_fadd_rhs.value(); + Node* value = assembler->Float64Add(lhs_value, rhs_value); + // TODO(bmeurer): Introduce a ChangeFloat64ToTagged. + Node* result = assembler->Allocate(HeapNumber::kSize, + compiler::CodeStubAssembler::kNone); + assembler->StoreMapNoWriteBarrier(result, + assembler->HeapNumberMapConstant()); + assembler->StoreHeapNumberValue(result, value); + assembler->Return(result); + } +} + +void SubtractStub::GenerateAssembly( + compiler::CodeStubAssembler* assembler) const { + typedef compiler::CodeStubAssembler::Label Label; + typedef compiler::Node Node; + typedef compiler::CodeStubAssembler::Variable Variable; + + Node* context = assembler->Parameter(2); + + // Shared entry for floating point subtraction. + Label do_fsub(assembler); + Variable var_fsub_lhs(assembler, MachineRepresentation::kFloat64), + var_fsub_rhs(assembler, MachineRepresentation::kFloat64); + + // We might need to loop several times due to ToPrimitive and/or ToNumber + // conversions. + Variable var_lhs(assembler, MachineRepresentation::kTagged), + var_rhs(assembler, MachineRepresentation::kTagged); + Variable* loop_vars[2] = {&var_lhs, &var_rhs}; + Label loop(assembler, 2, loop_vars); + var_lhs.Bind(assembler->Parameter(0)); + var_rhs.Bind(assembler->Parameter(1)); + assembler->Goto(&loop); + assembler->Bind(&loop); + { + // Load the current {lhs} and {rhs} values. + Node* lhs = var_lhs.value(); + Node* rhs = var_rhs.value(); + + // Check if the {lhs} is a Smi or a HeapObject. + Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); + assembler->Branch(assembler->WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); + + assembler->Bind(&if_lhsissmi); + { + // Check if the {rhs} is also a Smi. + Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); + assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, + &if_rhsisnotsmi); + + assembler->Bind(&if_rhsissmi); + { + // Try a fast Smi subtraction first. + Node* pair = assembler->SmiSubWithOverflow(lhs, rhs); + Node* result = assembler->Projection(0, pair); + Node* overflow = assembler->Projection(1, pair); + + // Check if the Smi subtraction overflowed. + Label if_overflow(assembler), if_notoverflow(assembler); + assembler->Branch(overflow, &if_overflow, &if_notoverflow); + + assembler->Bind(&if_overflow); + { + // The result doesn't fit into Smi range. + var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); + var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); + assembler->Goto(&do_fsub); + } + + assembler->Bind(&if_notoverflow); + assembler->Return(result); + } + + assembler->Bind(&if_rhsisnotsmi); + { + // Load the map of the {rhs}. + Node* rhs_map = assembler->LoadMap(rhs); + + // Check if {rhs} is a HeapNumber. + Label if_rhsisnumber(assembler), + if_rhsisnotnumber(assembler, Label::kDeferred); + Node* number_map = assembler->HeapNumberMapConstant(); + assembler->Branch(assembler->WordEqual(rhs_map, number_map), + &if_rhsisnumber, &if_rhsisnotnumber); + + assembler->Bind(&if_rhsisnumber); + { + // Perform a floating point subtraction. + var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); + var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); + assembler->Goto(&do_fsub); + } + + assembler->Bind(&if_rhsisnotnumber); + { + // Convert the {rhs} to a Number first. + Callable callable = CodeFactory::NonNumberToNumber(isolate()); + var_rhs.Bind(assembler->CallStub(callable, context, rhs)); + assembler->Goto(&loop); + } + } + } + + assembler->Bind(&if_lhsisnotsmi); + { + // Load the map of the {lhs}. + Node* lhs_map = assembler->LoadMap(lhs); + + // Check if the {lhs} is a HeapNumber. + Label if_lhsisnumber(assembler), + if_lhsisnotnumber(assembler, Label::kDeferred); + Node* number_map = assembler->HeapNumberMapConstant(); + assembler->Branch(assembler->WordEqual(lhs_map, number_map), + &if_lhsisnumber, &if_lhsisnotnumber); + + assembler->Bind(&if_lhsisnumber); + { + // Check if the {rhs} is a Smi. + Label if_rhsissmi(assembler), if_rhsisnotsmi(assembler); + assembler->Branch(assembler->WordIsSmi(rhs), &if_rhsissmi, + &if_rhsisnotsmi); + + assembler->Bind(&if_rhsissmi); + { + // Perform a floating point subtraction. + var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); + var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); + assembler->Goto(&do_fsub); + } + + assembler->Bind(&if_rhsisnotsmi); + { + // Load the map of the {rhs}. + Node* rhs_map = assembler->LoadMap(rhs); + + // Check if the {rhs} is a HeapNumber. + Label if_rhsisnumber(assembler), + if_rhsisnotnumber(assembler, Label::kDeferred); + assembler->Branch(assembler->WordEqual(rhs_map, number_map), + &if_rhsisnumber, &if_rhsisnotnumber); + + assembler->Bind(&if_rhsisnumber); + { + // Perform a floating point subtraction. + var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); + var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); + assembler->Goto(&do_fsub); + } + + assembler->Bind(&if_rhsisnotnumber); + { + // Convert the {rhs} to a Number first. + Callable callable = CodeFactory::NonNumberToNumber(isolate()); + var_rhs.Bind(assembler->CallStub(callable, context, rhs)); + assembler->Goto(&loop); + } + } + } + + assembler->Bind(&if_lhsisnotnumber); + { + // Convert the {lhs} to a Number first. + Callable callable = CodeFactory::NonNumberToNumber(isolate()); + var_lhs.Bind(assembler->CallStub(callable, context, lhs)); + assembler->Goto(&loop); + } + } + } + + assembler->Bind(&do_fsub); + { + Node* lhs_value = var_fsub_lhs.value(); + Node* rhs_value = var_fsub_rhs.value(); + Node* value = assembler->Float64Sub(lhs_value, rhs_value); + // TODO(bmeurer): Introduce a ChangeFloat64ToTagged. + Node* result = assembler->Allocate(HeapNumber::kSize, + compiler::CodeStubAssembler::kNone); + assembler->StoreMapNoWriteBarrier(result, + assembler->HeapNumberMapConstant()); + assembler->StoreHeapNumberValue(result, value); + assembler->Return(result); + } +} + namespace { enum RelationalComparisonMode { diff --git a/src/code-stubs.h b/src/code-stubs.h index 5bf8c3e8b7..66d409abbf 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -111,6 +111,8 @@ namespace internal { V(AllocateUint8x16) \ V(AllocateBool8x16) \ V(StringLength) \ + V(Add) \ + V(Subtract) \ V(LessThan) \ V(LessThanOrEqual) \ V(GreaterThan) \ @@ -667,6 +669,22 @@ class StringLengthStub : public TurboFanCodeStub { DEFINE_TURBOFAN_CODE_STUB(StringLength, TurboFanCodeStub); }; +class AddStub final : public TurboFanCodeStub { + public: + explicit AddStub(Isolate* isolate) : TurboFanCodeStub(isolate) {} + + DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp); + DEFINE_TURBOFAN_CODE_STUB(Add, TurboFanCodeStub); +}; + +class SubtractStub final : public TurboFanCodeStub { + public: + explicit SubtractStub(Isolate* isolate) : TurboFanCodeStub(isolate) {} + + DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp); + DEFINE_TURBOFAN_CODE_STUB(Subtract, TurboFanCodeStub); +}; + class LessThanStub final : public TurboFanCodeStub { public: explicit LessThanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {} diff --git a/src/compiler/code-stub-assembler.cc b/src/compiler/code-stub-assembler.cc index 741ce521e7..89a21d7245 100644 --- a/src/compiler/code-stub-assembler.cc +++ b/src/compiler/code-stub-assembler.cc @@ -175,6 +175,16 @@ Node* CodeStubAssembler::SmiToFloat64(Node* value) { Node* CodeStubAssembler::SmiAdd(Node* a, Node* b) { return IntPtrAdd(a, b); } +Node* CodeStubAssembler::SmiAddWithOverflow(Node* a, Node* b) { + return IntPtrAddWithOverflow(a, b); +} + +Node* CodeStubAssembler::SmiSub(Node* a, Node* b) { return IntPtrSub(a, b); } + +Node* CodeStubAssembler::SmiSubWithOverflow(Node* a, Node* b) { + return IntPtrSubWithOverflow(a, b); +} + Node* CodeStubAssembler::SmiEqual(Node* a, Node* b) { return WordEqual(a, b); } Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) { diff --git a/src/compiler/code-stub-assembler.h b/src/compiler/code-stub-assembler.h index 3335bda7de..b380aedc15 100644 --- a/src/compiler/code-stub-assembler.h +++ b/src/compiler/code-stub-assembler.h @@ -63,8 +63,12 @@ class Schedule; #define CODE_STUB_ASSEMBLER_BINARY_OP_LIST(V) \ CODE_STUB_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \ + V(Float64Add) \ + V(Float64Sub) \ V(IntPtrAdd) \ + V(IntPtrAddWithOverflow) \ V(IntPtrSub) \ + V(IntPtrSubWithOverflow) \ V(Int32Add) \ V(Int32Sub) \ V(Int32Mul) \ @@ -263,6 +267,9 @@ class CodeStubAssembler { // Smi operations. Node* SmiAdd(Node* a, Node* b); + Node* SmiAddWithOverflow(Node* a, Node* b); + Node* SmiSub(Node* a, Node* b); + Node* SmiSubWithOverflow(Node* a, Node* b); Node* SmiEqual(Node* a, Node* b); Node* SmiLessThan(Node* a, Node* b); Node* SmiLessThanOrEqual(Node* a, Node* b); diff --git a/src/compiler/js-generic-lowering.cc b/src/compiler/js-generic-lowering.cc index 71f61ec456..1ee8de57c7 100644 --- a/src/compiler/js-generic-lowering.cc +++ b/src/compiler/js-generic-lowering.cc @@ -76,8 +76,6 @@ REPLACE_BINARY_OP_IC_CALL(JSBitwiseAnd, Token::BIT_AND) REPLACE_BINARY_OP_IC_CALL(JSShiftLeft, Token::SHL) REPLACE_BINARY_OP_IC_CALL(JSShiftRight, Token::SAR) REPLACE_BINARY_OP_IC_CALL(JSShiftRightLogical, Token::SHR) -REPLACE_BINARY_OP_IC_CALL(JSAdd, Token::ADD) -REPLACE_BINARY_OP_IC_CALL(JSSubtract, Token::SUB) REPLACE_BINARY_OP_IC_CALL(JSMultiply, Token::MUL) REPLACE_BINARY_OP_IC_CALL(JSDivide, Token::DIV) REPLACE_BINARY_OP_IC_CALL(JSModulus, Token::MOD) @@ -98,6 +96,8 @@ REPLACE_RUNTIME_CALL(JSConvertReceiver, Runtime::kConvertReceiver) Callable callable = CodeFactory::Name(isolate()); \ ReplaceWithStubCall(node, callable, flags); \ } +REPLACE_STUB_CALL(Add) +REPLACE_STUB_CALL(Subtract) REPLACE_STUB_CALL(LessThan) REPLACE_STUB_CALL(LessThanOrEqual) REPLACE_STUB_CALL(GreaterThan) diff --git a/src/compiler/raw-machine-assembler.h b/src/compiler/raw-machine-assembler.h index dc35bca98e..7a1621920a 100644 --- a/src/compiler/raw-machine-assembler.h +++ b/src/compiler/raw-machine-assembler.h @@ -347,7 +347,9 @@ class RawMachineAssembler { } INTPTR_BINOP(Int, Add); + INTPTR_BINOP(Int, AddWithOverflow); INTPTR_BINOP(Int, Sub); + INTPTR_BINOP(Int, SubWithOverflow); INTPTR_BINOP(Int, LessThan); INTPTR_BINOP(Int, LessThanOrEqual); INTPTR_BINOP(Word, Equal); diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc index 3e8a045d22..2284eef10e 100644 --- a/src/interpreter/interpreter.cc +++ b/src/interpreter/interpreter.cc @@ -650,7 +650,7 @@ void Interpreter::DoBinaryOp(Runtime::FunctionId function_id, // // Add register to accumulator. void Interpreter::DoAdd(InterpreterAssembler* assembler) { - DoBinaryOp(Runtime::kAdd, assembler); + DoBinaryOp(CodeFactory::Add(isolate_), assembler); } @@ -658,7 +658,7 @@ void Interpreter::DoAdd(InterpreterAssembler* assembler) { // // Subtract register from accumulator. void Interpreter::DoSub(InterpreterAssembler* assembler) { - DoBinaryOp(Runtime::kSubtract, assembler); + DoBinaryOp(CodeFactory::Subtract(isolate_), assembler); }