Commit a6cb4903 authored by Mythri's avatar Mythri Committed by Commit Bot

Update bytecode handlers to work without feedback vectors

This is the first in a series of patches for adding support to execute
without feedback vectors. This cl updates some of the bytecode handlers
to check for feedback before using them. All these bytecodes only collect
type feedback, so their funcitonality would not change. This cl changes the
implementation for following bytecode:
  BinaryOperation
  CompareOperation
  UnaryOperation
  Call

Bug: v8:8394
Change-Id: I284bf9c010718c65f3fe76b6f3f4461b5bfa6742
Reviewed-on: https://chromium-review.googlesource.com/c/1333667
Commit-Queue: Mythri Alle <mythria@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57580}
parent 83fd98ab
...@@ -9845,32 +9845,42 @@ TNode<BoolT> CodeStubAssembler::IsOffsetInBounds(SloppyTNode<IntPtrT> offset, ...@@ -9845,32 +9845,42 @@ TNode<BoolT> CodeStubAssembler::IsOffsetInBounds(SloppyTNode<IntPtrT> offset,
TNode<FeedbackVector> CodeStubAssembler::LoadFeedbackVector( TNode<FeedbackVector> CodeStubAssembler::LoadFeedbackVector(
SloppyTNode<JSFunction> closure, Label* if_undefined) { SloppyTNode<JSFunction> closure, Label* if_undefined) {
TNode<FeedbackCell> feedback_cell = TNode<Object> maybe_vector = LoadFeedbackVectorUnchecked(closure);
CAST(LoadObjectField(closure, JSFunction::kFeedbackCellOffset));
TNode<Object> maybe_vector =
LoadObjectField(feedback_cell, FeedbackCell::kValueOffset);
if (if_undefined) { if (if_undefined) {
GotoIf(IsUndefined(maybe_vector), if_undefined); GotoIf(IsUndefined(maybe_vector), if_undefined);
} }
return CAST(maybe_vector); return CAST(maybe_vector);
} }
TNode<Object> CodeStubAssembler::LoadFeedbackVectorUnchecked(
SloppyTNode<JSFunction> closure) {
TNode<FeedbackCell> feedback_cell =
CAST(LoadObjectField(closure, JSFunction::kFeedbackCellOffset));
TNode<Object> maybe_vector =
LoadObjectField(feedback_cell, FeedbackCell::kValueOffset);
return maybe_vector;
}
TNode<FeedbackVector> CodeStubAssembler::LoadFeedbackVectorForStub() { TNode<FeedbackVector> CodeStubAssembler::LoadFeedbackVectorForStub() {
TNode<JSFunction> function = TNode<JSFunction> function =
CAST(LoadFromParentFrame(JavaScriptFrameConstants::kFunctionOffset)); CAST(LoadFromParentFrame(JavaScriptFrameConstants::kFunctionOffset));
return LoadFeedbackVector(function); return LoadFeedbackVector(function);
} }
void CodeStubAssembler::UpdateFeedback(Node* feedback, Node* feedback_vector, void CodeStubAssembler::UpdateFeedback(Node* feedback, Node* maybe_vector,
Node* slot_id) { Node* slot_id) {
Label end(this);
// If feedback_vector is not valid, then nothing to do.
GotoIf(IsUndefined(maybe_vector), &end);
// This method is used for binary op and compare feedback. These // This method is used for binary op and compare feedback. These
// vector nodes are initialized with a smi 0, so we can simply OR // vector nodes are initialized with a smi 0, so we can simply OR
// our new feedback in place. // our new feedback in place.
TNode<FeedbackVector> feedback_vector = CAST(maybe_vector);
TNode<MaybeObject> feedback_element = TNode<MaybeObject> feedback_element =
LoadFeedbackVectorSlot(feedback_vector, slot_id); LoadFeedbackVectorSlot(feedback_vector, slot_id);
TNode<Smi> previous_feedback = CAST(feedback_element); TNode<Smi> previous_feedback = CAST(feedback_element);
TNode<Smi> combined_feedback = SmiOr(previous_feedback, CAST(feedback)); TNode<Smi> combined_feedback = SmiOr(previous_feedback, CAST(feedback));
Label end(this);
GotoIf(SmiEqual(previous_feedback, combined_feedback), &end); GotoIf(SmiEqual(previous_feedback, combined_feedback), &end);
{ {
......
...@@ -2789,6 +2789,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -2789,6 +2789,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
TNode<FeedbackVector> LoadFeedbackVector(SloppyTNode<JSFunction> closure, TNode<FeedbackVector> LoadFeedbackVector(SloppyTNode<JSFunction> closure,
Label* if_undefined = nullptr); Label* if_undefined = nullptr);
// Load the object from feedback vector cell for the given closure.
// The returned object could be undefined if the closure does not have
// a feedback vector associated with it.
TNode<Object> LoadFeedbackVectorUnchecked(SloppyTNode<JSFunction> closure);
// Update the type feedback vector. // Update the type feedback vector.
void UpdateFeedback(Node* feedback, Node* feedback_vector, Node* slot_id); void UpdateFeedback(Node* feedback, Node* feedback_vector, Node* slot_id);
......
...@@ -674,6 +674,11 @@ TNode<FeedbackVector> InterpreterAssembler::LoadFeedbackVector() { ...@@ -674,6 +674,11 @@ TNode<FeedbackVector> InterpreterAssembler::LoadFeedbackVector() {
return CodeStubAssembler::LoadFeedbackVector(function); return CodeStubAssembler::LoadFeedbackVector(function);
} }
Node* InterpreterAssembler::LoadFeedbackVectorUnchecked() {
TNode<JSFunction> function = CAST(LoadRegister(Register::function_closure()));
return CodeStubAssembler::LoadFeedbackVectorUnchecked(function);
}
void InterpreterAssembler::CallPrologue() { void InterpreterAssembler::CallPrologue() {
if (!Bytecodes::MakesCallAlongCriticalPath(bytecode_)) { if (!Bytecodes::MakesCallAlongCriticalPath(bytecode_)) {
// Bytecodes that make a call along the critical path save the bytecode // Bytecodes that make a call along the critical path save the bytecode
...@@ -818,13 +823,22 @@ void InterpreterAssembler::CollectCallableFeedback(Node* target, Node* context, ...@@ -818,13 +823,22 @@ void InterpreterAssembler::CollectCallableFeedback(Node* target, Node* context,
} }
void InterpreterAssembler::CollectCallFeedback(Node* target, Node* context, void InterpreterAssembler::CollectCallFeedback(Node* target, Node* context,
Node* feedback_vector, Node* maybe_feedback_vector,
Node* slot_id) { Node* slot_id) {
Label feedback_done(this);
// If feedback_vector is not valid, then nothing to do.
GotoIf(IsUndefined(maybe_feedback_vector), &feedback_done);
CSA_SLOW_ASSERT(this, IsFeedbackVector(maybe_feedback_vector));
// Increment the call count. // Increment the call count.
IncrementCallCount(feedback_vector, slot_id); IncrementCallCount(maybe_feedback_vector, slot_id);
// Collect the callable {target} feedback. // Collect the callable {target} feedback.
CollectCallableFeedback(target, context, feedback_vector, slot_id); CollectCallableFeedback(target, context, maybe_feedback_vector, slot_id);
Goto(&feedback_done);
BIND(&feedback_done);
} }
void InterpreterAssembler::CallJSAndDispatch( void InterpreterAssembler::CallJSAndDispatch(
...@@ -898,10 +912,10 @@ template V8_EXPORT_PRIVATE void InterpreterAssembler::CallJSAndDispatch( ...@@ -898,10 +912,10 @@ template V8_EXPORT_PRIVATE void InterpreterAssembler::CallJSAndDispatch(
void InterpreterAssembler::CallJSWithSpreadAndDispatch( void InterpreterAssembler::CallJSWithSpreadAndDispatch(
Node* function, Node* context, const RegListNodePair& args, Node* slot_id, Node* function, Node* context, const RegListNodePair& args, Node* slot_id,
Node* feedback_vector) { Node* maybe_feedback_vector) {
DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_));
DCHECK_EQ(Bytecodes::GetReceiverMode(bytecode_), ConvertReceiverMode::kAny); DCHECK_EQ(Bytecodes::GetReceiverMode(bytecode_), ConvertReceiverMode::kAny);
CollectCallFeedback(function, context, feedback_vector, slot_id); CollectCallFeedback(function, context, maybe_feedback_vector, slot_id);
Comment("call using CallWithSpread builtin"); Comment("call using CallWithSpread builtin");
Callable callable = CodeFactory::InterpreterPushArgsThenCall( Callable callable = CodeFactory::InterpreterPushArgsThenCall(
isolate(), ConvertReceiverMode::kAny, isolate(), ConvertReceiverMode::kAny,
...@@ -1771,8 +1785,9 @@ void InterpreterAssembler::ToNumberOrNumeric(Object::Conversion mode) { ...@@ -1771,8 +1785,9 @@ void InterpreterAssembler::ToNumberOrNumeric(Object::Conversion mode) {
// Record the type feedback collected for {object}. // Record the type feedback collected for {object}.
Node* slot_index = BytecodeOperandIdx(0); Node* slot_index = BytecodeOperandIdx(0);
Node* feedback_vector = LoadFeedbackVector(); Node* maybe_feedback_vector = LoadFeedbackVectorUnchecked();
UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_index);
UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_index);
SetAccumulator(var_result.value()); SetAccumulator(var_result.value());
Dispatch(); Dispatch();
......
...@@ -147,6 +147,10 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler { ...@@ -147,6 +147,10 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// Load the FeedbackVector for the current function. // Load the FeedbackVector for the current function.
compiler::TNode<FeedbackVector> LoadFeedbackVector(); compiler::TNode<FeedbackVector> LoadFeedbackVector();
// Load the FeedbackVector for the current function. The returned node
// could be undefined.
compiler::Node* LoadFeedbackVectorUnchecked();
// Increment the call count for a CALL_IC or construct call. // Increment the call count for a CALL_IC or construct call.
// The call count is located at feedback_vector[slot_id + 1]. // The call count is located at feedback_vector[slot_id + 1].
void IncrementCallCount(compiler::Node* feedback_vector, void IncrementCallCount(compiler::Node* feedback_vector,
...@@ -162,7 +166,7 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler { ...@@ -162,7 +166,7 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// |feedback_vector| at |slot_id|, and the call counts in // |feedback_vector| at |slot_id|, and the call counts in
// the |feedback_vector| at |slot_id+1|. // the |feedback_vector| at |slot_id+1|.
void CollectCallFeedback(compiler::Node* target, compiler::Node* context, void CollectCallFeedback(compiler::Node* target, compiler::Node* context,
compiler::Node* feedback_vector, compiler::Node* maybe_feedback_vector,
compiler::Node* slot_id); compiler::Node* slot_id);
// Call JSFunction or Callable |function| with |args| arguments, possibly // Call JSFunction or Callable |function| with |args| arguments, possibly
......
...@@ -812,11 +812,11 @@ class InterpreterBinaryOpAssembler : public InterpreterAssembler { ...@@ -812,11 +812,11 @@ class InterpreterBinaryOpAssembler : public InterpreterAssembler {
Node* rhs = GetAccumulator(); Node* rhs = GetAccumulator();
Node* context = GetContext(); Node* context = GetContext();
Node* slot_index = BytecodeOperandIdx(1); Node* slot_index = BytecodeOperandIdx(1);
Node* feedback_vector = LoadFeedbackVector(); Node* maybe_feedback_vector = LoadFeedbackVectorUnchecked();
BinaryOpAssembler binop_asm(state()); BinaryOpAssembler binop_asm(state());
Node* result = (binop_asm.*generator)(context, lhs, rhs, slot_index, Node* result = (binop_asm.*generator)(context, lhs, rhs, slot_index,
feedback_vector, false); maybe_feedback_vector, false);
SetAccumulator(result); SetAccumulator(result);
Dispatch(); Dispatch();
} }
...@@ -826,11 +826,11 @@ class InterpreterBinaryOpAssembler : public InterpreterAssembler { ...@@ -826,11 +826,11 @@ class InterpreterBinaryOpAssembler : public InterpreterAssembler {
Node* rhs = BytecodeOperandImmSmi(0); Node* rhs = BytecodeOperandImmSmi(0);
Node* context = GetContext(); Node* context = GetContext();
Node* slot_index = BytecodeOperandIdx(1); Node* slot_index = BytecodeOperandIdx(1);
Node* feedback_vector = LoadFeedbackVector(); Node* maybe_feedback_vector = LoadFeedbackVectorUnchecked();
BinaryOpAssembler binop_asm(state()); BinaryOpAssembler binop_asm(state());
Node* result = (binop_asm.*generator)(context, lhs, rhs, slot_index, Node* result = (binop_asm.*generator)(context, lhs, rhs, slot_index,
feedback_vector, true); maybe_feedback_vector, true);
SetAccumulator(result); SetAccumulator(result);
Dispatch(); Dispatch();
} }
...@@ -933,7 +933,7 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler { ...@@ -933,7 +933,7 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler {
Node* right = GetAccumulator(); Node* right = GetAccumulator();
Node* context = GetContext(); Node* context = GetContext();
Node* slot_index = BytecodeOperandIdx(1); Node* slot_index = BytecodeOperandIdx(1);
Node* feedback_vector = LoadFeedbackVector(); Node* maybe_feedback_vector = LoadFeedbackVectorUnchecked();
TVARIABLE(Smi, var_left_feedback); TVARIABLE(Smi, var_left_feedback);
TVARIABLE(Smi, var_right_feedback); TVARIABLE(Smi, var_right_feedback);
...@@ -959,7 +959,7 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler { ...@@ -959,7 +959,7 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler {
BinaryOperationFeedback::kNumber); BinaryOperationFeedback::kNumber);
TNode<Smi> input_feedback = TNode<Smi> input_feedback =
SmiOr(var_left_feedback.value(), var_right_feedback.value()); SmiOr(var_left_feedback.value(), var_right_feedback.value());
UpdateFeedback(SmiOr(result_type, input_feedback), feedback_vector, UpdateFeedback(SmiOr(result_type, input_feedback), maybe_feedback_vector,
slot_index); slot_index);
SetAccumulator(result); SetAccumulator(result);
Dispatch(); Dispatch();
...@@ -974,7 +974,7 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler { ...@@ -974,7 +974,7 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler {
CallRuntime(Runtime::kBigIntBinaryOp, context, var_left_bigint.value(), CallRuntime(Runtime::kBigIntBinaryOp, context, var_left_bigint.value(),
var_right_bigint.value(), SmiConstant(bitwise_op))); var_right_bigint.value(), SmiConstant(bitwise_op)));
UpdateFeedback(SmiOr(var_left_feedback.value(), var_right_feedback.value()), UpdateFeedback(SmiOr(var_left_feedback.value(), var_right_feedback.value()),
feedback_vector, slot_index); maybe_feedback_vector, slot_index);
Dispatch(); Dispatch();
} }
...@@ -982,7 +982,7 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler { ...@@ -982,7 +982,7 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler {
Node* left = GetAccumulator(); Node* left = GetAccumulator();
Node* right = BytecodeOperandImmSmi(0); Node* right = BytecodeOperandImmSmi(0);
Node* slot_index = BytecodeOperandIdx(1); Node* slot_index = BytecodeOperandIdx(1);
Node* feedback_vector = LoadFeedbackVector(); Node* maybe_feedback_vector = LoadFeedbackVectorUnchecked();
Node* context = GetContext(); Node* context = GetContext();
TVARIABLE(Smi, var_left_feedback); TVARIABLE(Smi, var_left_feedback);
...@@ -1000,12 +1000,13 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler { ...@@ -1000,12 +1000,13 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler {
TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall,
BinaryOperationFeedback::kNumber); BinaryOperationFeedback::kNumber);
UpdateFeedback(SmiOr(result_type, var_left_feedback.value()), UpdateFeedback(SmiOr(result_type, var_left_feedback.value()),
feedback_vector, slot_index); maybe_feedback_vector, slot_index);
SetAccumulator(result); SetAccumulator(result);
Dispatch(); Dispatch();
BIND(&if_bigint_mix); BIND(&if_bigint_mix);
UpdateFeedback(var_left_feedback.value(), feedback_vector, slot_index); UpdateFeedback(var_left_feedback.value(), maybe_feedback_vector,
slot_index);
ThrowTypeError(context, MessageTemplate::kBigIntMixedTypes); ThrowTypeError(context, MessageTemplate::kBigIntMixedTypes);
} }
}; };
...@@ -1088,7 +1089,7 @@ IGNITION_HANDLER(BitwiseAndSmi, InterpreterBitwiseBinaryOpAssembler) { ...@@ -1088,7 +1089,7 @@ IGNITION_HANDLER(BitwiseAndSmi, InterpreterBitwiseBinaryOpAssembler) {
IGNITION_HANDLER(BitwiseNot, InterpreterAssembler) { IGNITION_HANDLER(BitwiseNot, InterpreterAssembler) {
Node* operand = GetAccumulator(); Node* operand = GetAccumulator();
Node* slot_index = BytecodeOperandIdx(0); Node* slot_index = BytecodeOperandIdx(0);
Node* feedback_vector = LoadFeedbackVector(); Node* maybe_feedback_vector = LoadFeedbackVectorUnchecked();
Node* context = GetContext(); Node* context = GetContext();
VARIABLE(var_word32, MachineRepresentation::kWord32); VARIABLE(var_word32, MachineRepresentation::kWord32);
...@@ -1105,15 +1106,15 @@ IGNITION_HANDLER(BitwiseNot, InterpreterAssembler) { ...@@ -1105,15 +1106,15 @@ IGNITION_HANDLER(BitwiseNot, InterpreterAssembler) {
TNode<Smi> result_type = SelectSmiConstant( TNode<Smi> result_type = SelectSmiConstant(
TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall,
BinaryOperationFeedback::kNumber); BinaryOperationFeedback::kNumber);
UpdateFeedback(SmiOr(result_type, var_feedback.value()), feedback_vector, UpdateFeedback(SmiOr(result_type, var_feedback.value()),
slot_index); maybe_feedback_vector, slot_index);
SetAccumulator(result); SetAccumulator(result);
Dispatch(); Dispatch();
// BigInt case. // BigInt case.
BIND(&if_bigint); BIND(&if_bigint);
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kBigInt), feedback_vector, UpdateFeedback(SmiConstant(BinaryOperationFeedback::kBigInt),
slot_index); maybe_feedback_vector, slot_index);
SetAccumulator(CallRuntime(Runtime::kBigIntUnaryOp, context, SetAccumulator(CallRuntime(Runtime::kBigIntUnaryOp, context,
var_bigint.value(), var_bigint.value(),
SmiConstant(Operation::kBitwiseNot))); SmiConstant(Operation::kBitwiseNot)));
...@@ -1166,7 +1167,7 @@ class UnaryNumericOpAssembler : public InterpreterAssembler { ...@@ -1166,7 +1167,7 @@ class UnaryNumericOpAssembler : public InterpreterAssembler {
void UnaryOpWithFeedback() { void UnaryOpWithFeedback() {
VARIABLE(var_value, MachineRepresentation::kTagged, GetAccumulator()); VARIABLE(var_value, MachineRepresentation::kTagged, GetAccumulator());
Node* slot_index = BytecodeOperandIdx(0); Node* slot_index = BytecodeOperandIdx(0);
Node* feedback_vector = LoadFeedbackVector(); Node* maybe_feedback_vector = LoadFeedbackVectorUnchecked();
VARIABLE(var_result, MachineRepresentation::kTagged); VARIABLE(var_result, MachineRepresentation::kTagged);
VARIABLE(var_float_value, MachineRepresentation::kFloat64); VARIABLE(var_float_value, MachineRepresentation::kFloat64);
...@@ -1245,7 +1246,7 @@ class UnaryNumericOpAssembler : public InterpreterAssembler { ...@@ -1245,7 +1246,7 @@ class UnaryNumericOpAssembler : public InterpreterAssembler {
} }
BIND(&end); BIND(&end);
UpdateFeedback(var_feedback.value(), feedback_vector, slot_index); UpdateFeedback(var_feedback.value(), maybe_feedback_vector, slot_index);
SetAccumulator(var_result.value()); SetAccumulator(var_result.value());
Dispatch(); Dispatch();
} }
...@@ -1522,11 +1523,11 @@ class InterpreterJSCallAssembler : public InterpreterAssembler { ...@@ -1522,11 +1523,11 @@ class InterpreterJSCallAssembler : public InterpreterAssembler {
Node* function = LoadRegisterAtOperandIndex(0); Node* function = LoadRegisterAtOperandIndex(0);
RegListNodePair args = GetRegisterListAtOperandIndex(1); RegListNodePair args = GetRegisterListAtOperandIndex(1);
Node* slot_id = BytecodeOperandIdx(3); Node* slot_id = BytecodeOperandIdx(3);
Node* feedback_vector = LoadFeedbackVector(); Node* maybe_feedback_vector = LoadFeedbackVectorUnchecked();
Node* context = GetContext(); Node* context = GetContext();
// Collect the {function} feedback. // Collect the {function} feedback.
CollectCallFeedback(function, context, feedback_vector, slot_id); CollectCallFeedback(function, context, maybe_feedback_vector, slot_id);
// Call the function and dispatch to the next handler. // Call the function and dispatch to the next handler.
CallJSAndDispatch(function, context, args, receiver_mode); CallJSAndDispatch(function, context, args, receiver_mode);
...@@ -1555,11 +1556,11 @@ class InterpreterJSCallAssembler : public InterpreterAssembler { ...@@ -1555,11 +1556,11 @@ class InterpreterJSCallAssembler : public InterpreterAssembler {
Node* function = LoadRegisterAtOperandIndex(0); Node* function = LoadRegisterAtOperandIndex(0);
Node* slot_id = BytecodeOperandIdx(kSlotOperandIndex); Node* slot_id = BytecodeOperandIdx(kSlotOperandIndex);
Node* feedback_vector = LoadFeedbackVector(); Node* maybe_feedback_vector = LoadFeedbackVectorUnchecked();
Node* context = GetContext(); Node* context = GetContext();
// Collect the {function} feedback. // Collect the {function} feedback.
CollectCallFeedback(function, context, feedback_vector, slot_id); CollectCallFeedback(function, context, maybe_feedback_vector, slot_id);
switch (kRecieverAndArgOperandCount) { switch (kRecieverAndArgOperandCount) {
case 0: case 0:
...@@ -1710,12 +1711,12 @@ IGNITION_HANDLER(CallWithSpread, InterpreterAssembler) { ...@@ -1710,12 +1711,12 @@ IGNITION_HANDLER(CallWithSpread, InterpreterAssembler) {
Node* callable = LoadRegisterAtOperandIndex(0); Node* callable = LoadRegisterAtOperandIndex(0);
RegListNodePair args = GetRegisterListAtOperandIndex(1); RegListNodePair args = GetRegisterListAtOperandIndex(1);
Node* slot_id = BytecodeOperandIdx(3); Node* slot_id = BytecodeOperandIdx(3);
Node* feedback_vector = LoadFeedbackVector(); Node* maybe_feedback_vector = LoadFeedbackVectorUnchecked();
Node* context = GetContext(); Node* context = GetContext();
// Call into Runtime function CallWithSpread which does everything. // Call into Runtime function CallWithSpread which does everything.
CallJSWithSpreadAndDispatch(callable, context, args, slot_id, CallJSWithSpreadAndDispatch(callable, context, args, slot_id,
feedback_vector); maybe_feedback_vector);
} }
// ConstructWithSpread <first_arg> <arg_count> // ConstructWithSpread <first_arg> <arg_count>
...@@ -1788,8 +1789,9 @@ class InterpreterCompareOpAssembler : public InterpreterAssembler { ...@@ -1788,8 +1789,9 @@ class InterpreterCompareOpAssembler : public InterpreterAssembler {
} }
Node* slot_index = BytecodeOperandIdx(1); Node* slot_index = BytecodeOperandIdx(1);
Node* feedback_vector = LoadFeedbackVector(); Node* maybe_feedback_vector = LoadFeedbackVectorUnchecked();
UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_index); UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector,
slot_index);
SetAccumulator(result); SetAccumulator(result);
Dispatch(); Dispatch();
} }
...@@ -1872,12 +1874,17 @@ IGNITION_HANDLER(TestInstanceOf, InterpreterAssembler) { ...@@ -1872,12 +1874,17 @@ IGNITION_HANDLER(TestInstanceOf, InterpreterAssembler) {
Node* object = LoadRegisterAtOperandIndex(0); Node* object = LoadRegisterAtOperandIndex(0);
Node* callable = GetAccumulator(); Node* callable = GetAccumulator();
Node* slot_id = BytecodeOperandIdx(1); Node* slot_id = BytecodeOperandIdx(1);
Node* feedback_vector = LoadFeedbackVector(); Node* feedback_vector = LoadFeedbackVectorUnchecked();
Node* context = GetContext(); Node* context = GetContext();
Label feedback_done(this);
GotoIf(IsUndefined(feedback_vector), &feedback_done);
// Record feedback for the {callable} in the {feedback_vector}. // Record feedback for the {callable} in the {feedback_vector}.
CollectCallableFeedback(callable, context, feedback_vector, slot_id); CollectCallableFeedback(callable, context, feedback_vector, slot_id);
Goto(&feedback_done);
BIND(&feedback_done);
// Perform the actual instanceof operation. // Perform the actual instanceof operation.
SetAccumulator(InstanceOf(object, callable, context)); SetAccumulator(InstanceOf(object, callable, context));
Dispatch(); Dispatch();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment