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