OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 __ mov(ecx, FieldOperand(ebx, JSGeneratorObject::kContinuationOffset)); | 513 __ mov(ecx, FieldOperand(ebx, JSGeneratorObject::kContinuationOffset)); |
514 __ SmiUntag(ecx); | 514 __ SmiUntag(ecx); |
515 __ lea(edx, FieldOperand(edx, ecx, times_1, Code::kHeaderSize)); | 515 __ lea(edx, FieldOperand(edx, ecx, times_1, Code::kHeaderSize)); |
516 __ mov(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset), | 516 __ mov(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset), |
517 Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))); | 517 Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))); |
518 __ mov(eax, ebx); // Continuation expects generator object in eax. | 518 __ mov(eax, ebx); // Continuation expects generator object in eax. |
519 __ jmp(edx); | 519 __ jmp(edx); |
520 } | 520 } |
521 } | 521 } |
522 | 522 |
| 523 static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1, |
| 524 Register scratch2) { |
| 525 Register args_count = scratch1; |
| 526 Register return_pc = scratch2; |
| 527 |
| 528 // Get the arguments + reciever count. |
| 529 __ mov(args_count, |
| 530 Operand(ebp, InterpreterFrameConstants::kBytecodeArrayFromFp)); |
| 531 __ mov(args_count, |
| 532 FieldOperand(args_count, BytecodeArray::kParameterSizeOffset)); |
| 533 |
| 534 // Leave the frame (also dropping the register file). |
| 535 __ leave(); |
| 536 |
| 537 // Drop receiver + arguments. |
| 538 __ pop(return_pc); |
| 539 __ add(esp, args_count); |
| 540 __ push(return_pc); |
| 541 } |
| 542 |
523 // Generate code for entering a JS function with the interpreter. | 543 // Generate code for entering a JS function with the interpreter. |
524 // On entry to the function the receiver and arguments have been pushed on the | 544 // On entry to the function the receiver and arguments have been pushed on the |
525 // stack left to right. The actual argument count matches the formal parameter | 545 // stack left to right. The actual argument count matches the formal parameter |
526 // count expected by the function. | 546 // count expected by the function. |
527 // | 547 // |
528 // The live registers are: | 548 // The live registers are: |
529 // o edi: the JS function object being called | 549 // o edi: the JS function object being called |
530 // o edx: the new target | 550 // o edx: the new target |
531 // o esi: our context | 551 // o esi: our context |
532 // o ebp: the caller's frame pointer | 552 // o ebp: the caller's frame pointer |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 | 636 |
617 // Dispatch to the first bytecode handler for the function. | 637 // Dispatch to the first bytecode handler for the function. |
618 __ movzx_b(ebx, Operand(kInterpreterBytecodeArrayRegister, | 638 __ movzx_b(ebx, Operand(kInterpreterBytecodeArrayRegister, |
619 kInterpreterBytecodeOffsetRegister, times_1, 0)); | 639 kInterpreterBytecodeOffsetRegister, times_1, 0)); |
620 __ mov(ebx, Operand(kInterpreterDispatchTableRegister, ebx, | 640 __ mov(ebx, Operand(kInterpreterDispatchTableRegister, ebx, |
621 times_pointer_size, 0)); | 641 times_pointer_size, 0)); |
622 __ call(ebx); | 642 __ call(ebx); |
623 masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); | 643 masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); |
624 | 644 |
625 // The return value is in eax. | 645 // The return value is in eax. |
626 | 646 LeaveInterpreterFrame(masm, ebx, ecx); |
627 // Get the arguments + reciever count. | |
628 __ mov(ebx, Operand(ebp, InterpreterFrameConstants::kBytecodeArrayFromFp)); | |
629 __ mov(ebx, FieldOperand(ebx, BytecodeArray::kParameterSizeOffset)); | |
630 | |
631 // Leave the frame (also dropping the register file). | |
632 __ leave(); | |
633 | |
634 // Drop receiver + arguments and return. | |
635 __ pop(ecx); | |
636 __ add(esp, ebx); | |
637 __ push(ecx); | |
638 __ ret(0); | 647 __ ret(0); |
639 | 648 |
640 // Load debug copy of the bytecode array. | 649 // Load debug copy of the bytecode array. |
641 __ bind(&load_debug_bytecode_array); | 650 __ bind(&load_debug_bytecode_array); |
642 Register debug_info = kInterpreterBytecodeArrayRegister; | 651 Register debug_info = kInterpreterBytecodeArrayRegister; |
643 __ mov(debug_info, FieldOperand(eax, SharedFunctionInfo::kDebugInfoOffset)); | 652 __ mov(debug_info, FieldOperand(eax, SharedFunctionInfo::kDebugInfoOffset)); |
644 __ mov(kInterpreterBytecodeArrayRegister, | 653 __ mov(kInterpreterBytecodeArrayRegister, |
645 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex)); | 654 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex)); |
646 __ jmp(&bytecode_array_loaded); | 655 __ jmp(&bytecode_array_loaded); |
647 | 656 |
648 // If the bytecode array is no longer present, then the underlying function | 657 // If the bytecode array is no longer present, then the underlying function |
649 // has been switched to a different kind of code and we heal the closure by | 658 // has been switched to a different kind of code and we heal the closure by |
650 // switching the code entry field over to the new code object as well. | 659 // switching the code entry field over to the new code object as well. |
651 __ bind(&bytecode_array_not_present); | 660 __ bind(&bytecode_array_not_present); |
652 __ pop(edx); // Callee's new target. | 661 __ pop(edx); // Callee's new target. |
653 __ pop(edi); // Callee's JS function. | 662 __ pop(edi); // Callee's JS function. |
654 __ pop(esi); // Callee's context. | 663 __ pop(esi); // Callee's context. |
655 __ leave(); // Leave the frame so we can tail call. | 664 __ leave(); // Leave the frame so we can tail call. |
656 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 665 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
657 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kCodeOffset)); | 666 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kCodeOffset)); |
658 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); | 667 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
659 __ mov(FieldOperand(edi, JSFunction::kCodeEntryOffset), ecx); | 668 __ mov(FieldOperand(edi, JSFunction::kCodeEntryOffset), ecx); |
660 __ RecordWriteCodeEntryField(edi, ecx, ebx); | 669 __ RecordWriteCodeEntryField(edi, ecx, ebx); |
661 __ jmp(ecx); | 670 __ jmp(ecx); |
662 } | 671 } |
663 | 672 |
| 673 void Builtins::Generate_InterpreterMarkBaselineOnReturn(MacroAssembler* masm) { |
| 674 // Save the function and context for call to CompileBaseline. |
| 675 __ mov(edi, Operand(ebp, StandardFrameConstants::kFunctionOffset)); |
| 676 __ mov(kContextRegister, |
| 677 Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 678 |
| 679 // Leave the frame before recompiling for baseline so that we don't count as |
| 680 // an activation on the stack. |
| 681 LeaveInterpreterFrame(masm, ebx, ecx); |
| 682 |
| 683 { |
| 684 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
| 685 // Push return value. |
| 686 __ push(eax); |
| 687 |
| 688 // Push function as argument and compile for baseline. |
| 689 __ push(edi); |
| 690 __ CallRuntime(Runtime::kCompileBaseline); |
| 691 |
| 692 // Restore return value. |
| 693 __ pop(eax); |
| 694 } |
| 695 __ ret(0); |
| 696 } |
| 697 |
664 static void Generate_InterpreterPushArgs(MacroAssembler* masm, | 698 static void Generate_InterpreterPushArgs(MacroAssembler* masm, |
665 Register array_limit) { | 699 Register array_limit) { |
666 // ----------- S t a t e ------------- | 700 // ----------- S t a t e ------------- |
667 // -- ebx : Pointer to the last argument in the args array. | 701 // -- ebx : Pointer to the last argument in the args array. |
668 // -- array_limit : Pointer to one before the first argument in the | 702 // -- array_limit : Pointer to one before the first argument in the |
669 // args array. | 703 // args array. |
670 // ----------------------------------- | 704 // ----------------------------------- |
671 Label loop_header, loop_check; | 705 Label loop_header, loop_check; |
672 __ jmp(&loop_check); | 706 __ jmp(&loop_check); |
673 __ bind(&loop_header); | 707 __ bind(&loop_header); |
(...skipping 2152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2826 // And "return" to the OSR entry point of the function. | 2860 // And "return" to the OSR entry point of the function. |
2827 __ ret(0); | 2861 __ ret(0); |
2828 } | 2862 } |
2829 | 2863 |
2830 | 2864 |
2831 #undef __ | 2865 #undef __ |
2832 } // namespace internal | 2866 } // namespace internal |
2833 } // namespace v8 | 2867 } // namespace v8 |
2834 | 2868 |
2835 #endif // V8_TARGET_ARCH_IA32 | 2869 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |