| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/compilation-dependencies.h" | 6 #include "src/compilation-dependencies.h" |
| 7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
| 8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
| 9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
| 10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node_->op())); | 55 DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node_->op())); |
| 56 CompareOperationHints hints = CompareOperationHintsOf(node_->op()); | 56 CompareOperationHints hints = CompareOperationHintsOf(node_->op()); |
| 57 CompareOperationHints::Hint combined = hints.combined(); | 57 CompareOperationHints::Hint combined = hints.combined(); |
| 58 if (combined == CompareOperationHints::kSignedSmall || | 58 if (combined == CompareOperationHints::kSignedSmall || |
| 59 combined == CompareOperationHints::kNumber) { | 59 combined == CompareOperationHints::kNumber) { |
| 60 return combined; | 60 return combined; |
| 61 } | 61 } |
| 62 return CompareOperationHints::kAny; | 62 return CompareOperationHints::kAny; |
| 63 } | 63 } |
| 64 | 64 |
| 65 void ConvertInputsToNumber(Node* frame_state) { | 65 void ConvertInputsToNumber() { |
| 66 // To convert the inputs to numbers, we have to provide frame states | 66 // To convert the inputs to numbers, we have to provide frame states |
| 67 // for lazy bailouts in the ToNumber conversions. | 67 // for lazy bailouts in the ToNumber conversions. |
| 68 // We use a little hack here: we take the frame state before the binary | 68 // We use a little hack here: we take the frame state before the binary |
| 69 // operation and use it to construct the frame states for the conversion | 69 // operation and use it to construct the frame states for the conversion |
| 70 // so that after the deoptimization, the binary operation IC gets | 70 // so that after the deoptimization, the binary operation IC gets |
| 71 // already converted values from full code. This way we are sure that we | 71 // already converted values from full code. This way we are sure that we |
| 72 // will not re-do any of the side effects. | 72 // will not re-do any of the side effects. |
| 73 | 73 |
| 74 Node* left_input = nullptr; | 74 Node* left_input = nullptr; |
| 75 Node* right_input = nullptr; | 75 Node* right_input = nullptr; |
| 76 bool left_is_primitive = left_type()->Is(Type::PlainPrimitive()); | 76 bool left_is_primitive = left_type()->Is(Type::PlainPrimitive()); |
| 77 bool right_is_primitive = right_type()->Is(Type::PlainPrimitive()); | 77 bool right_is_primitive = right_type()->Is(Type::PlainPrimitive()); |
| 78 bool handles_exception = NodeProperties::IsExceptionalCall(node_); | 78 bool handles_exception = NodeProperties::IsExceptionalCall(node_); |
| 79 | 79 |
| 80 if (!left_is_primitive && !right_is_primitive && handles_exception) { | 80 if (!left_is_primitive && !right_is_primitive && handles_exception) { |
| 81 ConvertBothInputsToNumber(&left_input, &right_input, frame_state); | 81 ConvertBothInputsToNumber(&left_input, &right_input); |
| 82 } else { | 82 } else { |
| 83 left_input = left_is_primitive | 83 left_input = left_is_primitive |
| 84 ? ConvertPlainPrimitiveToNumber(left()) | 84 ? ConvertPlainPrimitiveToNumber(left()) |
| 85 : ConvertSingleInputToNumber( | 85 : ConvertSingleInputToNumber( |
| 86 left(), CreateFrameStateForLeftInput(frame_state)); | 86 left(), CreateFrameStateForLeftInput()); |
| 87 right_input = right_is_primitive | 87 right_input = |
| 88 ? ConvertPlainPrimitiveToNumber(right()) | 88 right_is_primitive |
| 89 : ConvertSingleInputToNumber( | 89 ? ConvertPlainPrimitiveToNumber(right()) |
| 90 right(), CreateFrameStateForRightInput( | 90 : ConvertSingleInputToNumber( |
| 91 frame_state, left_input)); | 91 right(), CreateFrameStateForRightInput(left_input)); |
| 92 } | 92 } |
| 93 | 93 |
| 94 node_->ReplaceInput(0, left_input); | 94 node_->ReplaceInput(0, left_input); |
| 95 node_->ReplaceInput(1, right_input); | 95 node_->ReplaceInput(1, right_input); |
| 96 } | 96 } |
| 97 | 97 |
| 98 void ConvertInputsToUI32(Signedness left_signedness, | 98 void ConvertInputsToUI32(Signedness left_signedness, |
| 99 Signedness right_signedness) { | 99 Signedness right_signedness) { |
| 100 node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness)); | 100 node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness)); |
| 101 node_->ReplaceInput(1, ConvertToUI32(right(), right_signedness)); | 101 node_->ReplaceInput(1, ConvertToUI32(right(), right_signedness)); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 JSGraph* jsgraph() { return lowering_->jsgraph(); } | 222 JSGraph* jsgraph() { return lowering_->jsgraph(); } |
| 223 JSOperatorBuilder* javascript() { return lowering_->javascript(); } | 223 JSOperatorBuilder* javascript() { return lowering_->javascript(); } |
| 224 MachineOperatorBuilder* machine() { return lowering_->machine(); } | 224 MachineOperatorBuilder* machine() { return lowering_->machine(); } |
| 225 CommonOperatorBuilder* common() { return jsgraph()->common(); } | 225 CommonOperatorBuilder* common() { return jsgraph()->common(); } |
| 226 Zone* zone() const { return graph()->zone(); } | 226 Zone* zone() const { return graph()->zone(); } |
| 227 | 227 |
| 228 private: | 228 private: |
| 229 JSTypedLowering* lowering_; // The containing lowering instance. | 229 JSTypedLowering* lowering_; // The containing lowering instance. |
| 230 Node* node_; // The original node. | 230 Node* node_; // The original node. |
| 231 | 231 |
| 232 Node* CreateFrameStateForLeftInput(Node* frame_state) { | 232 Node* CreateFrameStateForLeftInput() { |
| 233 Node* frame_state = NodeProperties::GetFrameStateInput(node_, 1); |
| 233 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); | 234 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); |
| 234 | 235 |
| 235 if (state_info.bailout_id() == BailoutId::None()) { | 236 if (state_info.bailout_id() == BailoutId::None()) { |
| 236 // Dummy frame state => just leave it as is. | 237 // Dummy frame state => just leave it as is. |
| 237 return frame_state; | 238 return frame_state; |
| 238 } | 239 } |
| 239 | 240 |
| 240 // If the frame state is already the right one, just return it. | 241 // If the frame state is already the right one, just return it. |
| 241 if (state_info.state_combine().kind() == OutputFrameStateCombine::kPokeAt && | 242 if (state_info.state_combine().kind() == OutputFrameStateCombine::kPokeAt && |
| 242 state_info.state_combine().GetOffsetToPokeAt() == 1) { | 243 state_info.state_combine().GetOffsetToPokeAt() == 1) { |
| 243 return frame_state; | 244 return frame_state; |
| 244 } | 245 } |
| 245 | 246 |
| 246 // Here, we smash the result of the conversion into the slot just below | 247 // Here, we smash the result of the conversion into the slot just below |
| 247 // the stack top. This is the slot that full code uses to store the | 248 // the stack top. This is the slot that full code uses to store the |
| 248 // left operand. | 249 // left operand. |
| 249 const Operator* op = jsgraph()->common()->FrameState( | 250 const Operator* op = jsgraph()->common()->FrameState( |
| 250 state_info.bailout_id(), OutputFrameStateCombine::PokeAt(1), | 251 state_info.bailout_id(), OutputFrameStateCombine::PokeAt(1), |
| 251 state_info.function_info()); | 252 state_info.function_info()); |
| 252 | 253 |
| 253 return graph()->NewNode(op, | 254 return graph()->NewNode(op, |
| 254 frame_state->InputAt(kFrameStateParametersInput), | 255 frame_state->InputAt(kFrameStateParametersInput), |
| 255 frame_state->InputAt(kFrameStateLocalsInput), | 256 frame_state->InputAt(kFrameStateLocalsInput), |
| 256 frame_state->InputAt(kFrameStateStackInput), | 257 frame_state->InputAt(kFrameStateStackInput), |
| 257 frame_state->InputAt(kFrameStateContextInput), | 258 frame_state->InputAt(kFrameStateContextInput), |
| 258 frame_state->InputAt(kFrameStateFunctionInput), | 259 frame_state->InputAt(kFrameStateFunctionInput), |
| 259 frame_state->InputAt(kFrameStateOuterStateInput)); | 260 frame_state->InputAt(kFrameStateOuterStateInput)); |
| 260 } | 261 } |
| 261 | 262 |
| 262 Node* CreateFrameStateForRightInput(Node* frame_state, Node* converted_left) { | 263 Node* CreateFrameStateForRightInput(Node* converted_left) { |
| 264 Node* frame_state = NodeProperties::GetFrameStateInput(node_, 1); |
| 263 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); | 265 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); |
| 264 | 266 |
| 265 if (state_info.bailout_id() == BailoutId::None()) { | 267 if (state_info.bailout_id() == BailoutId::None()) { |
| 266 // Dummy frame state => just leave it as is. | 268 // Dummy frame state => just leave it as is. |
| 267 return frame_state; | 269 return frame_state; |
| 268 } | 270 } |
| 269 | 271 |
| 270 // Create a frame state that stores the result of the operation to the | 272 // Create a frame state that stores the result of the operation to the |
| 271 // top of the stack (i.e., the slot used for the right operand). | 273 // top of the stack (i.e., the slot used for the right operand). |
| 272 const Operator* op = jsgraph()->common()->FrameState( | 274 const Operator* op = jsgraph()->common()->FrameState( |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 DCHECK(!NodeProperties::GetType(node)->Is(Type::PlainPrimitive())); | 315 DCHECK(!NodeProperties::GetType(node)->Is(Type::PlainPrimitive())); |
| 314 Node* const n = graph()->NewNode(javascript()->ToNumber(), node, context(), | 316 Node* const n = graph()->NewNode(javascript()->ToNumber(), node, context(), |
| 315 frame_state, effect(), control()); | 317 frame_state, effect(), control()); |
| 316 Node* const if_success = graph()->NewNode(common()->IfSuccess(), n); | 318 Node* const if_success = graph()->NewNode(common()->IfSuccess(), n); |
| 317 NodeProperties::ReplaceControlInput(node_, if_success); | 319 NodeProperties::ReplaceControlInput(node_, if_success); |
| 318 NodeProperties::ReplaceUses(node_, node_, node_, node_, n); | 320 NodeProperties::ReplaceUses(node_, node_, node_, node_, n); |
| 319 update_effect(n); | 321 update_effect(n); |
| 320 return n; | 322 return n; |
| 321 } | 323 } |
| 322 | 324 |
| 323 void ConvertBothInputsToNumber(Node** left_result, Node** right_result, | 325 void ConvertBothInputsToNumber(Node** left_result, Node** right_result) { |
| 324 Node* frame_state) { | |
| 325 Node* projections[2]; | 326 Node* projections[2]; |
| 326 | 327 |
| 327 // Find {IfSuccess} and {IfException} continuations of the operation. | 328 // Find {IfSuccess} and {IfException} continuations of the operation. |
| 328 NodeProperties::CollectControlProjections(node_, projections, 2); | 329 NodeProperties::CollectControlProjections(node_, projections, 2); |
| 329 IfExceptionHint hint = OpParameter<IfExceptionHint>(projections[1]); | 330 IfExceptionHint hint = OpParameter<IfExceptionHint>(projections[1]); |
| 330 Node* if_exception = projections[1]; | 331 Node* if_exception = projections[1]; |
| 331 Node* if_success = projections[0]; | 332 Node* if_success = projections[0]; |
| 332 | 333 |
| 333 // Insert two ToNumber() operations that both potentially throw. | 334 // Insert two ToNumber() operations that both potentially throw. |
| 334 Node* left_state = CreateFrameStateForLeftInput(frame_state); | 335 Node* left_state = CreateFrameStateForLeftInput(); |
| 335 Node* left_conv = | 336 Node* left_conv = |
| 336 graph()->NewNode(javascript()->ToNumber(), left(), context(), | 337 graph()->NewNode(javascript()->ToNumber(), left(), context(), |
| 337 left_state, effect(), control()); | 338 left_state, effect(), control()); |
| 338 Node* left_success = graph()->NewNode(common()->IfSuccess(), left_conv); | 339 Node* left_success = graph()->NewNode(common()->IfSuccess(), left_conv); |
| 339 Node* right_state = CreateFrameStateForRightInput(frame_state, left_conv); | 340 Node* right_state = CreateFrameStateForRightInput(left_conv); |
| 340 Node* right_conv = | 341 Node* right_conv = |
| 341 graph()->NewNode(javascript()->ToNumber(), right(), context(), | 342 graph()->NewNode(javascript()->ToNumber(), right(), context(), |
| 342 right_state, left_conv, left_success); | 343 right_state, left_conv, left_success); |
| 343 Node* left_exception = | 344 Node* left_exception = |
| 344 graph()->NewNode(common()->IfException(hint), left_conv, left_conv); | 345 graph()->NewNode(common()->IfException(hint), left_conv, left_conv); |
| 345 Node* right_exception = | 346 Node* right_exception = |
| 346 graph()->NewNode(common()->IfException(hint), right_conv, right_conv); | 347 graph()->NewNode(common()->IfException(hint), right_conv, right_conv); |
| 347 NodeProperties::ReplaceControlInput(if_success, right_conv); | 348 NodeProperties::ReplaceControlInput(if_success, right_conv); |
| 348 update_effect(right_conv); | 349 update_effect(right_conv); |
| 349 | 350 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 Reduction JSTypedLowering::ReduceJSAdd(Node* node) { | 419 Reduction JSTypedLowering::ReduceJSAdd(Node* node) { |
| 419 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 420 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
| 420 | 421 |
| 421 JSBinopReduction r(this, node); | 422 JSBinopReduction r(this, node); |
| 422 | 423 |
| 423 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 424 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
| 424 if (feedback == BinaryOperationHints::kNumberOrUndefined && | 425 if (feedback == BinaryOperationHints::kNumberOrUndefined && |
| 425 r.BothInputsAre(Type::PlainPrimitive()) && | 426 r.BothInputsAre(Type::PlainPrimitive()) && |
| 426 r.NeitherInputCanBe(Type::StringOrReceiver())) { | 427 r.NeitherInputCanBe(Type::StringOrReceiver())) { |
| 427 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) | 428 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) |
| 428 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 429 r.ConvertInputsToNumber(); |
| 429 r.ConvertInputsToNumber(frame_state); | |
| 430 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); | 430 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); |
| 431 } | 431 } |
| 432 if (feedback != BinaryOperationHints::kAny) { | 432 if (feedback != BinaryOperationHints::kAny) { |
| 433 // Lower to the optimistic number binop. | 433 // Lower to the optimistic number binop. |
| 434 return r.ChangeToSpeculativeOperator( | 434 return r.ChangeToSpeculativeOperator( |
| 435 simplified()->SpeculativeNumberAdd(feedback), Type::Number()); | 435 simplified()->SpeculativeNumberAdd(feedback), Type::Number()); |
| 436 } | 436 } |
| 437 if (r.BothInputsAre(Type::Number())) { | 437 if (r.BothInputsAre(Type::Number())) { |
| 438 // JSAdd(x:number, y:number) => NumberAdd(x, y) | 438 // JSAdd(x:number, y:number) => NumberAdd(x, y) |
| 439 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 439 r.ConvertInputsToNumber(); |
| 440 r.ConvertInputsToNumber(frame_state); | |
| 441 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); | 440 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); |
| 442 } | 441 } |
| 443 if (r.NeitherInputCanBe(Type::StringOrReceiver())) { | 442 if (r.NeitherInputCanBe(Type::StringOrReceiver())) { |
| 444 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) | 443 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) |
| 445 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 444 r.ConvertInputsToNumber(); |
| 446 r.ConvertInputsToNumber(frame_state); | |
| 447 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); | 445 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); |
| 448 } | 446 } |
| 449 if (r.OneInputIs(Type::String())) { | 447 if (r.OneInputIs(Type::String())) { |
| 450 StringAddFlags flags = STRING_ADD_CHECK_NONE; | 448 StringAddFlags flags = STRING_ADD_CHECK_NONE; |
| 451 if (!r.LeftInputIs(Type::String())) { | 449 if (!r.LeftInputIs(Type::String())) { |
| 452 flags = STRING_ADD_CONVERT_LEFT; | 450 flags = STRING_ADD_CONVERT_LEFT; |
| 453 } else if (!r.RightInputIs(Type::String())) { | 451 } else if (!r.RightInputIs(Type::String())) { |
| 454 flags = STRING_ADD_CONVERT_RIGHT; | 452 flags = STRING_ADD_CONVERT_RIGHT; |
| 455 } | 453 } |
| 456 // JSAdd(x:string, y) => CallStub[StringAdd](x, y) | 454 // JSAdd(x:string, y) => CallStub[StringAdd](x, y) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 } | 486 } |
| 489 | 487 |
| 490 Reduction JSTypedLowering::ReduceJSSubtract(Node* node) { | 488 Reduction JSTypedLowering::ReduceJSSubtract(Node* node) { |
| 491 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 489 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
| 492 JSBinopReduction r(this, node); | 490 JSBinopReduction r(this, node); |
| 493 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 491 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
| 494 if (feedback == BinaryOperationHints::kNumberOrUndefined && | 492 if (feedback == BinaryOperationHints::kNumberOrUndefined && |
| 495 r.BothInputsAre(Type::PlainPrimitive())) { | 493 r.BothInputsAre(Type::PlainPrimitive())) { |
| 496 // JSSubtract(x:plain-primitive, y:plain-primitive) | 494 // JSSubtract(x:plain-primitive, y:plain-primitive) |
| 497 // => NumberSubtract(ToNumber(x), ToNumber(y)) | 495 // => NumberSubtract(ToNumber(x), ToNumber(y)) |
| 498 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 496 r.ConvertInputsToNumber(); |
| 499 r.ConvertInputsToNumber(frame_state); | |
| 500 return r.ChangeToPureOperator(simplified()->NumberSubtract(), | 497 return r.ChangeToPureOperator(simplified()->NumberSubtract(), |
| 501 Type::Number()); | 498 Type::Number()); |
| 502 } | 499 } |
| 503 if (feedback != BinaryOperationHints::kAny) { | 500 if (feedback != BinaryOperationHints::kAny) { |
| 504 // Lower to the optimistic number binop. | 501 // Lower to the optimistic number binop. |
| 505 return r.ChangeToSpeculativeOperator( | 502 return r.ChangeToSpeculativeOperator( |
| 506 simplified()->SpeculativeNumberSubtract(feedback), Type::Number()); | 503 simplified()->SpeculativeNumberSubtract(feedback), Type::Number()); |
| 507 } | 504 } |
| 508 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 505 r.ConvertInputsToNumber(); |
| 509 r.ConvertInputsToNumber(frame_state); | |
| 510 return r.ChangeToPureOperator(simplified()->NumberSubtract(), Type::Number()); | 506 return r.ChangeToPureOperator(simplified()->NumberSubtract(), Type::Number()); |
| 511 } | 507 } |
| 512 | 508 |
| 513 Reduction JSTypedLowering::ReduceJSMultiply(Node* node) { | 509 Reduction JSTypedLowering::ReduceJSMultiply(Node* node) { |
| 514 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 510 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
| 515 JSBinopReduction r(this, node); | 511 JSBinopReduction r(this, node); |
| 516 | 512 |
| 517 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 513 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
| 518 if (feedback != BinaryOperationHints::kAny) { | 514 if (feedback != BinaryOperationHints::kAny) { |
| 519 return r.ChangeToSpeculativeOperator( | 515 return r.ChangeToSpeculativeOperator( |
| 520 simplified()->SpeculativeNumberMultiply(feedback), Type::Number()); | 516 simplified()->SpeculativeNumberMultiply(feedback), Type::Number()); |
| 521 } | 517 } |
| 522 | 518 |
| 523 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 519 r.ConvertInputsToNumber(); |
| 524 r.ConvertInputsToNumber(frame_state); | |
| 525 return r.ChangeToPureOperator(simplified()->NumberMultiply(), Type::Number()); | 520 return r.ChangeToPureOperator(simplified()->NumberMultiply(), Type::Number()); |
| 526 } | 521 } |
| 527 | 522 |
| 528 Reduction JSTypedLowering::ReduceJSDivide(Node* node) { | 523 Reduction JSTypedLowering::ReduceJSDivide(Node* node) { |
| 529 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 524 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
| 530 JSBinopReduction r(this, node); | 525 JSBinopReduction r(this, node); |
| 531 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 526 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
| 532 if (feedback != BinaryOperationHints::kAny) { | 527 if (feedback != BinaryOperationHints::kAny) { |
| 533 return r.ChangeToSpeculativeOperator( | 528 return r.ChangeToSpeculativeOperator( |
| 534 simplified()->SpeculativeNumberDivide(feedback), Type::Number()); | 529 simplified()->SpeculativeNumberDivide(feedback), Type::Number()); |
| 535 } | 530 } |
| 536 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 531 r.ConvertInputsToNumber(); |
| 537 r.ConvertInputsToNumber(frame_state); | |
| 538 return r.ChangeToPureOperator(simplified()->NumberDivide(), Type::Number()); | 532 return r.ChangeToPureOperator(simplified()->NumberDivide(), Type::Number()); |
| 539 } | 533 } |
| 540 | 534 |
| 541 | 535 |
| 542 Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) { | 536 Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) { |
| 543 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 537 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
| 544 | 538 |
| 545 JSBinopReduction r(this, node); | 539 JSBinopReduction r(this, node); |
| 546 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 540 r.ConvertInputsToNumber(); |
| 547 r.ConvertInputsToNumber(frame_state); | |
| 548 r.ConvertInputsToUI32(kSigned, kSigned); | 541 r.ConvertInputsToUI32(kSigned, kSigned); |
| 549 return r.ChangeToPureOperator(intOp, Type::Integral32()); | 542 return r.ChangeToPureOperator(intOp, Type::Integral32()); |
| 550 } | 543 } |
| 551 | 544 |
| 552 | 545 |
| 553 Reduction JSTypedLowering::ReduceUI32Shift(Node* node, | 546 Reduction JSTypedLowering::ReduceUI32Shift(Node* node, |
| 554 Signedness left_signedness, | 547 Signedness left_signedness, |
| 555 const Operator* shift_op) { | 548 const Operator* shift_op) { |
| 556 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 549 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
| 557 | 550 |
| 558 JSBinopReduction r(this, node); | 551 JSBinopReduction r(this, node); |
| 559 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 552 r.ConvertInputsToNumber(); |
| 560 r.ConvertInputsToNumber(frame_state); | |
| 561 r.ConvertInputsToUI32(left_signedness, kUnsigned); | 553 r.ConvertInputsToUI32(left_signedness, kUnsigned); |
| 562 return r.ChangeToPureOperator(shift_op); | 554 return r.ChangeToPureOperator(shift_op); |
| 563 } | 555 } |
| 564 | 556 |
| 565 | 557 |
| 566 Reduction JSTypedLowering::ReduceJSComparison(Node* node) { | 558 Reduction JSTypedLowering::ReduceJSComparison(Node* node) { |
| 567 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 559 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
| 568 | 560 |
| 569 JSBinopReduction r(this, node); | 561 JSBinopReduction r(this, node); |
| 570 if (r.BothInputsAre(Type::String())) { | 562 if (r.BothInputsAre(Type::String())) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 594 | 586 |
| 595 CompareOperationHints::Hint hint = r.GetNumberCompareOperationFeedback(); | 587 CompareOperationHints::Hint hint = r.GetNumberCompareOperationFeedback(); |
| 596 if (hint != CompareOperationHints::kAny || | 588 if (hint != CompareOperationHints::kAny || |
| 597 r.OneInputCannotBe(Type::StringOrReceiver())) { | 589 r.OneInputCannotBe(Type::StringOrReceiver())) { |
| 598 const Operator* less_than; | 590 const Operator* less_than; |
| 599 const Operator* less_than_or_equal; | 591 const Operator* less_than_or_equal; |
| 600 if (hint != CompareOperationHints::kAny) { | 592 if (hint != CompareOperationHints::kAny) { |
| 601 less_than = simplified()->SpeculativeNumberLessThan(hint); | 593 less_than = simplified()->SpeculativeNumberLessThan(hint); |
| 602 less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint); | 594 less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint); |
| 603 } else { | 595 } else { |
| 604 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 596 r.ConvertInputsToNumber(); |
| 605 r.ConvertInputsToNumber(frame_state); | |
| 606 less_than = simplified()->NumberLessThan(); | 597 less_than = simplified()->NumberLessThan(); |
| 607 less_than_or_equal = simplified()->NumberLessThanOrEqual(); | 598 less_than_or_equal = simplified()->NumberLessThanOrEqual(); |
| 608 } | 599 } |
| 609 const Operator* comparison; | 600 const Operator* comparison; |
| 610 switch (node->opcode()) { | 601 switch (node->opcode()) { |
| 611 case IrOpcode::kJSLessThan: | 602 case IrOpcode::kJSLessThan: |
| 612 comparison = less_than; | 603 comparison = less_than; |
| 613 break; | 604 break; |
| 614 case IrOpcode::kJSGreaterThan: | 605 case IrOpcode::kJSGreaterThan: |
| 615 comparison = less_than; | 606 comparison = less_than; |
| (...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2026 } | 2017 } |
| 2027 | 2018 |
| 2028 | 2019 |
| 2029 CompilationDependencies* JSTypedLowering::dependencies() const { | 2020 CompilationDependencies* JSTypedLowering::dependencies() const { |
| 2030 return dependencies_; | 2021 return dependencies_; |
| 2031 } | 2022 } |
| 2032 | 2023 |
| 2033 } // namespace compiler | 2024 } // namespace compiler |
| 2034 } // namespace internal | 2025 } // namespace internal |
| 2035 } // namespace v8 | 2026 } // namespace v8 |
| OLD | NEW |