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 2547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2558 __ decl(length); | 2558 __ decl(length); |
2559 __ j(not_zero, &loop); | 2559 __ j(not_zero, &loop); |
2560 | 2560 |
2561 // Invoke the function. | 2561 // Invoke the function. |
2562 __ bind(&invoke); | 2562 __ bind(&invoke); |
2563 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); | 2563 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); |
2564 LPointerMap* pointers = instr->pointer_map(); | 2564 LPointerMap* pointers = instr->pointer_map(); |
2565 RecordPosition(pointers->position()); | 2565 RecordPosition(pointers->position()); |
2566 SafepointGenerator safepoint_generator( | 2566 SafepointGenerator safepoint_generator( |
2567 this, pointers, Safepoint::kLazyDeopt); | 2567 this, pointers, Safepoint::kLazyDeopt); |
2568 v8::internal::ParameterCount actual(rax); | 2568 ParameterCount actual(rax); |
2569 __ InvokeFunction(function, actual, CALL_FUNCTION, | 2569 __ InvokeFunction(function, actual, CALL_FUNCTION, |
2570 safepoint_generator, CALL_AS_METHOD); | 2570 safepoint_generator, CALL_AS_METHOD); |
2571 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2571 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2572 } | 2572 } |
2573 | 2573 |
2574 | 2574 |
2575 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 2575 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
2576 LOperand* argument = instr->InputAt(0); | 2576 LOperand* argument = instr->InputAt(0); |
2577 EmitPushTaggedOperand(argument); | 2577 EmitPushTaggedOperand(argument); |
2578 } | 2578 } |
(...skipping 29 matching lines...) Expand all Loading... |
2608 Register global = ToRegister(instr->global()); | 2608 Register global = ToRegister(instr->global()); |
2609 Register result = ToRegister(instr->result()); | 2609 Register result = ToRegister(instr->result()); |
2610 __ movq(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); | 2610 __ movq(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); |
2611 } | 2611 } |
2612 | 2612 |
2613 | 2613 |
2614 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 2614 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
2615 int arity, | 2615 int arity, |
2616 LInstruction* instr, | 2616 LInstruction* instr, |
2617 CallKind call_kind) { | 2617 CallKind call_kind) { |
2618 // Change context if needed. | 2618 bool can_invoke_directly = !function->NeedsArgumentsAdaption() || |
2619 bool change_context = | 2619 function->shared()->formal_parameter_count() == arity; |
2620 (info()->closure()->context() != function->context()) || | |
2621 scope()->contains_with() || | |
2622 (scope()->num_heap_slots() > 0); | |
2623 if (change_context) { | |
2624 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | |
2625 } | |
2626 | |
2627 // Set rax to arguments count if adaption is not needed. Assumes that rax | |
2628 // is available to write to at this point. | |
2629 if (!function->NeedsArgumentsAdaption()) { | |
2630 __ Set(rax, arity); | |
2631 } | |
2632 | 2620 |
2633 LPointerMap* pointers = instr->pointer_map(); | 2621 LPointerMap* pointers = instr->pointer_map(); |
2634 RecordPosition(pointers->position()); | 2622 RecordPosition(pointers->position()); |
2635 | 2623 |
2636 // Invoke function. | 2624 if (can_invoke_directly) { |
2637 __ SetCallKind(rcx, call_kind); | 2625 __ LoadHeapObject(rdi, function); |
2638 if (*function == *info()->closure()) { | 2626 |
2639 __ CallSelf(); | 2627 // Change context if needed. |
| 2628 bool change_context = |
| 2629 (info()->closure()->context() != function->context()) || |
| 2630 scope()->contains_with() || |
| 2631 (scope()->num_heap_slots() > 0); |
| 2632 if (change_context) { |
| 2633 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
| 2634 } |
| 2635 |
| 2636 // Set rax to arguments count if adaption is not needed. Assumes that rax |
| 2637 // is available to write to at this point. |
| 2638 if (!function->NeedsArgumentsAdaption()) { |
| 2639 __ Set(rax, arity); |
| 2640 } |
| 2641 |
| 2642 // Invoke function. |
| 2643 __ SetCallKind(rcx, call_kind); |
| 2644 if (*function == *info()->closure()) { |
| 2645 __ CallSelf(); |
| 2646 } else { |
| 2647 __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
| 2648 } |
| 2649 |
| 2650 // Set up deoptimization. |
| 2651 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); |
2640 } else { | 2652 } else { |
2641 __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 2653 // We need to adapt arguments. |
| 2654 SafepointGenerator generator( |
| 2655 this, pointers, Safepoint::kLazyDeopt); |
| 2656 ParameterCount count(arity); |
| 2657 __ InvokeFunction(function, count, CALL_FUNCTION, generator, call_kind); |
2642 } | 2658 } |
2643 | 2659 |
2644 // Set up deoptimization. | |
2645 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); | |
2646 | |
2647 // Restore context. | 2660 // Restore context. |
2648 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2661 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2649 } | 2662 } |
2650 | 2663 |
2651 | 2664 |
2652 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2665 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
2653 ASSERT(ToRegister(instr->result()).is(rax)); | 2666 ASSERT(ToRegister(instr->result()).is(rax)); |
2654 __ LoadHeapObject(rdi, instr->function()); | |
2655 CallKnownFunction(instr->function(), | 2667 CallKnownFunction(instr->function(), |
2656 instr->arity(), | 2668 instr->arity(), |
2657 instr, | 2669 instr, |
2658 CALL_AS_METHOD); | 2670 CALL_AS_METHOD); |
2659 } | 2671 } |
2660 | 2672 |
2661 | 2673 |
2662 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2674 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
2663 Register input_reg = ToRegister(instr->InputAt(0)); | 2675 Register input_reg = ToRegister(instr->InputAt(0)); |
2664 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), | 2676 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3087 Handle<Code> ic = | 3099 Handle<Code> ic = |
3088 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); | 3100 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
3089 __ Move(rcx, instr->name()); | 3101 __ Move(rcx, instr->name()); |
3090 CallCode(ic, mode, instr); | 3102 CallCode(ic, mode, instr); |
3091 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 3103 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
3092 } | 3104 } |
3093 | 3105 |
3094 | 3106 |
3095 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3107 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
3096 ASSERT(ToRegister(instr->result()).is(rax)); | 3108 ASSERT(ToRegister(instr->result()).is(rax)); |
3097 __ LoadHeapObject(rdi, instr->target()); | |
3098 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); | 3109 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); |
3099 } | 3110 } |
3100 | 3111 |
3101 | 3112 |
3102 void LCodeGen::DoCallNew(LCallNew* instr) { | 3113 void LCodeGen::DoCallNew(LCallNew* instr) { |
3103 ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); | 3114 ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); |
3104 ASSERT(ToRegister(instr->result()).is(rax)); | 3115 ASSERT(ToRegister(instr->result()).is(rax)); |
3105 | 3116 |
3106 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); | 3117 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); |
3107 __ Set(rax, instr->arity()); | 3118 __ Set(rax, instr->arity()); |
(...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4385 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); | 4396 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); |
4386 ASSERT(osr_pc_offset_ == -1); | 4397 ASSERT(osr_pc_offset_ == -1); |
4387 osr_pc_offset_ = masm()->pc_offset(); | 4398 osr_pc_offset_ = masm()->pc_offset(); |
4388 } | 4399 } |
4389 | 4400 |
4390 #undef __ | 4401 #undef __ |
4391 | 4402 |
4392 } } // namespace v8::internal | 4403 } } // namespace v8::internal |
4393 | 4404 |
4394 #endif // V8_TARGET_ARCH_X64 | 4405 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |