Chromium Code Reviews| Index: src/interpreter/interpreter-assembler.cc |
| diff --git a/src/interpreter/interpreter-assembler.cc b/src/interpreter/interpreter-assembler.cc |
| index 947979e7085a1ebb02a44fe722b60ab2eb6f8272..bc2257d7d69f46541067da5770342c603663c41b 100644 |
| --- a/src/interpreter/interpreter-assembler.cc |
| +++ b/src/interpreter/interpreter-assembler.cc |
| @@ -523,12 +523,50 @@ Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context, |
| Bind(&extra_checks); |
| { |
| - Label check_initialized(this, Label::kDeferred), mark_megamorphic(this); |
| + Label check_initialized(this, Label::kDeferred), mark_megamorphic(this), |
| + check_allocation_site(this), create_allocation_site(this); |
| // Check if it is a megamorphic target |
| Node* is_megamorphic = WordEqual( |
| feedback_element, |
| HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate()))); |
| - BranchIf(is_megamorphic, &call, &check_initialized); |
| + BranchIf(is_megamorphic, &call, &check_allocation_site); |
| + |
| + Bind(&check_allocation_site); |
| + { |
| + Node* is_allocation_site = |
| + WordEqual(LoadMap(feedback_element), |
| + LoadRoot(Heap::kAllocationSiteMapRootIndex)); |
| + GotoUnless(is_allocation_site, &check_initialized); |
| + |
| + // If it is not an array function, mark megamorphic. |
| + Node* context_slot = |
| + LoadFixedArrayElement(LoadNativeContext(context), |
| + Int32Constant(Context::ARRAY_FUNCTION_INDEX)); |
| + Node* is_array_function = WordEqual(context_slot, function); |
| + 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); |
| + |
| + // Call using CallFunction builtin. |
| + // TODO(mythria): We still do not use the collected feedback when creating |
| + // a new array. To use it, we should have an adapter builtin similiar to |
| + // InterpreterPushArgsAndCall to push arguments and call the |
| + // ArrayConstructorStub or Runtime_NewArray. |
| + Callable callable_call = CodeFactory::InterpreterPushArgsAndCall( |
| + isolate(), tail_call_mode, CallableType::kJSFunction); |
| + Node* code_target_call = HeapConstant(callable_call.code()); |
| + Node* ret_value = CallStub(callable_call.descriptor(), code_target_call, |
| + context, arg_count, first_arg, function); |
|
mythria
2016/09/02 14:33:46
We do not pass allocation site feedback here, so t
Benedikt Meurer
2016/09/05 04:11:20
Ah, I misunderstood you in our offline conversatio
mythria
2016/09/05 12:56:34
Thanks Benedikt. I now implemented it throw ArrayC
|
| + return_value.Bind(ret_value); |
| + Goto(&end); |
| + } |
| Bind(&check_initialized); |
| { |
| @@ -553,7 +591,7 @@ Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context, |
| LoadFixedArrayElement(LoadNativeContext(context), |
| Int32Constant(Context::ARRAY_FUNCTION_INDEX)); |
| Node* is_array_function = WordEqual(context_slot, function); |
| - GotoIf(is_array_function, &mark_megamorphic); |
| + GotoIf(is_array_function, &create_allocation_site); |
| // Check if the function belongs to the same native context |
| Node* native_context = LoadNativeContext( |
| @@ -581,6 +619,34 @@ Node* InterpreterAssembler::CallJSWithFeedback(Node* function, Node* context, |
| Goto(&end); |
| } |
| + Bind(&create_allocation_site); |
| + { |
| + // TODO(mythria): Inline the creation of allocation site. |
| + CreateAllocationSiteStub create_stub(isolate()); |
| + CallStub(create_stub.GetCallInterfaceDescriptor(), |
| + 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. |
| + // TODO(mythria): We still do not use the collected feedback when creating |
| + // a new array. To use it, we should have an adapter builtin similiar to |
| + // InterpreterPushArgsAndCall to push arguments and call the |
| + // ArrayConstructorStub or Runtime_NewArray. |
| + Callable callable_call = CodeFactory::InterpreterPushArgsAndCall( |
| + isolate(), tail_call_mode, CallableType::kJSFunction); |
| + 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(&mark_megamorphic); |
| { |
| // Mark it as a megamorphic. |
| @@ -764,9 +830,8 @@ Node* InterpreterAssembler::CallConstruct(Node* constructor, Node* context, |
| Bind(&mark_megamorphic); |
| { |
| - // MegamorphicSentinel is an immortal immovable object so no |
| - // write-barrier |
| - // is needed. |
| + // MegamorphicSentinel is an immortal immovable object so |
| + // write-barrier is not needed. |
| Comment("transition to megamorphic"); |
| DCHECK( |
| Heap::RootIsImmortalImmovable(Heap::kmegamorphic_symbolRootIndex)); |