Chromium Code Reviews| Index: src/ia32/code-stubs-ia32.cc |
| diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc |
| index 03c43611feadef2c2380ce9b40a9ef3a8fee132c..d8ecce3e21334746a8766369c209a20e30da5c10 100644 |
| --- a/src/ia32/code-stubs-ia32.cc |
| +++ b/src/ia32/code-stubs-ia32.cc |
| @@ -2371,11 +2371,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) { |
| // edi : the function to call |
| Label slow, non_function, wrap, cont; |
| - if (NeedsChecks()) { |
| + if (needs_checks) { |
| // Check that the function really is a JavaScript function. |
| __ JumpIfSmi(edi, &non_function); |
| @@ -2385,17 +2387,17 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { |
| } |
| // Fast-case: Just invoke the function. |
| - ParameterCount actual(argc_); |
| + ParameterCount actual(argc); |
| - if (CallAsMethod()) { |
| - if (NeedsChecks()) { |
| + if (call_as_method) { |
| + if (needs_checks) { |
| EmitContinueIfStrictOrNative(masm, &cont); |
| } |
| // Load the receiver from the stack. |
| - __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize)); |
| + __ mov(eax, Operand(esp, (argc + 1) * kPointerSize)); |
| - if (NeedsChecks()) { |
| + if (call_as_method) { |
| __ JumpIfSmi(eax, &wrap); |
| __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); |
| @@ -2409,20 +2411,25 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { |
| __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); |
| - if (NeedsChecks()) { |
| + if (needs_checks) { |
| // Slow-case: Non-function called. |
| __ bind(&slow); |
| // (non_function is bound in EmitSlowCase) |
| - EmitSlowCase(isolate(), masm, argc_, &non_function); |
| + EmitSlowCase(masm->isolate(), masm, argc, &non_function); |
| } |
| - if (CallAsMethod()) { |
| + if (call_as_method) { |
| __ bind(&wrap); |
| - EmitWrapCase(masm, argc_, &cont); |
| + EmitWrapCase(masm, argc, &cont); |
| } |
| } |
| +void CallFunctionStub::Generate(MacroAssembler* masm) { |
| + CallFunctionNoFeedback(masm, argc_, NeedsChecks(), CallAsMethod()); |
| +} |
| + |
| + |
| void CallConstructStub::Generate(MacroAssembler* masm) { |
| // eax : number of arguments |
| // ebx : feedback vector |
| @@ -2499,6 +2506,51 @@ static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) { |
| } |
| +void CallICStub::Generate_MonomorphicArray(MacroAssembler* masm, Label* miss) { |
| + // edi - function |
| + // ebx - feedback vector |
| + // edx - slot id |
| + __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
| + __ cmp(edi, ecx); |
| + __ j(not_equal, miss); |
| + |
| + __ mov(eax, arg_count()); |
| + __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size, |
| + FixedArray::kHeaderSize)); |
| + // Verify that ecx contains an AllocationSite |
| + __ AssertUndefinedOrAllocationSite(ebx); |
| + ArrayConstructorStub stub(masm->isolate(), arg_count()); |
| + __ TailCallStub(&stub); |
| +} |
| + |
| + |
| +void CallICStub::Generate_CustomFeedbackCall(MacroAssembler* masm) { |
| + // edi - function |
| + // ebx - feedback vector |
| + // edx - 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. |
| + __ int3(); |
|
danno
2014/05/16 16:34:11
I think there might be a macro for this.
mvstanton
2014/05/19 13:45:24
There isn't, code even in the macro assembler uses
|
| +} |
| + |
| + |
| void CallICStub::Generate(MacroAssembler* masm) { |
| // edi - function |
| // edx - slot id |
| @@ -2511,6 +2563,13 @@ void CallICStub::Generate(MacroAssembler* masm) { |
| EmitLoadTypeFeedbackVector(masm, ebx); |
| + // the MONOMORPHIC_ARRAY case is handled with a helper function. |
| + if (state_.stub_type() != CallIC::DEFAULT) { |
| + Generate_CustomFeedbackCall(masm); |
| + return; |
| + } |
| + |
| + // the MONOMORPHIC_ARRAY case is handled with a helper function. |
| // The checks. First, does edi match the recorded monomorphic target? |
| __ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size, |
| FixedArray::kHeaderSize)); |