diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/v8/src/compiler/bytecode-graph-builder.cc | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/v8/src/compiler/bytecode-graph-builder.cc')
-rw-r--r-- | chromium/v8/src/compiler/bytecode-graph-builder.cc | 319 |
1 files changed, 223 insertions, 96 deletions
diff --git a/chromium/v8/src/compiler/bytecode-graph-builder.cc b/chromium/v8/src/compiler/bytecode-graph-builder.cc index b59b5a1b844..93aaca2512e 100644 --- a/chromium/v8/src/compiler/bytecode-graph-builder.cc +++ b/chromium/v8/src/compiler/bytecode-graph-builder.cc @@ -63,12 +63,30 @@ class BytecodeGraphBuilder { // Get or create the node that represents the outer function closure. Node* GetFunctionClosure(); + bool native_context_independent() const { + return native_context_independent_; + } + + // The node representing the current feedback vector is generated once prior + // to visiting bytecodes, and is later passed as input to other nodes that + // may need it. + // TODO(jgruber): Remove feedback_vector() and rename feedback_vector_node() + // to feedback_vector() once all uses of the direct heap object reference + // have been replaced with a Node* reference. + void CreateFeedbackVectorNode(); + Node* BuildLoadFeedbackVector(); + Node* feedback_vector_node() const { + DCHECK_NOT_NULL(feedback_vector_node_); + return feedback_vector_node_; + } + // Builder for loading the a native context field. Node* BuildLoadNativeContextField(int index); // Helper function for creating a feedback source containing type feedback // vector and a feedback slot. FeedbackSource CreateFeedbackSource(int slot_id); + FeedbackSource CreateFeedbackSource(FeedbackSlot slot); void set_environment(Environment* env) { environment_ = env; } const Environment* environment() const { return environment_; } @@ -191,6 +209,7 @@ class BytecodeGraphBuilder { void BuildUnaryOp(const Operator* op); void BuildBinaryOp(const Operator* op); void BuildBinaryOpWithImmediate(const Operator* op); + void BuildInstanceOf(const Operator* op); void BuildCompareOp(const Operator* op); void BuildDelete(LanguageMode language_mode); void BuildCastOperator(const Operator* op); @@ -243,14 +262,6 @@ class BytecodeGraphBuilder { Environment* CheckContextExtensionAtDepth(Environment* slow_environment, uint32_t depth); - // Helper function to create binary operation hint from the recorded - // type feedback. - BinaryOperationHint GetBinaryOperationHint(int operand_index); - - // Helper function to create compare operation hint from the recorded - // type feedback. - CompareOperationHint GetCompareOperationHint(); - // Helper function to create for-in mode from the recorded type feedback. ForInMode GetForInMode(int operand_index); @@ -423,6 +434,9 @@ class BytecodeGraphBuilder { int input_buffer_size_; Node** input_buffer_; + const bool native_context_independent_; + Node* feedback_vector_node_; + // Optimization to only create checkpoints when the current position in the // control-flow is not effect-dominated by another checkpoint already. All // operations that do not have observable side-effects can be re-evaluated. @@ -443,10 +457,11 @@ class BytecodeGraphBuilder { TickCounter* const tick_counter_; - static int const kBinaryOperationHintIndex = 1; - static int const kCountOperationHintIndex = 0; - static int const kBinaryOperationSmiHintIndex = 1; - static int const kUnaryOperationHintIndex = 0; + static constexpr int kBinaryOperationHintIndex = 1; + static constexpr int kBinaryOperationSmiHintIndex = 1; + static constexpr int kCompareOperationHintIndex = 1; + static constexpr int kCountOperationHintIndex = 0; + static constexpr int kUnaryOperationHintIndex = 0; DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilder); }; @@ -984,6 +999,9 @@ BytecodeGraphBuilder::BytecodeGraphBuilder( current_exception_handler_(0), input_buffer_size_(0), input_buffer_(nullptr), + native_context_independent_( + flags & BytecodeGraphBuilderFlag::kNativeContextIndependent), + feedback_vector_node_(nullptr), needs_eager_checkpoint_(true), exit_controls_(local_zone), state_values_cache_(jsgraph), @@ -1014,6 +1032,36 @@ Node* BytecodeGraphBuilder::GetFunctionClosure() { return function_closure_.get(); } +void BytecodeGraphBuilder::CreateFeedbackVectorNode() { + DCHECK_NULL(feedback_vector_node_); + feedback_vector_node_ = native_context_independent() + ? BuildLoadFeedbackVector() + : jsgraph()->Constant(feedback_vector()); +} + +Node* BytecodeGraphBuilder::BuildLoadFeedbackVector() { + DCHECK(native_context_independent()); + DCHECK_NULL(feedback_vector_node_); + + // The feedback vector must exist and remain live while the generated code + // lives. Specifically that means it must be created when NCI code is + // installed, and must not be flushed. + + Environment* env = environment(); + Node* control = env->GetControlDependency(); + Node* effect = env->GetEffectDependency(); + + Node* feedback_cell = effect = graph()->NewNode( + simplified()->LoadField(AccessBuilder::ForJSFunctionFeedbackCell()), + GetFunctionClosure(), effect, control); + Node* vector = effect = graph()->NewNode( + simplified()->LoadField(AccessBuilder::ForFeedbackCellValue()), + feedback_cell, effect, control); + + env->UpdateEffectDependency(effect); + return vector; +} + Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) { Node* result = NewNode(javascript()->LoadContext(0, index, true)); NodeProperties::ReplaceContextInput(result, @@ -1022,7 +1070,10 @@ Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) { } FeedbackSource BytecodeGraphBuilder::CreateFeedbackSource(int slot_id) { - FeedbackSlot slot = FeedbackVector::ToSlot(slot_id); + return CreateFeedbackSource(FeedbackVector::ToSlot(slot_id)); +} + +FeedbackSource BytecodeGraphBuilder::CreateFeedbackSource(FeedbackSlot slot) { return FeedbackSource(feedback_vector(), slot); } @@ -1042,6 +1093,7 @@ void BytecodeGraphBuilder::CreateGraph() { graph()->start()); set_environment(&env); + CreateFeedbackVectorNode(); VisitBytecodes(); // Finish the basic structure of the graph. @@ -2179,8 +2231,7 @@ void BytecodeGraphBuilder::VisitCreateObjectLiteral() { } void BytecodeGraphBuilder::VisitCreateEmptyObjectLiteral() { - Node* literal = - NewNode(javascript()->CreateEmptyLiteralObject(), GetFunctionClosure()); + Node* literal = NewNode(javascript()->CreateEmptyLiteralObject()); environment()->BindAccumulator(literal); } @@ -2210,10 +2261,7 @@ void BytecodeGraphBuilder::VisitGetTemplateObject() { Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters( Node* callee, Node* receiver, interpreter::Register first_arg, int arg_count) { - // The arity of the Call node -- includes the callee, receiver and function - // arguments. - int arity = 2 + arg_count; - + int arity = kTargetAndReceiver + arg_count; Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity)); all[0] = callee; @@ -2222,7 +2270,7 @@ Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters( // The function arguments are in consecutive registers. int arg_base = first_arg.index(); for (int i = 0; i < arg_count; ++i) { - all[2 + i] = + all[kTargetAndReceiver + i] = environment()->LookupRegister(interpreter::Register(arg_base + i)); } @@ -2247,7 +2295,8 @@ Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, Node* const* call_args = GetCallArgumentsFromRegisters(callee, receiver_node, first_arg, arg_count); - return ProcessCallArguments(call_op, call_args, 2 + arg_count); + return ProcessCallArguments(call_op, call_args, + kTargetAndReceiver + arg_count); } void BytecodeGraphBuilder::BuildCall(ConvertReceiverMode receiver_mode, @@ -2318,8 +2367,8 @@ void BytecodeGraphBuilder::BuildCallVarArgs(ConvertReceiverMode receiver_mode) { : static_cast<int>(reg_count) - 1; Node* const* call_args = ProcessCallVarArgs(receiver_mode, callee, first_reg, arg_count); - BuildCall(receiver_mode, call_args, static_cast<size_t>(2 + arg_count), - slot_id); + BuildCall(receiver_mode, call_args, + static_cast<size_t>(kTargetAndReceiver + arg_count), slot_id); } void BytecodeGraphBuilder::VisitCallAnyReceiver() { @@ -2341,9 +2390,7 @@ void BytecodeGraphBuilder::VisitCallNoFeedback() { // The receiver is the first register, followed by the arguments in the // consecutive registers. int arg_count = static_cast<int>(reg_count) - 1; - // The arity of the Call node -- includes the callee, receiver and function - // arguments. - int arity = 2 + arg_count; + int arity = kTargetAndReceiver + arg_count; // Setting call frequency to a value less than min_inlining frequency to // prevent inlining of one-shot call node. @@ -2459,7 +2506,7 @@ void BytecodeGraphBuilder::VisitCallWithSpread() { node = lowering.value(); } else { DCHECK(!lowering.Changed()); - node = ProcessCallArguments(op, args, 2 + arg_count); + node = ProcessCallArguments(op, args, kTargetAndReceiver + arg_count); } environment()->BindAccumulator(node, Environment::kAttachFrameState); } @@ -2472,10 +2519,11 @@ void BytecodeGraphBuilder::VisitCallJSRuntime() { size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); int arg_count = static_cast<int>(reg_count); - const Operator* call = javascript()->Call(2 + arg_count); + const Operator* call = javascript()->Call(kTargetAndReceiver + arg_count); Node* const* call_args = ProcessCallVarArgs( ConvertReceiverMode::kNullOrUndefined, callee, first_reg, arg_count); - Node* value = ProcessCallArguments(call, call_args, 2 + arg_count); + Node* value = + ProcessCallArguments(call, call_args, kTargetAndReceiver + arg_count); environment()->BindAccumulator(value, Environment::kAttachFrameState); } @@ -2532,8 +2580,7 @@ void BytecodeGraphBuilder::VisitCallRuntimeForPair() { Node* const* BytecodeGraphBuilder::GetConstructArgumentsFromRegister( Node* target, Node* new_target, interpreter::Register first_arg, int arg_count) { - // arity is args + callee and new target. - int arity = arg_count + 2; + int arity = kTargetAndNewTarget + arg_count; Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity)); all[0] = target; int first_arg_index = first_arg.index(); @@ -2563,9 +2610,10 @@ void BytecodeGraphBuilder::VisitConstruct() { Node* callee = environment()->LookupRegister(callee_reg); CallFrequency frequency = ComputeCallFrequency(slot_id); - const Operator* op = javascript()->Construct( - static_cast<uint32_t>(reg_count + 2), frequency, feedback); - int arg_count = static_cast<int>(reg_count); + const uint32_t arg_count = static_cast<uint32_t>(reg_count); + const uint32_t arg_count_with_extra_args = kTargetAndNewTarget + arg_count; + const Operator* op = + javascript()->Construct(arg_count_with_extra_args, frequency, feedback); Node* const* args = GetConstructArgumentsFromRegister(callee, new_target, first_reg, arg_count); JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct( @@ -2577,7 +2625,7 @@ void BytecodeGraphBuilder::VisitConstruct() { node = lowering.value(); } else { DCHECK(!lowering.Changed()); - node = ProcessConstructArguments(op, args, 2 + arg_count); + node = ProcessConstructArguments(op, args, arg_count_with_extra_args); } environment()->BindAccumulator(node, Environment::kAttachFrameState); } @@ -2594,9 +2642,10 @@ void BytecodeGraphBuilder::VisitConstructWithSpread() { Node* callee = environment()->LookupRegister(callee_reg); CallFrequency frequency = ComputeCallFrequency(slot_id); + const uint32_t arg_count = static_cast<uint32_t>(reg_count); + const uint32_t arg_count_with_extra_args = kTargetAndNewTarget + arg_count; const Operator* op = javascript()->ConstructWithSpread( - static_cast<uint32_t>(reg_count + 2), frequency, feedback); - int arg_count = static_cast<int>(reg_count); + arg_count_with_extra_args, frequency, feedback); Node* const* args = GetConstructArgumentsFromRegister(callee, new_target, first_reg, arg_count); JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct( @@ -2608,7 +2657,7 @@ void BytecodeGraphBuilder::VisitConstructWithSpread() { node = lowering.value(); } else { DCHECK(!lowering.Changed()); - node = ProcessConstructArguments(op, args, 2 + arg_count); + node = ProcessConstructArguments(op, args, arg_count_with_extra_args); } environment()->BindAccumulator(node, Environment::kAttachFrameState); } @@ -2711,6 +2760,7 @@ void BytecodeGraphBuilder::VisitThrowSuperAlreadyCalledIfNotHole() { } void BytecodeGraphBuilder::BuildUnaryOp(const Operator* op) { + DCHECK(JSOperator::IsUnaryWithFeedback(op->opcode())); PrepareEagerCheckpoint(); Node* operand = environment()->LookupAccumulator(); @@ -2725,13 +2775,14 @@ void BytecodeGraphBuilder::BuildUnaryOp(const Operator* op) { node = lowering.value(); } else { DCHECK(!lowering.Changed()); - node = NewNode(op, operand); + node = NewNode(op, operand, feedback_vector_node()); } environment()->BindAccumulator(node, Environment::kAttachFrameState); } void BytecodeGraphBuilder::BuildBinaryOp(const Operator* op) { + DCHECK(JSOperator::IsBinaryWithFeedback(op->opcode())); PrepareEagerCheckpoint(); Node* left = environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); @@ -2748,29 +2799,12 @@ void BytecodeGraphBuilder::BuildBinaryOp(const Operator* op) { node = lowering.value(); } else { DCHECK(!lowering.Changed()); - node = NewNode(op, left, right); + node = NewNode(op, left, right, feedback_vector_node()); } environment()->BindAccumulator(node, Environment::kAttachFrameState); } -// Helper function to create binary operation hint from the recorded type -// feedback. -BinaryOperationHint BytecodeGraphBuilder::GetBinaryOperationHint( - int operand_index) { - FeedbackSlot slot = bytecode_iterator().GetSlotOperand(operand_index); - FeedbackSource source(feedback_vector(), slot); - return broker()->GetFeedbackForBinaryOperation(source); -} - -// Helper function to create compare operation hint from the recorded type -// feedback. -CompareOperationHint BytecodeGraphBuilder::GetCompareOperationHint() { - FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1); - FeedbackSource source(feedback_vector(), slot); - return broker()->GetFeedbackForCompareOperation(source); -} - // Helper function to create for-in mode from the recorded type feedback. ForInMode BytecodeGraphBuilder::GetForInMode(int operand_index) { FeedbackSlot slot = bytecode_iterator().GetSlotOperand(operand_index); @@ -2810,69 +2844,103 @@ SpeculationMode BytecodeGraphBuilder::GetSpeculationMode(int slot_id) const { } void BytecodeGraphBuilder::VisitBitwiseNot() { - BuildUnaryOp(javascript()->BitwiseNot()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex)); + BuildUnaryOp(javascript()->BitwiseNot(feedback)); } void BytecodeGraphBuilder::VisitDec() { - BuildUnaryOp(javascript()->Decrement()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex)); + BuildUnaryOp(javascript()->Decrement(feedback)); } void BytecodeGraphBuilder::VisitInc() { - BuildUnaryOp(javascript()->Increment()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex)); + BuildUnaryOp(javascript()->Increment(feedback)); } void BytecodeGraphBuilder::VisitNegate() { - BuildUnaryOp(javascript()->Negate()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex)); + BuildUnaryOp(javascript()->Negate(feedback)); } void BytecodeGraphBuilder::VisitAdd() { - BuildBinaryOp( - javascript()->Add(GetBinaryOperationHint(kBinaryOperationHintIndex))); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex)); + BuildBinaryOp(javascript()->Add(feedback)); } void BytecodeGraphBuilder::VisitSub() { - BuildBinaryOp(javascript()->Subtract()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex)); + BuildBinaryOp(javascript()->Subtract(feedback)); } void BytecodeGraphBuilder::VisitMul() { - BuildBinaryOp(javascript()->Multiply()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex)); + BuildBinaryOp(javascript()->Multiply(feedback)); } -void BytecodeGraphBuilder::VisitDiv() { BuildBinaryOp(javascript()->Divide()); } +void BytecodeGraphBuilder::VisitDiv() { + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex)); + BuildBinaryOp(javascript()->Divide(feedback)); +} void BytecodeGraphBuilder::VisitMod() { - BuildBinaryOp(javascript()->Modulus()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex)); + BuildBinaryOp(javascript()->Modulus(feedback)); } void BytecodeGraphBuilder::VisitExp() { - BuildBinaryOp(javascript()->Exponentiate()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex)); + BuildBinaryOp(javascript()->Exponentiate(feedback)); } void BytecodeGraphBuilder::VisitBitwiseOr() { - BuildBinaryOp(javascript()->BitwiseOr()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex)); + BuildBinaryOp(javascript()->BitwiseOr(feedback)); } void BytecodeGraphBuilder::VisitBitwiseXor() { - BuildBinaryOp(javascript()->BitwiseXor()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex)); + BuildBinaryOp(javascript()->BitwiseXor(feedback)); } void BytecodeGraphBuilder::VisitBitwiseAnd() { - BuildBinaryOp(javascript()->BitwiseAnd()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex)); + BuildBinaryOp(javascript()->BitwiseAnd(feedback)); } void BytecodeGraphBuilder::VisitShiftLeft() { - BuildBinaryOp(javascript()->ShiftLeft()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex)); + BuildBinaryOp(javascript()->ShiftLeft(feedback)); } void BytecodeGraphBuilder::VisitShiftRight() { - BuildBinaryOp(javascript()->ShiftRight()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex)); + BuildBinaryOp(javascript()->ShiftRight(feedback)); } void BytecodeGraphBuilder::VisitShiftRightLogical() { - BuildBinaryOp(javascript()->ShiftRightLogical()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex)); + BuildBinaryOp(javascript()->ShiftRightLogical(feedback)); } void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* op) { + DCHECK(JSOperator::IsBinaryWithFeedback(op->opcode())); PrepareEagerCheckpoint(); Node* left = environment()->LookupAccumulator(); Node* right = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0)); @@ -2888,58 +2956,81 @@ void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* op) { node = lowering.value(); } else { DCHECK(!lowering.Changed()); - node = NewNode(op, left, right); + node = NewNode(op, left, right, feedback_vector_node()); } environment()->BindAccumulator(node, Environment::kAttachFrameState); } void BytecodeGraphBuilder::VisitAddSmi() { - BuildBinaryOpWithImmediate( - javascript()->Add(GetBinaryOperationHint(kBinaryOperationSmiHintIndex))); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex)); + BuildBinaryOpWithImmediate(javascript()->Add(feedback)); } void BytecodeGraphBuilder::VisitSubSmi() { - BuildBinaryOpWithImmediate(javascript()->Subtract()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex)); + BuildBinaryOpWithImmediate(javascript()->Subtract(feedback)); } void BytecodeGraphBuilder::VisitMulSmi() { - BuildBinaryOpWithImmediate(javascript()->Multiply()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex)); + BuildBinaryOpWithImmediate(javascript()->Multiply(feedback)); } void BytecodeGraphBuilder::VisitDivSmi() { - BuildBinaryOpWithImmediate(javascript()->Divide()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex)); + BuildBinaryOpWithImmediate(javascript()->Divide(feedback)); } void BytecodeGraphBuilder::VisitModSmi() { - BuildBinaryOpWithImmediate(javascript()->Modulus()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex)); + BuildBinaryOpWithImmediate(javascript()->Modulus(feedback)); } void BytecodeGraphBuilder::VisitExpSmi() { - BuildBinaryOpWithImmediate(javascript()->Exponentiate()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex)); + BuildBinaryOpWithImmediate(javascript()->Exponentiate(feedback)); } void BytecodeGraphBuilder::VisitBitwiseOrSmi() { - BuildBinaryOpWithImmediate(javascript()->BitwiseOr()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex)); + BuildBinaryOpWithImmediate(javascript()->BitwiseOr(feedback)); } void BytecodeGraphBuilder::VisitBitwiseXorSmi() { - BuildBinaryOpWithImmediate(javascript()->BitwiseXor()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex)); + BuildBinaryOpWithImmediate(javascript()->BitwiseXor(feedback)); } void BytecodeGraphBuilder::VisitBitwiseAndSmi() { - BuildBinaryOpWithImmediate(javascript()->BitwiseAnd()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex)); + BuildBinaryOpWithImmediate(javascript()->BitwiseAnd(feedback)); } void BytecodeGraphBuilder::VisitShiftLeftSmi() { - BuildBinaryOpWithImmediate(javascript()->ShiftLeft()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex)); + BuildBinaryOpWithImmediate(javascript()->ShiftLeft(feedback)); } void BytecodeGraphBuilder::VisitShiftRightSmi() { - BuildBinaryOpWithImmediate(javascript()->ShiftRight()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex)); + BuildBinaryOpWithImmediate(javascript()->ShiftRight(feedback)); } void BytecodeGraphBuilder::VisitShiftRightLogicalSmi() { - BuildBinaryOpWithImmediate(javascript()->ShiftRightLogical()); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex)); + BuildBinaryOpWithImmediate(javascript()->ShiftRightLogical(feedback)); } void BytecodeGraphBuilder::VisitLogicalNot() { @@ -2986,7 +3077,9 @@ void BytecodeGraphBuilder::VisitGetSuperConstructor() { Environment::kAttachFrameState); } -void BytecodeGraphBuilder::BuildCompareOp(const Operator* op) { +void BytecodeGraphBuilder::BuildInstanceOf(const Operator* op) { + // TODO(jgruber, v8:8888): Treat InstanceOf like other compare ops. + DCHECK_EQ(op->opcode(), IrOpcode::kJSInstanceOf); PrepareEagerCheckpoint(); Node* left = environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); @@ -3007,28 +3100,62 @@ void BytecodeGraphBuilder::BuildCompareOp(const Operator* op) { environment()->BindAccumulator(node, Environment::kAttachFrameState); } +void BytecodeGraphBuilder::BuildCompareOp(const Operator* op) { + DCHECK(JSOperator::IsBinaryWithFeedback(op->opcode())); + PrepareEagerCheckpoint(); + Node* left = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); + Node* right = environment()->LookupAccumulator(); + + FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1); + JSTypeHintLowering::LoweringResult lowering = + TryBuildSimplifiedBinaryOp(op, left, right, slot); + if (lowering.IsExit()) return; + + Node* node = nullptr; + if (lowering.IsSideEffectFree()) { + node = lowering.value(); + } else { + DCHECK(!lowering.Changed()); + node = NewNode(op, left, right, feedback_vector_node()); + } + environment()->BindAccumulator(node, Environment::kAttachFrameState); +} + void BytecodeGraphBuilder::VisitTestEqual() { - BuildCompareOp(javascript()->Equal(GetCompareOperationHint())); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex)); + BuildCompareOp(javascript()->Equal(feedback)); } void BytecodeGraphBuilder::VisitTestEqualStrict() { - BuildCompareOp(javascript()->StrictEqual(GetCompareOperationHint())); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex)); + BuildCompareOp(javascript()->StrictEqual(feedback)); } void BytecodeGraphBuilder::VisitTestLessThan() { - BuildCompareOp(javascript()->LessThan(GetCompareOperationHint())); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex)); + BuildCompareOp(javascript()->LessThan(feedback)); } void BytecodeGraphBuilder::VisitTestGreaterThan() { - BuildCompareOp(javascript()->GreaterThan(GetCompareOperationHint())); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex)); + BuildCompareOp(javascript()->GreaterThan(feedback)); } void BytecodeGraphBuilder::VisitTestLessThanOrEqual() { - BuildCompareOp(javascript()->LessThanOrEqual(GetCompareOperationHint())); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex)); + BuildCompareOp(javascript()->LessThanOrEqual(feedback)); } void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() { - BuildCompareOp(javascript()->GreaterThanOrEqual(GetCompareOperationHint())); + FeedbackSource feedback = CreateFeedbackSource( + bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex)); + BuildCompareOp(javascript()->GreaterThanOrEqual(feedback)); } void BytecodeGraphBuilder::VisitTestReferenceEqual() { @@ -3052,7 +3179,7 @@ void BytecodeGraphBuilder::VisitTestIn() { void BytecodeGraphBuilder::VisitTestInstanceOf() { int const slot_index = bytecode_iterator().GetIndexOperand(1); - BuildCompareOp(javascript()->InstanceOf(CreateFeedbackSource(slot_index))); + BuildInstanceOf(javascript()->InstanceOf(CreateFeedbackSource(slot_index))); } void BytecodeGraphBuilder::VisitTestUndetectable() { |