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 2810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2821 __ b(ne, &loop); | 2821 __ b(ne, &loop); |
2822 | 2822 |
2823 __ bind(&invoke); | 2823 __ bind(&invoke); |
2824 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); | 2824 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); |
2825 LPointerMap* pointers = instr->pointer_map(); | 2825 LPointerMap* pointers = instr->pointer_map(); |
2826 RecordPosition(pointers->position()); | 2826 RecordPosition(pointers->position()); |
2827 SafepointGenerator safepoint_generator( | 2827 SafepointGenerator safepoint_generator( |
2828 this, pointers, Safepoint::kLazyDeopt); | 2828 this, pointers, Safepoint::kLazyDeopt); |
2829 // The number of arguments is stored in receiver which is r0, as expected | 2829 // The number of arguments is stored in receiver which is r0, as expected |
2830 // by InvokeFunction. | 2830 // by InvokeFunction. |
2831 v8::internal::ParameterCount actual(receiver); | 2831 ParameterCount actual(receiver); |
2832 __ InvokeFunction(function, actual, CALL_FUNCTION, | 2832 __ InvokeFunction(function, actual, CALL_FUNCTION, |
2833 safepoint_generator, CALL_AS_METHOD); | 2833 safepoint_generator, CALL_AS_METHOD); |
2834 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2834 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2835 } | 2835 } |
2836 | 2836 |
2837 | 2837 |
2838 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 2838 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
2839 LOperand* argument = instr->InputAt(0); | 2839 LOperand* argument = instr->InputAt(0); |
2840 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { | 2840 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { |
2841 Abort("DoPushArgument not implemented for double type."); | 2841 Abort("DoPushArgument not implemented for double type."); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2876 Register global = ToRegister(instr->global()); | 2876 Register global = ToRegister(instr->global()); |
2877 Register result = ToRegister(instr->result()); | 2877 Register result = ToRegister(instr->result()); |
2878 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); | 2878 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); |
2879 } | 2879 } |
2880 | 2880 |
2881 | 2881 |
2882 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 2882 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
2883 int arity, | 2883 int arity, |
2884 LInstruction* instr, | 2884 LInstruction* instr, |
2885 CallKind call_kind) { | 2885 CallKind call_kind) { |
2886 // Change context if needed. | 2886 bool can_invoke_directly = !function->NeedsArgumentsAdaption() || |
2887 bool change_context = | 2887 function->shared()->formal_parameter_count() == arity; |
2888 (info()->closure()->context() != function->context()) || | |
2889 scope()->contains_with() || | |
2890 (scope()->num_heap_slots() > 0); | |
2891 if (change_context) { | |
2892 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | |
2893 } | |
2894 | |
2895 // Set r0 to arguments count if adaption is not needed. Assumes that r0 | |
2896 // is available to write to at this point. | |
2897 if (!function->NeedsArgumentsAdaption()) { | |
2898 __ mov(r0, Operand(arity)); | |
2899 } | |
2900 | 2888 |
2901 LPointerMap* pointers = instr->pointer_map(); | 2889 LPointerMap* pointers = instr->pointer_map(); |
2902 RecordPosition(pointers->position()); | 2890 RecordPosition(pointers->position()); |
2903 | 2891 |
2904 // Invoke function. | 2892 if (can_invoke_directly) { |
2905 __ SetCallKind(r5, call_kind); | 2893 __ LoadHeapObject(r1, function); |
2906 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 2894 // Change context if needed. |
2907 __ Call(ip); | 2895 bool change_context = |
| 2896 (info()->closure()->context() != function->context()) || |
| 2897 scope()->contains_with() || |
| 2898 (scope()->num_heap_slots() > 0); |
| 2899 if (change_context) { |
| 2900 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 2901 } |
2908 | 2902 |
2909 // Set up deoptimization. | 2903 // Set r0 to arguments count if adaption is not needed. Assumes that r0 |
2910 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); | 2904 // is available to write to at this point. |
| 2905 if (!function->NeedsArgumentsAdaption()) { |
| 2906 __ mov(r0, Operand(arity)); |
| 2907 } |
| 2908 |
| 2909 // Invoke function. |
| 2910 __ SetCallKind(r5, call_kind); |
| 2911 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
| 2912 __ Call(ip); |
| 2913 |
| 2914 // Set up deoptimization. |
| 2915 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
| 2916 } else { |
| 2917 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 2918 ParameterCount count(arity); |
| 2919 __ InvokeFunction(function, count, CALL_FUNCTION, generator, call_kind); |
| 2920 } |
2911 | 2921 |
2912 // Restore context. | 2922 // Restore context. |
2913 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2923 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2914 } | 2924 } |
2915 | 2925 |
2916 | 2926 |
2917 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2927 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
2918 ASSERT(ToRegister(instr->result()).is(r0)); | 2928 ASSERT(ToRegister(instr->result()).is(r0)); |
2919 __ LoadHeapObject(r1, instr->function()); | |
2920 CallKnownFunction(instr->function(), | 2929 CallKnownFunction(instr->function(), |
2921 instr->arity(), | 2930 instr->arity(), |
2922 instr, | 2931 instr, |
2923 CALL_AS_METHOD); | 2932 CALL_AS_METHOD); |
2924 } | 2933 } |
2925 | 2934 |
2926 | 2935 |
2927 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2936 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
2928 Register input = ToRegister(instr->InputAt(0)); | 2937 Register input = ToRegister(instr->InputAt(0)); |
2929 Register result = ToRegister(instr->result()); | 2938 Register result = ToRegister(instr->result()); |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3344 Handle<Code> ic = | 3353 Handle<Code> ic = |
3345 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); | 3354 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
3346 __ mov(r2, Operand(instr->name())); | 3355 __ mov(r2, Operand(instr->name())); |
3347 CallCode(ic, mode, instr); | 3356 CallCode(ic, mode, instr); |
3348 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3357 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3349 } | 3358 } |
3350 | 3359 |
3351 | 3360 |
3352 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3361 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
3353 ASSERT(ToRegister(instr->result()).is(r0)); | 3362 ASSERT(ToRegister(instr->result()).is(r0)); |
3354 __ LoadHeapObject(r1, instr->target()); | |
3355 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); | 3363 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); |
3356 } | 3364 } |
3357 | 3365 |
3358 | 3366 |
3359 void LCodeGen::DoCallNew(LCallNew* instr) { | 3367 void LCodeGen::DoCallNew(LCallNew* instr) { |
3360 ASSERT(ToRegister(instr->InputAt(0)).is(r1)); | 3368 ASSERT(ToRegister(instr->InputAt(0)).is(r1)); |
3361 ASSERT(ToRegister(instr->result()).is(r0)); | 3369 ASSERT(ToRegister(instr->result()).is(r0)); |
3362 | 3370 |
3363 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); | 3371 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); |
3364 __ mov(r0, Operand(instr->arity())); | 3372 __ mov(r0, Operand(instr->arity())); |
(...skipping 1419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4784 ASSERT(osr_pc_offset_ == -1); | 4792 ASSERT(osr_pc_offset_ == -1); |
4785 osr_pc_offset_ = masm()->pc_offset(); | 4793 osr_pc_offset_ = masm()->pc_offset(); |
4786 } | 4794 } |
4787 | 4795 |
4788 | 4796 |
4789 | 4797 |
4790 | 4798 |
4791 #undef __ | 4799 #undef __ |
4792 | 4800 |
4793 } } // namespace v8::internal | 4801 } } // namespace v8::internal |
OLD | NEW |