summaryrefslogtreecommitdiff
path: root/chromium/v8/src/compiler/bytecode-graph-builder.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/v8/src/compiler/bytecode-graph-builder.cc
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-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.cc319
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() {