| 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 |