OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2708 __ sll(scratch, length, 2); | 2708 __ sll(scratch, length, 2); |
2709 | 2709 |
2710 __ bind(&invoke); | 2710 __ bind(&invoke); |
2711 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); | 2711 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); |
2712 LPointerMap* pointers = instr->pointer_map(); | 2712 LPointerMap* pointers = instr->pointer_map(); |
2713 RecordPosition(pointers->position()); | 2713 RecordPosition(pointers->position()); |
2714 SafepointGenerator safepoint_generator( | 2714 SafepointGenerator safepoint_generator( |
2715 this, pointers, Safepoint::kLazyDeopt); | 2715 this, pointers, Safepoint::kLazyDeopt); |
2716 // The number of arguments is stored in receiver which is a0, as expected | 2716 // The number of arguments is stored in receiver which is a0, as expected |
2717 // by InvokeFunction. | 2717 // by InvokeFunction. |
2718 v8::internal::ParameterCount actual(receiver); | 2718 ParameterCount actual(receiver); |
2719 __ InvokeFunction(function, actual, CALL_FUNCTION, | 2719 __ InvokeFunction(function, actual, CALL_FUNCTION, |
2720 safepoint_generator, CALL_AS_METHOD); | 2720 safepoint_generator, CALL_AS_METHOD); |
2721 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2721 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2722 } | 2722 } |
2723 | 2723 |
2724 | 2724 |
2725 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 2725 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
2726 LOperand* argument = instr->InputAt(0); | 2726 LOperand* argument = instr->InputAt(0); |
2727 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { | 2727 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { |
2728 Abort("DoPushArgument not implemented for double type."); | 2728 Abort("DoPushArgument not implemented for double type."); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2764 Register global = ToRegister(instr->global()); | 2764 Register global = ToRegister(instr->global()); |
2765 Register result = ToRegister(instr->result()); | 2765 Register result = ToRegister(instr->result()); |
2766 __ lw(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); | 2766 __ lw(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); |
2767 } | 2767 } |
2768 | 2768 |
2769 | 2769 |
2770 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 2770 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
2771 int arity, | 2771 int arity, |
2772 LInstruction* instr, | 2772 LInstruction* instr, |
2773 CallKind call_kind) { | 2773 CallKind call_kind) { |
2774 // Change context if needed. | 2774 bool can_invoke_directly = !function->NeedsArgumentsAdaption() || |
2775 bool change_context = | 2775 function->shared()->formal_parameter_count() == arity; |
2776 (info()->closure()->context() != function->context()) || | |
2777 scope()->contains_with() || | |
2778 (scope()->num_heap_slots() > 0); | |
2779 if (change_context) { | |
2780 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | |
2781 } | |
2782 | |
2783 // Set a0 to arguments count if adaption is not needed. Assumes that a0 | |
2784 // is available to write to at this point. | |
2785 if (!function->NeedsArgumentsAdaption()) { | |
2786 __ li(a0, Operand(arity)); | |
2787 } | |
2788 | 2776 |
2789 LPointerMap* pointers = instr->pointer_map(); | 2777 LPointerMap* pointers = instr->pointer_map(); |
2790 RecordPosition(pointers->position()); | 2778 RecordPosition(pointers->position()); |
2791 | 2779 |
2792 // Invoke function. | 2780 if (can_invoke_directly) { |
2793 __ SetCallKind(t1, call_kind); | 2781 __ LoadHeapObject(a1, function); |
2794 __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 2782 // Change context if needed. |
2795 __ Call(at); | 2783 bool change_context = |
| 2784 (info()->closure()->context() != function->context()) || |
| 2785 scope()->contains_with() || |
| 2786 (scope()->num_heap_slots() > 0); |
| 2787 if (change_context) { |
| 2788 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
| 2789 } |
2796 | 2790 |
2797 // Set up deoptimization. | 2791 // Set r0 to arguments count if adaption is not needed. Assumes that r0 |
2798 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); | 2792 // is available to write to at this point. |
| 2793 if (!function->NeedsArgumentsAdaption()) { |
| 2794 __ li(a0, Operand(arity)); |
| 2795 } |
| 2796 |
| 2797 // Invoke function. |
| 2798 __ SetCallKind(t1, call_kind); |
| 2799 __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
| 2800 __ Call(at); |
| 2801 |
| 2802 // Set up deoptimization. |
| 2803 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
| 2804 } else { |
| 2805 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 2806 ParameterCount count(arity); |
| 2807 __ InvokeFunction(function, count, CALL_FUNCTION, generator, call_kind); |
| 2808 } |
2799 | 2809 |
2800 // Restore context. | 2810 // Restore context. |
2801 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2811 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2802 } | 2812 } |
2803 | 2813 |
2804 | 2814 |
2805 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2815 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
2806 ASSERT(ToRegister(instr->result()).is(v0)); | 2816 ASSERT(ToRegister(instr->result()).is(v0)); |
2807 __ mov(a0, v0); | 2817 __ mov(a0, v0); |
2808 __ LoadHeapObject(a1, instr->function()); | |
2809 CallKnownFunction(instr->function(), instr->arity(), instr, CALL_AS_METHOD); | 2818 CallKnownFunction(instr->function(), instr->arity(), instr, CALL_AS_METHOD); |
2810 } | 2819 } |
2811 | 2820 |
2812 | 2821 |
2813 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2822 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
2814 Register input = ToRegister(instr->InputAt(0)); | 2823 Register input = ToRegister(instr->InputAt(0)); |
2815 Register result = ToRegister(instr->result()); | 2824 Register result = ToRegister(instr->result()); |
2816 Register scratch = scratch0(); | 2825 Register scratch = scratch0(); |
2817 | 2826 |
2818 // Deoptimize if not a heap number. | 2827 // Deoptimize if not a heap number. |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3241 Handle<Code> ic = | 3250 Handle<Code> ic = |
3242 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); | 3251 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
3243 __ li(a2, Operand(instr->name())); | 3252 __ li(a2, Operand(instr->name())); |
3244 CallCode(ic, mode, instr); | 3253 CallCode(ic, mode, instr); |
3245 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3254 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3246 } | 3255 } |
3247 | 3256 |
3248 | 3257 |
3249 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3258 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
3250 ASSERT(ToRegister(instr->result()).is(v0)); | 3259 ASSERT(ToRegister(instr->result()).is(v0)); |
3251 __ LoadHeapObject(a1, instr->target()); | |
3252 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); | 3260 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); |
3253 } | 3261 } |
3254 | 3262 |
3255 | 3263 |
3256 void LCodeGen::DoCallNew(LCallNew* instr) { | 3264 void LCodeGen::DoCallNew(LCallNew* instr) { |
3257 ASSERT(ToRegister(instr->InputAt(0)).is(a1)); | 3265 ASSERT(ToRegister(instr->InputAt(0)).is(a1)); |
3258 ASSERT(ToRegister(instr->result()).is(v0)); | 3266 ASSERT(ToRegister(instr->result()).is(v0)); |
3259 | 3267 |
3260 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); | 3268 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); |
3261 __ li(a0, Operand(instr->arity())); | 3269 __ li(a0, Operand(instr->arity())); |
(...skipping 1444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4706 ASSERT(!environment->HasBeenRegistered()); | 4714 ASSERT(!environment->HasBeenRegistered()); |
4707 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); | 4715 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); |
4708 ASSERT(osr_pc_offset_ == -1); | 4716 ASSERT(osr_pc_offset_ == -1); |
4709 osr_pc_offset_ = masm()->pc_offset(); | 4717 osr_pc_offset_ = masm()->pc_offset(); |
4710 } | 4718 } |
4711 | 4719 |
4712 | 4720 |
4713 #undef __ | 4721 #undef __ |
4714 | 4722 |
4715 } } // namespace v8::internal | 4723 } } // namespace v8::internal |
OLD | NEW |