OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved.7 |
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 |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 // fp: Caller's frame pointer. | 146 // fp: Caller's frame pointer. |
147 // lr: Caller's pc. | 147 // lr: Caller's pc. |
148 | 148 |
149 // Classic mode functions and builtins need to replace the receiver with the | 149 // Classic mode functions and builtins need to replace the receiver with the |
150 // global proxy when called as functions (without an explicit receiver | 150 // global proxy when called as functions (without an explicit receiver |
151 // object). | 151 // object). |
152 if (info_->this_has_uses() && | 152 if (info_->this_has_uses() && |
153 info_->is_classic_mode() && | 153 info_->is_classic_mode() && |
154 !info_->is_native()) { | 154 !info_->is_native()) { |
155 Label ok; | 155 Label ok; |
156 __ Branch(&ok, eq, t1, Operand(zero_reg)); | |
157 | |
158 int receiver_offset = info_->scope()->num_parameters() * kPointerSize; | 156 int receiver_offset = info_->scope()->num_parameters() * kPointerSize; |
159 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 157 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
160 __ lw(a2, MemOperand(sp, receiver_offset)); | 158 __ lw(a2, MemOperand(sp, receiver_offset)); |
161 __ Branch(&ok, ne, a2, Operand(at)); | 159 __ Branch(&ok, ne, a2, Operand(at)); |
162 | 160 |
163 __ lw(a2, GlobalObjectOperand()); | 161 __ lw(a2, GlobalObjectOperand()); |
164 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); | 162 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); |
165 | 163 |
166 __ sw(a2, MemOperand(sp, receiver_offset)); | 164 __ sw(a2, MemOperand(sp, receiver_offset)); |
167 | 165 |
(...skipping 3266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3434 __ sll(scratch, length, 2); | 3432 __ sll(scratch, length, 2); |
3435 | 3433 |
3436 __ bind(&invoke); | 3434 __ bind(&invoke); |
3437 ASSERT(instr->HasPointerMap()); | 3435 ASSERT(instr->HasPointerMap()); |
3438 LPointerMap* pointers = instr->pointer_map(); | 3436 LPointerMap* pointers = instr->pointer_map(); |
3439 SafepointGenerator safepoint_generator( | 3437 SafepointGenerator safepoint_generator( |
3440 this, pointers, Safepoint::kLazyDeopt); | 3438 this, pointers, Safepoint::kLazyDeopt); |
3441 // The number of arguments is stored in receiver which is a0, as expected | 3439 // The number of arguments is stored in receiver which is a0, as expected |
3442 // by InvokeFunction. | 3440 // by InvokeFunction. |
3443 ParameterCount actual(receiver); | 3441 ParameterCount actual(receiver); |
3444 __ InvokeFunction(function, actual, CALL_FUNCTION, | 3442 __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator); |
3445 safepoint_generator, CALL_AS_FUNCTION); | |
3446 } | 3443 } |
3447 | 3444 |
3448 | 3445 |
3449 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 3446 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
3450 LOperand* argument = instr->value(); | 3447 LOperand* argument = instr->value(); |
3451 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { | 3448 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { |
3452 Abort(kDoPushArgumentNotImplementedForDoubleType); | 3449 Abort(kDoPushArgumentNotImplementedForDoubleType); |
3453 } else { | 3450 } else { |
3454 Register argument_reg = EmitLoadRegister(argument, at); | 3451 Register argument_reg = EmitLoadRegister(argument, at); |
3455 __ push(argument_reg); | 3452 __ push(argument_reg); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3509 Register global = ToRegister(instr->global_object()); | 3506 Register global = ToRegister(instr->global_object()); |
3510 Register result = ToRegister(instr->result()); | 3507 Register result = ToRegister(instr->result()); |
3511 __ lw(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); | 3508 __ lw(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); |
3512 } | 3509 } |
3513 | 3510 |
3514 | 3511 |
3515 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 3512 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
3516 int formal_parameter_count, | 3513 int formal_parameter_count, |
3517 int arity, | 3514 int arity, |
3518 LInstruction* instr, | 3515 LInstruction* instr, |
3519 CallKind call_kind, | |
3520 A1State a1_state) { | 3516 A1State a1_state) { |
3521 bool dont_adapt_arguments = | 3517 bool dont_adapt_arguments = |
3522 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 3518 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
3523 bool can_invoke_directly = | 3519 bool can_invoke_directly = |
3524 dont_adapt_arguments || formal_parameter_count == arity; | 3520 dont_adapt_arguments || formal_parameter_count == arity; |
3525 | 3521 |
3526 LPointerMap* pointers = instr->pointer_map(); | 3522 LPointerMap* pointers = instr->pointer_map(); |
3527 | 3523 |
3528 if (can_invoke_directly) { | 3524 if (can_invoke_directly) { |
3529 if (a1_state == A1_UNINITIALIZED) { | 3525 if (a1_state == A1_UNINITIALIZED) { |
3530 __ li(a1, function); | 3526 __ li(a1, function); |
3531 } | 3527 } |
3532 | 3528 |
3533 // Change context. | 3529 // Change context. |
3534 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 3530 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
3535 | 3531 |
3536 // Set r0 to arguments count if adaption is not needed. Assumes that r0 | 3532 // Set r0 to arguments count if adaption is not needed. Assumes that r0 |
3537 // is available to write to at this point. | 3533 // is available to write to at this point. |
3538 if (dont_adapt_arguments) { | 3534 if (dont_adapt_arguments) { |
3539 __ li(a0, Operand(arity)); | 3535 __ li(a0, Operand(arity)); |
3540 } | 3536 } |
3541 | 3537 |
3542 // Invoke function. | 3538 // Invoke function. |
3543 __ SetCallKind(t1, call_kind); | |
3544 __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 3539 __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
3545 __ Call(at); | 3540 __ Call(at); |
3546 | 3541 |
3547 // Set up deoptimization. | 3542 // Set up deoptimization. |
3548 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); | 3543 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
3549 } else { | 3544 } else { |
3550 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3545 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
3551 ParameterCount count(arity); | 3546 ParameterCount count(arity); |
3552 ParameterCount expected(formal_parameter_count); | 3547 ParameterCount expected(formal_parameter_count); |
3553 __ InvokeFunction( | 3548 __ InvokeFunction(function, expected, count, CALL_FUNCTION, generator); |
3554 function, expected, count, CALL_FUNCTION, generator, call_kind); | |
3555 } | 3549 } |
3556 } | 3550 } |
3557 | 3551 |
3558 | 3552 |
3559 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 3553 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
3560 ASSERT(ToRegister(instr->result()).is(v0)); | 3554 ASSERT(ToRegister(instr->result()).is(v0)); |
3561 __ mov(a0, v0); | 3555 __ mov(a0, v0); |
3562 CallKnownFunction(instr->hydrogen()->function(), | 3556 CallKnownFunction(instr->hydrogen()->function(), |
3563 instr->hydrogen()->formal_parameter_count(), | 3557 instr->hydrogen()->formal_parameter_count(), |
3564 instr->arity(), | 3558 instr->arity(), |
3565 instr, | 3559 instr, |
3566 CALL_AS_FUNCTION, | |
3567 A1_UNINITIALIZED); | 3560 A1_UNINITIALIZED); |
3568 } | 3561 } |
3569 | 3562 |
3570 | 3563 |
3571 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { | 3564 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { |
3572 ASSERT(instr->context() != NULL); | 3565 ASSERT(instr->context() != NULL); |
3573 ASSERT(ToRegister(instr->context()).is(cp)); | 3566 ASSERT(ToRegister(instr->context()).is(cp)); |
3574 Register input = ToRegister(instr->value()); | 3567 Register input = ToRegister(instr->value()); |
3575 Register result = ToRegister(instr->result()); | 3568 Register result = ToRegister(instr->result()); |
3576 Register scratch = scratch0(); | 3569 Register scratch = scratch0(); |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3879 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 3872 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
3880 ASSERT(ToRegister(instr->context()).is(cp)); | 3873 ASSERT(ToRegister(instr->context()).is(cp)); |
3881 ASSERT(ToRegister(instr->function()).is(a1)); | 3874 ASSERT(ToRegister(instr->function()).is(a1)); |
3882 ASSERT(instr->HasPointerMap()); | 3875 ASSERT(instr->HasPointerMap()); |
3883 | 3876 |
3884 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); | 3877 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
3885 if (known_function.is_null()) { | 3878 if (known_function.is_null()) { |
3886 LPointerMap* pointers = instr->pointer_map(); | 3879 LPointerMap* pointers = instr->pointer_map(); |
3887 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3880 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
3888 ParameterCount count(instr->arity()); | 3881 ParameterCount count(instr->arity()); |
3889 __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_FUNCTION); | 3882 __ InvokeFunction(a1, count, CALL_FUNCTION, generator); |
3890 } else { | 3883 } else { |
3891 CallKnownFunction(known_function, | 3884 CallKnownFunction(known_function, |
3892 instr->hydrogen()->formal_parameter_count(), | 3885 instr->hydrogen()->formal_parameter_count(), |
3893 instr->arity(), | 3886 instr->arity(), |
3894 instr, | 3887 instr, |
3895 CALL_AS_FUNCTION, | |
3896 A1_CONTAINS_TARGET); | 3888 A1_CONTAINS_TARGET); |
3897 } | 3889 } |
3898 } | 3890 } |
3899 | 3891 |
3900 | 3892 |
3901 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { | 3893 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { |
3902 ASSERT(ToRegister(instr->context()).is(cp)); | 3894 ASSERT(ToRegister(instr->context()).is(cp)); |
3903 ASSERT(ToRegister(instr->result()).is(v0)); | 3895 ASSERT(ToRegister(instr->result()).is(v0)); |
3904 | 3896 |
3905 int arity = instr->arity(); | 3897 int arity = instr->arity(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3948 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3940 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
3949 } | 3941 } |
3950 | 3942 |
3951 | 3943 |
3952 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3944 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
3953 ASSERT(ToRegister(instr->result()).is(v0)); | 3945 ASSERT(ToRegister(instr->result()).is(v0)); |
3954 CallKnownFunction(instr->hydrogen()->target(), | 3946 CallKnownFunction(instr->hydrogen()->target(), |
3955 instr->hydrogen()->formal_parameter_count(), | 3947 instr->hydrogen()->formal_parameter_count(), |
3956 instr->arity(), | 3948 instr->arity(), |
3957 instr, | 3949 instr, |
3958 CALL_AS_FUNCTION, | |
3959 A1_UNINITIALIZED); | 3950 A1_UNINITIALIZED); |
3960 } | 3951 } |
3961 | 3952 |
3962 | 3953 |
3963 void LCodeGen::DoCallNew(LCallNew* instr) { | 3954 void LCodeGen::DoCallNew(LCallNew* instr) { |
3964 ASSERT(ToRegister(instr->context()).is(cp)); | 3955 ASSERT(ToRegister(instr->context()).is(cp)); |
3965 ASSERT(ToRegister(instr->constructor()).is(a1)); | 3956 ASSERT(ToRegister(instr->constructor()).is(a1)); |
3966 ASSERT(ToRegister(instr->result()).is(v0)); | 3957 ASSERT(ToRegister(instr->result()).is(v0)); |
3967 | 3958 |
3968 __ li(a0, Operand(instr->arity())); | 3959 __ li(a0, Operand(instr->arity())); |
(...skipping 1847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5816 __ Subu(scratch, result, scratch); | 5807 __ Subu(scratch, result, scratch); |
5817 __ lw(result, FieldMemOperand(scratch, | 5808 __ lw(result, FieldMemOperand(scratch, |
5818 FixedArray::kHeaderSize - kPointerSize)); | 5809 FixedArray::kHeaderSize - kPointerSize)); |
5819 __ bind(&done); | 5810 __ bind(&done); |
5820 } | 5811 } |
5821 | 5812 |
5822 | 5813 |
5823 #undef __ | 5814 #undef __ |
5824 | 5815 |
5825 } } // namespace v8::internal | 5816 } } // namespace v8::internal |
OLD | NEW |