Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index 392c74dc23bc29a4fac7f93c62f3cb6aaecaaa9f..291901e537e334256481a26b9d354566be30f408 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -2565,7 +2565,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |
RecordPosition(pointers->position()); |
SafepointGenerator safepoint_generator( |
this, pointers, Safepoint::kLazyDeopt); |
- v8::internal::ParameterCount actual(rax); |
+ ParameterCount actual(rax); |
__ InvokeFunction(function, actual, CALL_FUNCTION, |
safepoint_generator, CALL_AS_METHOD); |
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
@@ -2615,35 +2615,48 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
int arity, |
LInstruction* instr, |
CallKind call_kind) { |
- // Change context if needed. |
- bool change_context = |
- (info()->closure()->context() != function->context()) || |
- scope()->contains_with() || |
- (scope()->num_heap_slots() > 0); |
- if (change_context) { |
- __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
- } |
- |
- // Set rax to arguments count if adaption is not needed. Assumes that rax |
- // is available to write to at this point. |
- if (!function->NeedsArgumentsAdaption()) { |
- __ Set(rax, arity); |
- } |
+ bool can_invoke_directly = !function->NeedsArgumentsAdaption() || |
+ function->shared()->formal_parameter_count() == arity; |
LPointerMap* pointers = instr->pointer_map(); |
RecordPosition(pointers->position()); |
- // Invoke function. |
- __ SetCallKind(rcx, call_kind); |
- if (*function == *info()->closure()) { |
- __ CallSelf(); |
+ if (can_invoke_directly) { |
+ __ LoadHeapObject(rdi, function); |
+ |
+ // Change context if needed. |
+ bool change_context = |
+ (info()->closure()->context() != function->context()) || |
+ scope()->contains_with() || |
+ (scope()->num_heap_slots() > 0); |
+ if (change_context) { |
+ __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
+ } |
+ |
+ // Set rax to arguments count if adaption is not needed. Assumes that rax |
+ // is available to write to at this point. |
+ if (!function->NeedsArgumentsAdaption()) { |
+ __ Set(rax, arity); |
+ } |
+ |
+ // Invoke function. |
+ __ SetCallKind(rcx, call_kind); |
+ if (*function == *info()->closure()) { |
+ __ CallSelf(); |
+ } else { |
+ __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
+ } |
+ |
+ // Set up deoptimization. |
+ RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); |
} else { |
- __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
+ // We need to adapt arguments. |
+ SafepointGenerator generator( |
+ this, pointers, Safepoint::kLazyDeopt); |
+ ParameterCount count(arity); |
+ __ InvokeFunction(function, count, CALL_FUNCTION, generator, call_kind); |
} |
- // Set up deoptimization. |
- RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); |
- |
// Restore context. |
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
} |
@@ -2651,7 +2664,6 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
ASSERT(ToRegister(instr->result()).is(rax)); |
- __ LoadHeapObject(rdi, instr->function()); |
CallKnownFunction(instr->function(), |
instr->arity(), |
instr, |
@@ -3094,7 +3106,6 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { |
void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
ASSERT(ToRegister(instr->result()).is(rax)); |
- __ LoadHeapObject(rdi, instr->target()); |
CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); |
} |