Index: src/interpreter/interpreter-assembler.cc |
diff --git a/src/interpreter/interpreter-assembler.cc b/src/interpreter/interpreter-assembler.cc |
index 94b6b554f32062d3ef0a5daa538f6ed9717b1b2d..0d3e37781cdd1445f3634408e9880b2e13f43c69 100644 |
--- a/src/interpreter/interpreter-assembler.cc |
+++ b/src/interpreter/interpreter-assembler.cc |
@@ -460,6 +460,17 @@ void InterpreterAssembler::CallEpilogue() { |
} |
} |
+Node* InterpreterAssembler::IncrementCallCount(Node* type_feedback_vector, |
+ Node* slot_id) { |
+ Node* call_count_slot = IntPtrAdd(slot_id, IntPtrConstant(1)); |
+ Node* call_count = |
+ LoadFixedArrayElement(type_feedback_vector, call_count_slot); |
+ Node* new_count = SmiAdd(call_count, SmiTag(Int32Constant(1))); |
+ // Count is Smi, so we don't need a write barrier. |
+ return StoreFixedArrayElement(type_feedback_vector, call_count_slot, |
+ new_count, SKIP_WRITE_BARRIER); |
+} |
+ |
Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context, |
Node* first_arg, Node* arg_count, |
Node* slot_id, |
@@ -482,13 +493,13 @@ Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context, |
Variable return_value(this, MachineRepresentation::kTagged); |
Label handle_monomorphic(this), extra_checks(this), end(this), call(this), |
- call_function(this); |
+ call_function(this), call_without_feedback(this); |
// Slot id of 0 is used to indicate no typefeedback is available. Call using |
// call builtin. |
STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0); |
Node* is_feedback_unavailable = Word32Equal(slot_id, Int32Constant(0)); |
- GotoIf(is_feedback_unavailable, &call); |
+ GotoIf(is_feedback_unavailable, &call_without_feedback); |
// The checks. First, does function match the recorded monomorphic target? |
Node* feedback_element = LoadFixedArrayElement(type_feedback_vector, slot_id); |
@@ -504,13 +515,7 @@ Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context, |
GotoIf(is_smi, &extra_checks); |
// Increment the call count. |
- Node* call_count_slot = IntPtrAdd(slot_id, IntPtrConstant(1)); |
- Node* call_count = |
- LoadFixedArrayElement(type_feedback_vector, call_count_slot); |
- Node* new_count = SmiAdd(call_count, SmiTag(Int32Constant(1))); |
- // Count is Smi, so we don't need a write barrier. |
- StoreFixedArrayElement(type_feedback_vector, call_count_slot, new_count, |
- SKIP_WRITE_BARRIER); |
+ IncrementCallCount(type_feedback_vector, slot_id); |
// Call using call function builtin. |
Callable callable = CodeFactory::InterpreterPushArgsAndCall( |
@@ -548,13 +553,7 @@ Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context, |
GotoUnless(is_array_function, &mark_megamorphic); |
// It is a monomorphic Array function. Increment the call count. |
- Node* call_count_slot = IntPtrAdd(slot_id, IntPtrConstant(1)); |
- Node* call_count = |
- LoadFixedArrayElement(type_feedback_vector, call_count_slot); |
- Node* new_count = SmiAdd(call_count, SmiTag(Int32Constant(1))); |
- // Count is Smi, so we don't need a write barrier. |
- StoreFixedArrayElement(type_feedback_vector, call_count_slot, new_count, |
- SKIP_WRITE_BARRIER); |
+ IncrementCallCount(type_feedback_vector, slot_id); |
// Call ArrayConstructorStub. |
Callable callable_call = |
@@ -599,12 +598,6 @@ Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context, |
WordEqual(native_context, LoadNativeContext(context)); |
GotoUnless(is_same_native_context, &mark_megamorphic); |
- // Initialize it to a monomorphic target. |
- Node* call_count_slot = IntPtrAdd(slot_id, IntPtrConstant(1)); |
- // Count is Smi, so we don't need a write barrier. |
- StoreFixedArrayElement(type_feedback_vector, call_count_slot, |
- SmiTag(Int32Constant(1)), SKIP_WRITE_BARRIER); |
- |
CreateWeakCellInFeedbackVector(type_feedback_vector, SmiTag(slot_id), |
function); |
@@ -620,12 +613,6 @@ Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context, |
HeapConstant(create_stub.GetCode()), context, |
type_feedback_vector, SmiTag(slot_id)); |
- // Initialize the count to 1. |
- Node* call_count_slot = IntPtrAdd(slot_id, IntPtrConstant(1)); |
- // Count is Smi, so we don't need a write barrier. |
- StoreFixedArrayElement(type_feedback_vector, call_count_slot, |
- SmiTag(Int32Constant(1)), SKIP_WRITE_BARRIER); |
- |
// Call using CallFunction builtin. CallICs have a PREMONOMORPHIC state. |
// They start collecting feedback only when a call is executed the second |
// time. So, do not pass any feedback here. |
@@ -648,6 +635,9 @@ Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context, |
Bind(&call_function); |
{ |
+ // Increment the call count. |
+ IncrementCallCount(type_feedback_vector, slot_id); |
+ |
Callable callable_call = CodeFactory::InterpreterPushArgsAndCall( |
isolate(), tail_call_mode, CallableType::kJSFunction); |
Node* code_target_call = HeapConstant(callable_call.code()); |
@@ -659,6 +649,21 @@ Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context, |
Bind(&call); |
{ |
+ // Increment the call count. |
+ IncrementCallCount(type_feedback_vector, slot_id); |
+ |
+ // Call using call builtin. |
+ Callable callable_call = CodeFactory::InterpreterPushArgsAndCall( |
+ isolate(), tail_call_mode, CallableType::kAny); |
+ Node* code_target_call = HeapConstant(callable_call.code()); |
+ Node* ret_value = CallStub(callable_call.descriptor(), code_target_call, |
+ context, arg_count, first_arg, function); |
+ return_value.Bind(ret_value); |
+ Goto(&end); |
+ } |
+ |
+ Bind(&call_without_feedback); |
+ { |
// Call using call builtin. |
Callable callable_call = CodeFactory::InterpreterPushArgsAndCall( |
isolate(), tail_call_mode, CallableType::kAny); |