| Index: src/arm/code-stubs-arm.cc
 | 
| diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
 | 
| index afea875e9e9a4da5b5f290fc57ad46189466c481..585108b2bddf9bf60d3662d0627e642f57dd4545 100644
 | 
| --- a/src/arm/code-stubs-arm.cc
 | 
| +++ b/src/arm/code-stubs-arm.cc
 | 
| @@ -2934,11 +2934,13 @@ static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void CallFunctionStub::Generate(MacroAssembler* masm) {
 | 
| +static void CallFunctionNoFeedback(MacroAssembler* masm,
 | 
| +                                   int argc, bool needs_checks,
 | 
| +                                   bool call_as_method) {
 | 
|    // r1 : the function to call
 | 
|    Label slow, non_function, wrap, cont;
 | 
|  
 | 
| -  if (NeedsChecks()) {
 | 
| +  if (needs_checks) {
 | 
|      // Check that the function is really a JavaScript function.
 | 
|      // r1: pushed function (to be verified)
 | 
|      __ JumpIfSmi(r1, &non_function);
 | 
| @@ -2950,18 +2952,17 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
 | 
|  
 | 
|    // Fast-case: Invoke the function now.
 | 
|    // r1: pushed function
 | 
| -  int argc = argc_;
 | 
|    ParameterCount actual(argc);
 | 
|  
 | 
| -  if (CallAsMethod()) {
 | 
| -    if (NeedsChecks()) {
 | 
| +  if (call_as_method) {
 | 
| +    if (needs_checks) {
 | 
|        EmitContinueIfStrictOrNative(masm, &cont);
 | 
|      }
 | 
|  
 | 
|      // Compute the receiver in sloppy mode.
 | 
|      __ ldr(r3, MemOperand(sp, argc * kPointerSize));
 | 
|  
 | 
| -    if (NeedsChecks()) {
 | 
| +    if (needs_checks) {
 | 
|        __ JumpIfSmi(r3, &wrap);
 | 
|        __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE);
 | 
|        __ b(lt, &wrap);
 | 
| @@ -2974,19 +2975,24 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
 | 
|  
 | 
|    __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper());
 | 
|  
 | 
| -  if (NeedsChecks()) {
 | 
| +  if (needs_checks) {
 | 
|      // Slow-case: Non-function called.
 | 
|      __ bind(&slow);
 | 
|      EmitSlowCase(masm, argc, &non_function);
 | 
|    }
 | 
|  
 | 
| -  if (CallAsMethod()) {
 | 
| +  if (call_as_method) {
 | 
|      __ bind(&wrap);
 | 
|      EmitWrapCase(masm, argc, &cont);
 | 
|    }
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void CallFunctionStub::Generate(MacroAssembler* masm) {
 | 
| +  CallFunctionNoFeedback(masm, argc_, NeedsChecks(), CallAsMethod());
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void CallConstructStub::Generate(MacroAssembler* masm) {
 | 
|    // r0 : number of arguments
 | 
|    // r1 : the function to call
 | 
| @@ -3046,7 +3052,7 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
 | 
|    __ bind(&do_call);
 | 
|    // Set expected number of arguments to zero (not changing r0).
 | 
|    __ mov(r2, Operand::Zero());
 | 
| -  __ Jump(isolate()->builtins()->ArgumentsAdaptorTrampoline(),
 | 
| +  __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
 | 
|            RelocInfo::CODE_TARGET);
 | 
|  }
 | 
|  
 | 
| @@ -3060,6 +3066,51 @@ static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) {
 | 
| +  // r1 - function
 | 
| +  // r2 - feedback vector
 | 
| +  // r3 - slot id
 | 
| +  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4);
 | 
| +  __ cmp(r1, r4);
 | 
| +  __ b(ne, miss);
 | 
| +
 | 
| +  __ mov(r0, Operand(arg_count()));
 | 
| +  __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
 | 
| +  __ ldr(r2, FieldMemOperand(r4, FixedArray::kHeaderSize));
 | 
| +  // Verify that r2 contains an AllocationSite
 | 
| +  __ AssertUndefinedOrAllocationSite(r2, r4);
 | 
| +  ArrayConstructorStub stub(masm->isolate(), arg_count());
 | 
| +  __ TailCallStub(&stub);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) {
 | 
| +  // r1 - function
 | 
| +  // r2 - feedback vector
 | 
| +  // r3 - slot id
 | 
| +  Label miss;
 | 
| +
 | 
| +  if (state_.stub_type() == CallIC::MONOMORPHIC_ARRAY) {
 | 
| +    Generate_MonomorphicArray(masm, &miss);
 | 
| +  } else {
 | 
| +    // So far there is only one customer for our custom feedback scheme.
 | 
| +    UNREACHABLE();
 | 
| +  }
 | 
| +
 | 
| +  __ bind(&miss);
 | 
| +  GenerateMiss(masm);
 | 
| +
 | 
| +  // The slow case, we need this no matter what to complete a call after a miss.
 | 
| +  CallFunctionNoFeedback(masm,
 | 
| +                         arg_count(),
 | 
| +                         true,
 | 
| +                         CallAsMethod());
 | 
| +
 | 
| +  // Unreachable.
 | 
| +  __ stop("Unexpected code address");
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void CallICStub::Generate(MacroAssembler* masm) {
 | 
|    // r1 - function
 | 
|    // r3 - slot id (Smi)
 | 
| @@ -3071,6 +3122,11 @@ void CallICStub::Generate(MacroAssembler* masm) {
 | 
|  
 | 
|    EmitLoadTypeFeedbackVector(masm, r2);
 | 
|  
 | 
| +  if (state_.stub_type() != CallIC::DEFAULT) {
 | 
| +    Generate_CustomFeedbackCall(masm);
 | 
| +    return;
 | 
| +  }
 | 
| +
 | 
|    // The checks. First, does r1 match the recorded monomorphic target?
 | 
|    __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
 | 
|    __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize));
 | 
| 
 |