From ef24af119e0f2574760bfbd3f14f4bc27db8c17d Mon Sep 17 00:00:00 2001 From: "fschneider@chromium.org" Date: Fri, 15 Apr 2011 07:58:22 +0000 Subject: [PATCH] Land Kevin's patch for supporting %_CallFunction in Crankshaft. Original code review: http://codereview.chromium.org/6838018/ TBR=ager@chromium.org Review URL: http://codereview.chromium.org/6869005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7624 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/full-codegen-arm.cc | 13 ++++++------- src/arm/lithium-arm.cc | 15 +++++++++++++++ src/arm/lithium-arm.h | 18 ++++++++++++++++++ src/arm/lithium-codegen-arm.cc | 25 ++++++++++++++++++++----- src/arm/lithium-codegen-arm.h | 4 ++-- src/hydrogen-instructions.h | 18 ++++++++++++++++++ src/hydrogen.cc | 16 +++++++++++++++- src/ia32/full-codegen-ia32.cc | 13 ++++++------- src/ia32/lithium-codegen-ia32.cc | 27 +++++++++++++++++++++------ src/ia32/lithium-codegen-ia32.h | 4 ++-- src/ia32/lithium-ia32.cc | 18 ++++++++++++++++++ src/ia32/lithium-ia32.h | 20 ++++++++++++++++++++ src/runtime-profiler.cc | 3 ++- src/x64/full-codegen-x64.cc | 13 ++++++------- src/x64/lithium-codegen-x64.cc | 28 ++++++++++++++++++++++------ src/x64/lithium-codegen-x64.h | 4 ++-- src/x64/lithium-x64.cc | 15 +++++++++++++++ src/x64/lithium-x64.h | 22 ++++++++++++++++++++-- 18 files changed, 228 insertions(+), 48 deletions(-) diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index ff8b012..85e4262 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -3161,15 +3161,14 @@ void FullCodeGenerator::EmitMathSqrt(ZoneList* args) { void FullCodeGenerator::EmitCallFunction(ZoneList* args) { ASSERT(args->length() >= 2); - int arg_count = args->length() - 2; // For receiver and function. - VisitForStackValue(args->at(0)); // Receiver. - for (int i = 0; i < arg_count; i++) { - VisitForStackValue(args->at(i + 1)); + int arg_count = args->length() - 2; // 2 ~ receiver and function. + for (int i = 0; i < arg_count + 1; i++) { + VisitForStackValue(args->at(i)); } - VisitForAccumulatorValue(args->at(arg_count + 1)); // Function. + VisitForAccumulatorValue(args->last()); // Function. - // InvokeFunction requires function in r1. Move it in there. - if (!result_register().is(r1)) __ mov(r1, result_register()); + // InvokeFunction requires the function in r1. Move it in there. + __ mov(r1, result_register()); ParameterCount count(arg_count); __ InvokeFunction(r1, count, CALL_FUNCTION); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 5df6802..faf6404 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -300,6 +300,13 @@ void LStoreContextSlot::PrintDataTo(StringStream* stream) { } +void LInvokeFunction::PrintDataTo(StringStream* stream) { + stream->Add("= "); + InputAt(0)->PrintTo(stream); + stream->Add(" #%d / ", arity()); +} + + void LCallKeyed::PrintDataTo(StringStream* stream) { stream->Add("[r2] #%d / ", arity()); } @@ -1211,6 +1218,14 @@ LInstruction* LChunkBuilder::DoCallConstantFunction( } +LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { + LOperand* function = UseFixed(instr->function(), r1); + argument_count_ -= instr->argument_count(); + LInvokeFunction* result = new LInvokeFunction(function); + return MarkAsCall(DefineFixed(result, r0), instr, CANNOT_DEOPTIMIZE_EAGERLY); +} + + LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { BuiltinFunctionId op = instr->op(); if (op == kMathLog || op == kMathSin || op == kMathCos) { diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index 8c3449a..ea6aa5d 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -106,6 +106,7 @@ class LCodeGen; V(InstanceOfAndBranch) \ V(InstanceOfKnownGlobal) \ V(Integer32ToDouble) \ + V(InvokeFunction) \ V(IsNull) \ V(IsNullAndBranch) \ V(IsObject) \ @@ -1413,6 +1414,23 @@ class LCallConstantFunction: public LTemplateInstruction<1, 0, 0> { }; +class LInvokeFunction: public LTemplateInstruction<1, 1, 0> { + public: + LInvokeFunction(LOperand* function) { + inputs_[0] = function; + } + + DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function") + DECLARE_HYDROGEN_ACCESSOR(InvokeFunction) + + LOperand* function() { return inputs_[0]; } + + virtual void PrintDataTo(StringStream* stream); + + int arity() const { return hydrogen()->argument_count() - 1; } +}; + + class LCallKeyed: public LTemplateInstruction<1, 1, 0> { public: explicit LCallKeyed(LOperand* key) { diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index d4b651d..9ff034f 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -91,7 +91,7 @@ bool LCodeGen::GenerateCode() { void LCodeGen::FinishCode(Handle code) { ASSERT(is_done()); - code->set_stack_slots(StackSlotCount()); + code->set_stack_slots(GetStackSlotCount()); code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); PopulateDeoptimizationData(code); Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); @@ -149,7 +149,7 @@ bool LCodeGen::GeneratePrologue() { __ add(fp, sp, Operand(2 * kPointerSize)); // Adjust FP to point to saved FP. // Reserve space for the stack slots needed by the code. - int slots = StackSlotCount(); + int slots = GetStackSlotCount(); if (slots > 0) { if (FLAG_debug_code) { __ mov(r0, Operand(slots)); @@ -263,7 +263,7 @@ bool LCodeGen::GenerateDeferredCode() { bool LCodeGen::GenerateSafepointTable() { ASSERT(is_done()); - safepoints_.Emit(masm(), StackSlotCount()); + safepoints_.Emit(masm(), GetStackSlotCount()); return !is_aborted(); } @@ -459,7 +459,7 @@ void LCodeGen::AddToTranslation(Translation* translation, translation->StoreDoubleStackSlot(op->index()); } else if (op->IsArgument()) { ASSERT(is_tagged); - int src_index = StackSlotCount() + op->index(); + int src_index = GetStackSlotCount() + op->index(); translation->StoreStackSlot(src_index); } else if (op->IsRegister()) { Register reg = ToRegister(op); @@ -2180,7 +2180,7 @@ void LCodeGen::DoReturn(LReturn* instr) { __ push(r0); __ CallRuntime(Runtime::kTraceExit, 1); } - int32_t sp_delta = (ParameterCount() + 1) * kPointerSize; + int32_t sp_delta = (GetParameterCount() + 1) * kPointerSize; __ mov(sp, fp); __ ldm(ia_w, sp, fp.bit() | lr.bit()); __ add(sp, sp, Operand(sp_delta)); @@ -3025,6 +3025,21 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { } +void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { + ASSERT(ToRegister(instr->function()).is(r1)); + ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasDeoptimizationEnvironment()); + LPointerMap* pointers = instr->pointer_map(); + LEnvironment* env = instr->deoptimization_environment(); + RecordPosition(pointers->position()); + RegisterEnvironmentForDeoptimization(env); + SafepointGenerator generator(this, pointers, env->deoptimization_index()); + ParameterCount count(instr->arity()); + __ InvokeFunction(r1, count, CALL_FUNCTION, &generator); + __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); +} + + void LCodeGen::DoCallKeyed(LCallKeyed* instr) { ASSERT(ToRegister(instr->result()).is(r0)); diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h index 8a4ea27..1110ea6 100644 --- a/src/arm/lithium-codegen-arm.h +++ b/src/arm/lithium-codegen-arm.h @@ -158,8 +158,8 @@ class LCodeGen BASE_EMBEDDED { Register temporary, Register temporary2); - int StackSlotCount() const { return chunk()->spill_slot_count(); } - int ParameterCount() const { return scope()->num_parameters(); } + int GetStackSlotCount() const { return chunk()->spill_slot_count(); } + int GetParameterCount() const { return scope()->num_parameters(); } void Abort(const char* format, ...); void Comment(const char* format, ...); diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 9af60da..e32a09c 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -114,6 +114,7 @@ class LChunkBuilder; V(HasCachedArrayIndex) \ V(InstanceOf) \ V(InstanceOfKnownGlobal) \ + V(InvokeFunction) \ V(IsNull) \ V(IsObject) \ V(IsSmi) \ @@ -1244,6 +1245,23 @@ class HBinaryCall: public HCall<2> { }; +class HInvokeFunction: public HBinaryCall { + public: + HInvokeFunction(HValue* context, HValue* function, int argument_count) + : HBinaryCall(context, function, argument_count) { + } + + virtual Representation RequiredInputRepresentation(int index) const { + return Representation::Tagged(); + } + + HValue* context() { return first(); } + HValue* function() { return second(); } + + DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke_function") +}; + + class HCallConstantFunction: public HCall<0> { public: HCallConstantFunction(Handle function, int argument_count) diff --git a/src/hydrogen.cc b/src/hydrogen.cc index e254005..f6c47f3 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -5540,7 +5540,21 @@ void HGraphBuilder::GenerateSwapElements(CallRuntime* call) { // Fast call for custom callbacks. void HGraphBuilder::GenerateCallFunction(CallRuntime* call) { - return Bailout("inlined runtime function: CallFunction"); + // 1 ~ The function to call is not itself an argument to the call. + int arg_count = call->arguments()->length() - 1; + ASSERT(arg_count >= 1); // There's always at least a receiver. + + for (int i = 0; i < arg_count; ++i) { + CHECK_ALIVE(VisitArgument(call->arguments()->at(i))); + } + CHECK_ALIVE(VisitForValue(call->arguments()->last())); + HValue* function = Pop(); + HContext* context = new HContext; + AddInstruction(context); + HInvokeFunction* result = + new(zone()) HInvokeFunction(context, function, arg_count); + Drop(arg_count); + ast_context()->ReturnInstruction(result, call->id()); } diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 5c40b75..69d5e77 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -3087,15 +3087,14 @@ void FullCodeGenerator::EmitMathSqrt(ZoneList* args) { void FullCodeGenerator::EmitCallFunction(ZoneList* args) { ASSERT(args->length() >= 2); - int arg_count = args->length() - 2; // For receiver and function. - VisitForStackValue(args->at(0)); // Receiver. - for (int i = 0; i < arg_count; i++) { - VisitForStackValue(args->at(i + 1)); + int arg_count = args->length() - 2; // 2 ~ receiver and function. + for (int i = 0; i < arg_count + 1; ++i) { + VisitForStackValue(args->at(i)); } - VisitForAccumulatorValue(args->at(arg_count + 1)); // Function. + VisitForAccumulatorValue(args->last()); // Function. - // InvokeFunction requires function in edi. Move it in there. - if (!result_register().is(edi)) __ mov(edi, result_register()); + // InvokeFunction requires the function in edi. Move it in there. + __ mov(edi, result_register()); ParameterCount count(arg_count); __ InvokeFunction(edi, count, CALL_FUNCTION); __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 1ce7e4b..46c71e8 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -77,7 +77,7 @@ bool LCodeGen::GenerateCode() { void LCodeGen::FinishCode(Handle code) { ASSERT(is_done()); - code->set_stack_slots(StackSlotCount()); + code->set_stack_slots(GetStackSlotCount()); code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); PopulateDeoptimizationData(code); Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); @@ -132,7 +132,7 @@ bool LCodeGen::GeneratePrologue() { __ push(edi); // Callee's JS function. // Reserve space for the stack slots needed by the code. - int slots = StackSlotCount(); + int slots = GetStackSlotCount(); if (slots > 0) { if (FLAG_debug_code) { __ mov(Operand(eax), Immediate(slots)); @@ -254,7 +254,7 @@ bool LCodeGen::GenerateDeferredCode() { bool LCodeGen::GenerateSafepointTable() { ASSERT(is_done()); - safepoints_.Emit(masm(), StackSlotCount()); + safepoints_.Emit(masm(), GetStackSlotCount()); return !is_aborted(); } @@ -386,7 +386,7 @@ void LCodeGen::AddToTranslation(Translation* translation, translation->StoreDoubleStackSlot(op->index()); } else if (op->IsArgument()) { ASSERT(is_tagged); - int src_index = StackSlotCount() + op->index(); + int src_index = GetStackSlotCount() + op->index(); translation->StoreStackSlot(src_index); } else if (op->IsRegister()) { Register reg = ToRegister(op); @@ -2057,7 +2057,7 @@ void LCodeGen::DoReturn(LReturn* instr) { } __ mov(esp, ebp); __ pop(ebp); - __ Ret((ParameterCount() + 1) * kPointerSize, ecx); + __ Ret((GetParameterCount() + 1) * kPointerSize, ecx); } @@ -2493,7 +2493,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { SafepointGenerator safepoint_generator(this, pointers, env->deoptimization_index()); - v8::internal::ParameterCount actual(eax); + ParameterCount actual(eax); __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator); } @@ -2905,6 +2905,21 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { } +void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { + ASSERT(ToRegister(instr->context()).is(esi)); + ASSERT(ToRegister(instr->function()).is(edi)); + ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasDeoptimizationEnvironment()); + LPointerMap* pointers = instr->pointer_map(); + LEnvironment* env = instr->deoptimization_environment(); + RecordPosition(pointers->position()); + RegisterEnvironmentForDeoptimization(env); + SafepointGenerator generator(this, pointers, env->deoptimization_index()); + ParameterCount count(instr->arity()); + __ InvokeFunction(edi, count, CALL_FUNCTION, &generator); +} + + void LCodeGen::DoCallKeyed(LCallKeyed* instr) { ASSERT(ToRegister(instr->context()).is(esi)); ASSERT(ToRegister(instr->key()).is(ecx)); diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h index 6d42cd7..f8bbea3 100644 --- a/src/ia32/lithium-codegen-ia32.h +++ b/src/ia32/lithium-codegen-ia32.h @@ -147,8 +147,8 @@ class LCodeGen BASE_EMBEDDED { Register temporary, Register temporary2); - int StackSlotCount() const { return chunk()->spill_slot_count(); } - int ParameterCount() const { return scope()->num_parameters(); } + int GetStackSlotCount() const { return chunk()->spill_slot_count(); } + int GetParameterCount() const { return scope()->num_parameters(); } void Abort(const char* format, ...); void Comment(const char* format, ...); diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 409e4cd..aa91a83 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -302,6 +302,15 @@ void LStoreContextSlot::PrintDataTo(StringStream* stream) { } +void LInvokeFunction::PrintDataTo(StringStream* stream) { + stream->Add("= "); + InputAt(0)->PrintTo(stream); + stream->Add(" "); + InputAt(1)->PrintTo(stream); + stream->Add(" #%d / ", arity()); +} + + void LCallKeyed::PrintDataTo(StringStream* stream) { stream->Add("[ecx] #%d / ", arity()); } @@ -1221,6 +1230,15 @@ LInstruction* LChunkBuilder::DoCallConstantFunction( } +LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { + LOperand* context = UseFixed(instr->context(), esi); + LOperand* function = UseFixed(instr->function(), edi); + argument_count_ -= instr->argument_count(); + LInvokeFunction* result = new LInvokeFunction(context, function); + return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY); +} + + LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { BuiltinFunctionId op = instr->op(); if (op == kMathLog) { diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index d5d6ae5..76c90be 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -107,6 +107,7 @@ class LCodeGen; V(InstanceOfAndBranch) \ V(InstanceOfKnownGlobal) \ V(Integer32ToDouble) \ + V(InvokeFunction) \ V(IsNull) \ V(IsNullAndBranch) \ V(IsObject) \ @@ -1452,6 +1453,25 @@ class LCallConstantFunction: public LTemplateInstruction<1, 0, 0> { }; +class LInvokeFunction: public LTemplateInstruction<1, 2, 0> { + public: + LInvokeFunction(LOperand* context, LOperand* function) { + inputs_[0] = context; + inputs_[1] = function; + } + + DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function") + DECLARE_HYDROGEN_ACCESSOR(InvokeFunction) + + LOperand* context() { return inputs_[0]; } + LOperand* function() { return inputs_[1]; } + + virtual void PrintDataTo(StringStream* stream); + + int arity() const { return hydrogen()->argument_count() - 1; } +}; + + class LCallKeyed: public LTemplateInstruction<1, 2, 0> { public: LCallKeyed(LOperand* context, LOperand* key) { diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc index 97f0341..8d258ac 100644 --- a/src/runtime-profiler.cc +++ b/src/runtime-profiler.cc @@ -1,4 +1,4 @@ -// Copyright 2010 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -153,6 +153,7 @@ void RuntimeProfiler::Optimize(JSFunction* function, bool eager, int delay) { if (FLAG_trace_opt) { PrintF("[marking (%s) ", eager ? "eagerly" : "lazily"); function->PrintName(); + PrintF(" 0x%" V8PRIxPTR, reinterpret_cast(function->address())); PrintF(" for recompilation"); if (delay > 0) { PrintF(" (delayed %0.3f ms)", static_cast(delay) / 1000); diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 6062983..c28ebad 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -3043,15 +3043,14 @@ void FullCodeGenerator::EmitMathSqrt(ZoneList* args) { void FullCodeGenerator::EmitCallFunction(ZoneList* args) { ASSERT(args->length() >= 2); - int arg_count = args->length() - 2; // For receiver and function. - VisitForStackValue(args->at(0)); // Receiver. - for (int i = 0; i < arg_count; i++) { - VisitForStackValue(args->at(i + 1)); + int arg_count = args->length() - 2; // 2 ~ receiver and function. + for (int i = 0; i < arg_count + 1; i++) { + VisitForStackValue(args->at(i)); } - VisitForAccumulatorValue(args->at(arg_count + 1)); // Function. + VisitForAccumulatorValue(args->last()); // Function. - // InvokeFunction requires function in rdi. Move it in there. - if (!result_register().is(rdi)) __ movq(rdi, result_register()); + // InvokeFunction requires the function in rdi. Move it in there. + __ movq(rdi, result_register()); ParameterCount count(arg_count); __ InvokeFunction(rdi, count, CALL_FUNCTION); __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 0fcc8a0..746d02e 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -91,7 +91,7 @@ bool LCodeGen::GenerateCode() { void LCodeGen::FinishCode(Handle code) { ASSERT(is_done()); - code->set_stack_slots(StackSlotCount()); + code->set_stack_slots(GetStackSlotCount()); code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); PopulateDeoptimizationData(code); Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); @@ -146,7 +146,7 @@ bool LCodeGen::GeneratePrologue() { __ push(rdi); // Callee's JS function. // Reserve space for the stack slots needed by the code. - int slots = StackSlotCount(); + int slots = GetStackSlotCount(); if (slots > 0) { if (FLAG_debug_code) { __ Set(rax, slots); @@ -290,7 +290,7 @@ bool LCodeGen::GenerateSafepointTable() { while (byte_count-- > 0) { __ int3(); } - safepoints_.Emit(masm(), StackSlotCount()); + safepoints_.Emit(masm(), GetStackSlotCount()); return !is_aborted(); } @@ -418,7 +418,7 @@ void LCodeGen::AddToTranslation(Translation* translation, translation->StoreDoubleStackSlot(op->index()); } else if (op->IsArgument()) { ASSERT(is_tagged); - int src_index = StackSlotCount() + op->index(); + int src_index = GetStackSlotCount() + op->index(); translation->StoreStackSlot(src_index); } else if (op->IsRegister()) { Register reg = ToRegister(op); @@ -2058,7 +2058,7 @@ void LCodeGen::DoReturn(LReturn* instr) { } __ movq(rsp, rbp); __ pop(rbp); - __ Ret((ParameterCount() + 1) * kPointerSize, rcx); + __ Ret((GetParameterCount() + 1) * kPointerSize, rcx); } @@ -2507,6 +2507,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { env->deoptimization_index()); v8::internal::ParameterCount actual(rax); __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator); + __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); } @@ -2518,7 +2519,7 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) { void LCodeGen::DoContext(LContext* instr) { Register result = ToRegister(instr->result()); - __ movq(result, Operand(rbp, StandardFrameConstants::kContextOffset)); + __ movq(result, rsi); } @@ -2900,6 +2901,21 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { } +void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { + ASSERT(ToRegister(instr->function()).is(rdi)); + ASSERT(instr->HasPointerMap()); + ASSERT(instr->HasDeoptimizationEnvironment()); + LPointerMap* pointers = instr->pointer_map(); + LEnvironment* env = instr->deoptimization_environment(); + RecordPosition(pointers->position()); + RegisterEnvironmentForDeoptimization(env); + SafepointGenerator generator(this, pointers, env->deoptimization_index()); + ParameterCount count(instr->arity()); + __ InvokeFunction(rdi, count, CALL_FUNCTION, &generator); + __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); +} + + void LCodeGen::DoCallKeyed(LCallKeyed* instr) { ASSERT(ToRegister(instr->key()).is(rcx)); ASSERT(ToRegister(instr->result()).is(rax)); diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h index 0afbd7d..96e0a0f 100644 --- a/src/x64/lithium-codegen-x64.h +++ b/src/x64/lithium-codegen-x64.h @@ -141,8 +141,8 @@ class LCodeGen BASE_EMBEDDED { Register input, Register temporary); - int StackSlotCount() const { return chunk()->spill_slot_count(); } - int ParameterCount() const { return scope()->num_parameters(); } + int GetStackSlotCount() const { return chunk()->spill_slot_count(); } + int GetParameterCount() const { return scope()->num_parameters(); } void Abort(const char* format, ...); void Comment(const char* format, ...); diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index ddc227d..620bbc9 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -302,6 +302,13 @@ void LStoreContextSlot::PrintDataTo(StringStream* stream) { } +void LInvokeFunction::PrintDataTo(StringStream* stream) { + stream->Add("= "); + InputAt(0)->PrintTo(stream); + stream->Add(" #%d / ", arity()); +} + + void LCallKeyed::PrintDataTo(StringStream* stream) { stream->Add("[rcx] #%d / ", arity()); } @@ -1210,6 +1217,14 @@ LInstruction* LChunkBuilder::DoCallConstantFunction( } +LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { + LOperand* function = UseFixed(instr->function(), rdi); + argument_count_ -= instr->argument_count(); + LInvokeFunction* result = new LInvokeFunction(function); + return MarkAsCall(DefineFixed(result, rax), instr, CANNOT_DEOPTIMIZE_EAGERLY); +} + + LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { BuiltinFunctionId op = instr->op(); if (op == kMathLog || op == kMathSin || op == kMathCos) { diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index b532236..5a03d62 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -98,14 +98,15 @@ class LCodeGen; V(GlobalObject) \ V(GlobalReceiver) \ V(Goto) \ - V(HasInstanceType) \ - V(HasInstanceTypeAndBranch) \ V(HasCachedArrayIndex) \ V(HasCachedArrayIndexAndBranch) \ + V(HasInstanceType) \ + V(HasInstanceTypeAndBranch) \ V(InstanceOf) \ V(InstanceOfAndBranch) \ V(InstanceOfKnownGlobal) \ V(Integer32ToDouble) \ + V(InvokeFunction) \ V(IsNull) \ V(IsNullAndBranch) \ V(IsObject) \ @@ -1394,6 +1395,23 @@ class LCallConstantFunction: public LTemplateInstruction<1, 0, 0> { }; +class LInvokeFunction: public LTemplateInstruction<1, 1, 0> { + public: + LInvokeFunction(LOperand* function) { + inputs_[0] = function; + } + + DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function") + DECLARE_HYDROGEN_ACCESSOR(InvokeFunction) + + LOperand* function() { return inputs_[0]; } + + virtual void PrintDataTo(StringStream* stream); + + int arity() const { return hydrogen()->argument_count() - 1; } +}; + + class LCallKeyed: public LTemplateInstruction<1, 1, 0> { public: explicit LCallKeyed(LOperand* key) { -- 2.7.4