Chromium Code Reviews| 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..423a3765d95c95eaa16f24c2316a4ace7db1f13a 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,12 @@ void CallICStub::Generate(MacroAssembler* masm) { |
| EmitLoadTypeFeedbackVector(masm, r2); |
| + // the MONOMORPHIC_ARRAY case is handled with a helper function. |
|
danno
2014/05/22 08:20:43
nit: this comment is a bit misleading, all non-def
mvstanton
2014/05/22 09:29:47
Cool, I removed the comment, it's self-explanatory
|
| + 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)); |