OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 __ int3(); | 155 __ int3(); |
156 } | 156 } |
157 #endif | 157 #endif |
158 | 158 |
159 // Classic mode functions need to replace the receiver with the global proxy | 159 // Classic mode functions need to replace the receiver with the global proxy |
160 // when called as functions (without an explicit receiver object). | 160 // when called as functions (without an explicit receiver object). |
161 if (info_->this_has_uses() && | 161 if (info_->this_has_uses() && |
162 info_->is_classic_mode() && | 162 info_->is_classic_mode() && |
163 !info_->is_native()) { | 163 !info_->is_native()) { |
164 Label ok; | 164 Label ok; |
165 __ testq(rcx, rcx); | |
166 __ j(zero, &ok, Label::kNear); | |
167 | |
168 StackArgumentsAccessor args(rsp, scope()->num_parameters()); | 165 StackArgumentsAccessor args(rsp, scope()->num_parameters()); |
169 __ movq(rcx, args.GetReceiverOperand()); | 166 __ movq(rcx, args.GetReceiverOperand()); |
170 | 167 |
171 __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex); | 168 __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex); |
172 __ j(not_equal, &ok, Label::kNear); | 169 __ j(not_equal, &ok, Label::kNear); |
173 | 170 |
174 __ movq(rcx, GlobalObjectOperand()); | 171 __ movq(rcx, GlobalObjectOperand()); |
175 __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); | 172 __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); |
176 | 173 |
177 __ movq(args.GetReceiverOperand(), rcx); | 174 __ movq(args.GetReceiverOperand(), rcx); |
(...skipping 3117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3295 __ decl(length); | 3292 __ decl(length); |
3296 __ j(not_zero, &loop); | 3293 __ j(not_zero, &loop); |
3297 | 3294 |
3298 // Invoke the function. | 3295 // Invoke the function. |
3299 __ bind(&invoke); | 3296 __ bind(&invoke); |
3300 ASSERT(instr->HasPointerMap()); | 3297 ASSERT(instr->HasPointerMap()); |
3301 LPointerMap* pointers = instr->pointer_map(); | 3298 LPointerMap* pointers = instr->pointer_map(); |
3302 SafepointGenerator safepoint_generator( | 3299 SafepointGenerator safepoint_generator( |
3303 this, pointers, Safepoint::kLazyDeopt); | 3300 this, pointers, Safepoint::kLazyDeopt); |
3304 ParameterCount actual(rax); | 3301 ParameterCount actual(rax); |
3305 __ InvokeFunction(function, actual, CALL_FUNCTION, | 3302 __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator); |
3306 safepoint_generator, CALL_AS_FUNCTION); | |
3307 } | 3303 } |
3308 | 3304 |
3309 | 3305 |
3310 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 3306 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
3311 LOperand* argument = instr->value(); | 3307 LOperand* argument = instr->value(); |
3312 EmitPushTaggedOperand(argument); | 3308 EmitPushTaggedOperand(argument); |
3313 } | 3309 } |
3314 | 3310 |
3315 | 3311 |
3316 void LCodeGen::DoDrop(LDrop* instr) { | 3312 void LCodeGen::DoDrop(LDrop* instr) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3364 Register global = ToRegister(instr->global()); | 3360 Register global = ToRegister(instr->global()); |
3365 Register result = ToRegister(instr->result()); | 3361 Register result = ToRegister(instr->result()); |
3366 __ movq(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); | 3362 __ movq(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); |
3367 } | 3363 } |
3368 | 3364 |
3369 | 3365 |
3370 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 3366 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
3371 int formal_parameter_count, | 3367 int formal_parameter_count, |
3372 int arity, | 3368 int arity, |
3373 LInstruction* instr, | 3369 LInstruction* instr, |
3374 CallKind call_kind, | |
3375 RDIState rdi_state) { | 3370 RDIState rdi_state) { |
3376 bool dont_adapt_arguments = | 3371 bool dont_adapt_arguments = |
3377 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 3372 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
3378 bool can_invoke_directly = | 3373 bool can_invoke_directly = |
3379 dont_adapt_arguments || formal_parameter_count == arity; | 3374 dont_adapt_arguments || formal_parameter_count == arity; |
3380 | 3375 |
3381 LPointerMap* pointers = instr->pointer_map(); | 3376 LPointerMap* pointers = instr->pointer_map(); |
3382 | 3377 |
3383 if (can_invoke_directly) { | 3378 if (can_invoke_directly) { |
3384 if (rdi_state == RDI_UNINITIALIZED) { | 3379 if (rdi_state == RDI_UNINITIALIZED) { |
3385 __ Move(rdi, function); | 3380 __ Move(rdi, function); |
3386 } | 3381 } |
3387 | 3382 |
3388 // Change context. | 3383 // Change context. |
3389 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 3384 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
3390 | 3385 |
3391 // Set rax to arguments count if adaption is not needed. Assumes that rax | 3386 // Set rax to arguments count if adaption is not needed. Assumes that rax |
3392 // is available to write to at this point. | 3387 // is available to write to at this point. |
3393 if (dont_adapt_arguments) { | 3388 if (dont_adapt_arguments) { |
3394 __ Set(rax, arity); | 3389 __ Set(rax, arity); |
3395 } | 3390 } |
3396 | 3391 |
3397 // Invoke function. | 3392 // Invoke function. |
3398 __ SetCallKind(rcx, call_kind); | |
3399 if (function.is_identical_to(info()->closure())) { | 3393 if (function.is_identical_to(info()->closure())) { |
3400 __ CallSelf(); | 3394 __ CallSelf(); |
3401 } else { | 3395 } else { |
3402 __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 3396 __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
3403 } | 3397 } |
3404 | 3398 |
3405 // Set up deoptimization. | 3399 // Set up deoptimization. |
3406 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); | 3400 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); |
3407 } else { | 3401 } else { |
3408 // We need to adapt arguments. | 3402 // We need to adapt arguments. |
3409 SafepointGenerator generator( | 3403 SafepointGenerator generator( |
3410 this, pointers, Safepoint::kLazyDeopt); | 3404 this, pointers, Safepoint::kLazyDeopt); |
3411 ParameterCount count(arity); | 3405 ParameterCount count(arity); |
3412 ParameterCount expected(formal_parameter_count); | 3406 ParameterCount expected(formal_parameter_count); |
3413 __ InvokeFunction( | 3407 __ InvokeFunction(function, expected, count, CALL_FUNCTION, generator); |
3414 function, expected, count, CALL_FUNCTION, generator, call_kind); | |
3415 } | 3408 } |
3416 } | 3409 } |
3417 | 3410 |
3418 | 3411 |
3419 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 3412 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
3420 ASSERT(ToRegister(instr->result()).is(rax)); | 3413 ASSERT(ToRegister(instr->result()).is(rax)); |
3421 CallKnownFunction(instr->hydrogen()->function(), | 3414 CallKnownFunction(instr->hydrogen()->function(), |
3422 instr->hydrogen()->formal_parameter_count(), | 3415 instr->hydrogen()->formal_parameter_count(), |
3423 instr->arity(), | 3416 instr->arity(), |
3424 instr, | 3417 instr, |
3425 CALL_AS_FUNCTION, | |
3426 RDI_UNINITIALIZED); | 3418 RDI_UNINITIALIZED); |
3427 } | 3419 } |
3428 | 3420 |
3429 | 3421 |
3430 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { | 3422 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { |
3431 Register input_reg = ToRegister(instr->value()); | 3423 Register input_reg = ToRegister(instr->value()); |
3432 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), | 3424 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), |
3433 Heap::kHeapNumberMapRootIndex); | 3425 Heap::kHeapNumberMapRootIndex); |
3434 DeoptimizeIf(not_equal, instr->environment()); | 3426 DeoptimizeIf(not_equal, instr->environment()); |
3435 | 3427 |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3774 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 3766 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
3775 ASSERT(ToRegister(instr->context()).is(rsi)); | 3767 ASSERT(ToRegister(instr->context()).is(rsi)); |
3776 ASSERT(ToRegister(instr->function()).is(rdi)); | 3768 ASSERT(ToRegister(instr->function()).is(rdi)); |
3777 ASSERT(instr->HasPointerMap()); | 3769 ASSERT(instr->HasPointerMap()); |
3778 | 3770 |
3779 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); | 3771 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
3780 if (known_function.is_null()) { | 3772 if (known_function.is_null()) { |
3781 LPointerMap* pointers = instr->pointer_map(); | 3773 LPointerMap* pointers = instr->pointer_map(); |
3782 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3774 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
3783 ParameterCount count(instr->arity()); | 3775 ParameterCount count(instr->arity()); |
3784 __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_FUNCTION); | 3776 __ InvokeFunction(rdi, count, CALL_FUNCTION, generator); |
3785 } else { | 3777 } else { |
3786 CallKnownFunction(known_function, | 3778 CallKnownFunction(known_function, |
3787 instr->hydrogen()->formal_parameter_count(), | 3779 instr->hydrogen()->formal_parameter_count(), |
3788 instr->arity(), | 3780 instr->arity(), |
3789 instr, | 3781 instr, |
3790 CALL_AS_FUNCTION, | |
3791 RDI_CONTAINS_TARGET); | 3782 RDI_CONTAINS_TARGET); |
3792 } | 3783 } |
3793 } | 3784 } |
3794 | 3785 |
3795 | 3786 |
3796 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { | 3787 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { |
3797 ASSERT(ToRegister(instr->context()).is(rsi)); | 3788 ASSERT(ToRegister(instr->context()).is(rsi)); |
3798 ASSERT(ToRegister(instr->key()).is(rcx)); | 3789 ASSERT(ToRegister(instr->key()).is(rcx)); |
3799 ASSERT(ToRegister(instr->result()).is(rax)); | 3790 ASSERT(ToRegister(instr->result()).is(rax)); |
3800 | 3791 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3843 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3834 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
3844 } | 3835 } |
3845 | 3836 |
3846 | 3837 |
3847 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3838 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
3848 ASSERT(ToRegister(instr->result()).is(rax)); | 3839 ASSERT(ToRegister(instr->result()).is(rax)); |
3849 CallKnownFunction(instr->hydrogen()->target(), | 3840 CallKnownFunction(instr->hydrogen()->target(), |
3850 instr->hydrogen()->formal_parameter_count(), | 3841 instr->hydrogen()->formal_parameter_count(), |
3851 instr->arity(), | 3842 instr->arity(), |
3852 instr, | 3843 instr, |
3853 CALL_AS_FUNCTION, | |
3854 RDI_UNINITIALIZED); | 3844 RDI_UNINITIALIZED); |
3855 } | 3845 } |
3856 | 3846 |
3857 | 3847 |
3858 void LCodeGen::DoCallNew(LCallNew* instr) { | 3848 void LCodeGen::DoCallNew(LCallNew* instr) { |
3859 ASSERT(ToRegister(instr->context()).is(rsi)); | 3849 ASSERT(ToRegister(instr->context()).is(rsi)); |
3860 ASSERT(ToRegister(instr->constructor()).is(rdi)); | 3850 ASSERT(ToRegister(instr->constructor()).is(rdi)); |
3861 ASSERT(ToRegister(instr->result()).is(rax)); | 3851 ASSERT(ToRegister(instr->result()).is(rax)); |
3862 | 3852 |
3863 __ Set(rax, instr->arity()); | 3853 __ Set(rax, instr->arity()); |
(...skipping 1772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5636 FixedArray::kHeaderSize - kPointerSize)); | 5626 FixedArray::kHeaderSize - kPointerSize)); |
5637 __ bind(&done); | 5627 __ bind(&done); |
5638 } | 5628 } |
5639 | 5629 |
5640 | 5630 |
5641 #undef __ | 5631 #undef __ |
5642 | 5632 |
5643 } } // namespace v8::internal | 5633 } } // namespace v8::internal |
5644 | 5634 |
5645 #endif // V8_TARGET_ARCH_X64 | 5635 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |