OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 | 42 |
43 VirtualFrame::VirtualFrame(CodeGenerator* cgen) { | 43 VirtualFrame::VirtualFrame(CodeGenerator* cgen) { |
44 ASSERT(cgen->scope() != NULL); | 44 ASSERT(cgen->scope() != NULL); |
45 | 45 |
46 masm_ = cgen->masm(); | 46 masm_ = cgen->masm(); |
47 frame_local_count_ = cgen->scope()->num_stack_slots(); | 47 frame_local_count_ = cgen->scope()->num_stack_slots(); |
48 parameter_count_ = cgen->scope()->num_parameters(); | 48 parameter_count_ = cgen->scope()->num_parameters(); |
49 } | 49 } |
50 | 50 |
51 | 51 |
| 52 void VirtualFrame::Enter() { |
| 53 Comment cmnt(masm_, "[ Enter JS frame"); |
| 54 __ push(ebp); |
| 55 __ mov(ebp, Operand(esp)); |
| 56 |
| 57 // Store the context and the function in the frame. |
| 58 __ push(esi); |
| 59 __ push(edi); |
| 60 |
| 61 // Clear the function slot when generating debug code. |
| 62 if (FLAG_debug_code) { |
| 63 __ Set(edi, Immediate(reinterpret_cast<int>(kZapValue))); |
| 64 } |
| 65 } |
| 66 |
| 67 |
| 68 void VirtualFrame::Exit() { |
| 69 Comment cmnt(masm_, "[ Exit JS frame"); |
| 70 // Record the location of the JS exit code for patching when setting |
| 71 // break point. |
| 72 __ RecordJSReturn(); |
| 73 |
| 74 // Avoid using the leave instruction here, because it is too |
| 75 // short. We need the return sequence to be a least the size of a |
| 76 // call instruction to support patching the exit code in the |
| 77 // debugger. See VisitReturnStatement for the full return sequence. |
| 78 __ mov(esp, Operand(ebp)); |
| 79 __ pop(ebp); |
| 80 } |
| 81 |
| 82 |
52 void VirtualFrame::AllocateLocals() { | 83 void VirtualFrame::AllocateLocals() { |
53 if (frame_local_count_ > 0) { | 84 if (frame_local_count_ > 0) { |
54 Comment cmnt(masm_, "[ Allocate space for locals"); | 85 Comment cmnt(masm_, "[ Allocate space for locals"); |
55 __ Set(eax, Immediate(Factory::undefined_value())); | 86 __ Set(eax, Immediate(Factory::undefined_value())); |
56 for (int i = 0; i < frame_local_count_; i++) { | 87 for (int i = 0; i < frame_local_count_; i++) { |
57 __ push(eax); | 88 __ push(eax); |
58 } | 89 } |
59 } | 90 } |
60 } | 91 } |
61 | 92 |
(...skipping 3602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3664 void CodeGenerator::RecordStatementPosition(Node* node) { | 3695 void CodeGenerator::RecordStatementPosition(Node* node) { |
3665 if (FLAG_debug_info) { | 3696 if (FLAG_debug_info) { |
3666 int pos = node->statement_pos(); | 3697 int pos = node->statement_pos(); |
3667 if (pos != RelocInfo::kNoPosition) { | 3698 if (pos != RelocInfo::kNoPosition) { |
3668 __ RecordStatementPosition(pos); | 3699 __ RecordStatementPosition(pos); |
3669 } | 3700 } |
3670 } | 3701 } |
3671 } | 3702 } |
3672 | 3703 |
3673 | 3704 |
3674 void VirtualFrame::Enter() { | |
3675 Comment cmnt(masm_, "[ Enter JS frame"); | |
3676 __ push(ebp); | |
3677 __ mov(ebp, Operand(esp)); | |
3678 | |
3679 // Store the context and the function in the frame. | |
3680 __ push(esi); | |
3681 __ push(edi); | |
3682 | |
3683 // Clear the function slot when generating debug code. | |
3684 if (FLAG_debug_code) { | |
3685 __ Set(edi, Immediate(reinterpret_cast<int>(kZapValue))); | |
3686 } | |
3687 } | |
3688 | |
3689 | |
3690 void VirtualFrame::Exit() { | |
3691 Comment cmnt(masm_, "[ Exit JS frame"); | |
3692 // Record the location of the JS exit code for patching when setting | |
3693 // break point. | |
3694 __ RecordJSReturn(); | |
3695 | |
3696 // Avoid using the leave instruction here, because it is too | |
3697 // short. We need the return sequence to be a least the size of a | |
3698 // call instruction to support patching the exit code in the | |
3699 // debugger. See VisitReturnStatement for the full return sequence. | |
3700 __ mov(esp, Operand(ebp)); | |
3701 __ pop(ebp); | |
3702 } | |
3703 | |
3704 | |
3705 #undef __ | 3705 #undef __ |
3706 #define __ masm-> | 3706 #define __ masm-> |
3707 | 3707 |
3708 Handle<String> Reference::GetName() { | 3708 Handle<String> Reference::GetName() { |
3709 ASSERT(type_ == NAMED); | 3709 ASSERT(type_ == NAMED); |
3710 Property* property = expression_->AsProperty(); | 3710 Property* property = expression_->AsProperty(); |
3711 if (property == NULL) { | 3711 if (property == NULL) { |
3712 // Global variable reference treated as a named property reference. | 3712 // Global variable reference treated as a named property reference. |
3713 VariableProxy* proxy = expression_->AsVariableProxy(); | 3713 VariableProxy* proxy = expression_->AsVariableProxy(); |
3714 ASSERT(proxy->AsVariable() != NULL); | 3714 ASSERT(proxy->AsVariable() != NULL); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3845 } | 3845 } |
3846 | 3846 |
3847 // We must execute the store. Storing a variable must keep the | 3847 // We must execute the store. Storing a variable must keep the |
3848 // (new) value on the stack. This is necessary for compiling | 3848 // (new) value on the stack. This is necessary for compiling |
3849 // assignment expressions. | 3849 // assignment expressions. |
3850 // | 3850 // |
3851 // Note: We will reach here even with slot->var()->mode() == | 3851 // Note: We will reach here even with slot->var()->mode() == |
3852 // Variable::CONST because of const declarations which will | 3852 // Variable::CONST because of const declarations which will |
3853 // initialize consts to 'the hole' value and by doing so, end up | 3853 // initialize consts to 'the hole' value and by doing so, end up |
3854 // calling this code. | 3854 // calling this code. |
3855 __ pop(eax); | 3855 frame->Pop(eax); |
3856 __ mov(cgen_->SlotOperand(slot, ecx), eax); | 3856 __ mov(cgen_->SlotOperand(slot, ecx), eax); |
3857 frame->Push(eax); // RecordWrite may destroy the value in eax. | 3857 frame->Push(eax); // RecordWrite may destroy the value in eax. |
3858 if (slot->type() == Slot::CONTEXT) { | 3858 if (slot->type() == Slot::CONTEXT) { |
3859 // ecx is loaded with context when calling SlotOperand above. | 3859 // ecx is loaded with context when calling SlotOperand above. |
3860 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; | 3860 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; |
3861 __ RecordWrite(ecx, offset, eax, ebx); | 3861 __ RecordWrite(ecx, offset, eax, ebx); |
3862 } | 3862 } |
3863 // If we definitely did not jump over the assignment, we do not need | 3863 // If we definitely did not jump over the assignment, we do not need |
3864 // to bind the exit label. Doing so can defeat peephole | 3864 // to bind the exit label. Doing so can defeat peephole |
3865 // optimization. | 3865 // optimization. |
3866 if (init_state == CONST_INIT) __ bind(&exit); | 3866 if (init_state == CONST_INIT) __ bind(&exit); |
3867 } | 3867 } |
3868 break; | 3868 break; |
3869 } | 3869 } |
3870 | 3870 |
3871 case NAMED: { | 3871 case NAMED: { |
3872 Comment cmnt(masm, "[ Store to named Property"); | 3872 Comment cmnt(masm, "[ Store to named Property"); |
3873 // Call the appropriate IC code. | 3873 // Call the appropriate IC code. |
3874 Handle<String> name(GetName()); | 3874 Handle<String> name(GetName()); |
3875 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 3875 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
3876 // TODO(1222589): Make the IC grab the values from the stack. | 3876 // TODO(1222589): Make the IC grab the values from the stack. |
3877 __ pop(eax); | 3877 frame->Pop(eax); |
3878 // Setup the name register. | 3878 // Setup the name register. |
3879 __ mov(ecx, name); | 3879 __ mov(ecx, name); |
3880 __ call(ic, RelocInfo::CODE_TARGET); | 3880 __ call(ic, RelocInfo::CODE_TARGET); |
3881 frame->Push(eax); // IC call leaves result in eax, push it out | 3881 frame->Push(eax); // IC call leaves result in eax, push it out |
3882 break; | 3882 break; |
3883 } | 3883 } |
3884 | 3884 |
3885 case KEYED: { | 3885 case KEYED: { |
3886 Comment cmnt(masm, "[ Store to keyed Property"); | 3886 Comment cmnt(masm, "[ Store to keyed Property"); |
3887 Property* property = expression_->AsProperty(); | 3887 Property* property = expression_->AsProperty(); |
3888 ASSERT(property != NULL); | 3888 ASSERT(property != NULL); |
3889 __ RecordPosition(property->position()); | 3889 __ RecordPosition(property->position()); |
3890 // Call IC code. | 3890 // Call IC code. |
3891 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 3891 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
3892 // TODO(1222589): Make the IC grab the values from the stack. | 3892 // TODO(1222589): Make the IC grab the values from the stack. |
3893 __ pop(eax); | 3893 frame->Pop(eax); |
3894 __ call(ic, RelocInfo::CODE_TARGET); | 3894 __ call(ic, RelocInfo::CODE_TARGET); |
3895 frame->Push(eax); // IC call leaves result in eax, push it out | 3895 frame->Push(eax); // IC call leaves result in eax, push it out |
3896 break; | 3896 break; |
3897 } | 3897 } |
3898 | 3898 |
3899 default: | 3899 default: |
3900 UNREACHABLE(); | 3900 UNREACHABLE(); |
3901 } | 3901 } |
3902 } | 3902 } |
3903 | 3903 |
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5111 | 5111 |
5112 // Slow-case: Go through the JavaScript implementation. | 5112 // Slow-case: Go through the JavaScript implementation. |
5113 __ bind(&slow); | 5113 __ bind(&slow); |
5114 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 5114 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
5115 } | 5115 } |
5116 | 5116 |
5117 | 5117 |
5118 #undef __ | 5118 #undef __ |
5119 | 5119 |
5120 } } // namespace v8::internal | 5120 } } // namespace v8::internal |
OLD | NEW |