Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 566008: Incorporate the arguments to the code generator constructors and their (Closed)
Patch Set: Incorporate the arguments to the code generator constructors and their... Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ia32/fast-codegen-ia32.cc ('k') | src/x64/codegen-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 // formal parameter count expected by the function. 44 // formal parameter count expected by the function.
45 // 45 //
46 // The live registers are: 46 // The live registers are:
47 // o edi: the JS function object being called (ie, ourselves) 47 // o edi: the JS function object being called (ie, ourselves)
48 // o esi: our context 48 // o esi: our context
49 // o ebp: our caller's frame pointer 49 // o ebp: our caller's frame pointer
50 // o esp: stack pointer (pointing to return address) 50 // o esp: stack pointer (pointing to return address)
51 // 51 //
52 // The function builds a JS frame. Please see JavaScriptFrameConstants in 52 // The function builds a JS frame. Please see JavaScriptFrameConstants in
53 // frames-ia32.h for its layout. 53 // frames-ia32.h for its layout.
54 void FullCodeGenerator::Generate(FunctionLiteral* fun, Mode mode) { 54 void FullCodeGenerator::Generate(CompilationInfo* info, Mode mode) {
55 function_ = fun; 55 ASSERT(info_ == NULL);
56 SetFunctionPosition(fun); 56 info_ = info;
57 SetFunctionPosition(function());
57 58
58 if (mode == PRIMARY) { 59 if (mode == PRIMARY) {
59 __ push(ebp); // Caller's frame pointer. 60 __ push(ebp); // Caller's frame pointer.
60 __ mov(ebp, esp); 61 __ mov(ebp, esp);
61 __ push(esi); // Callee's context. 62 __ push(esi); // Callee's context.
62 __ push(edi); // Callee's JS Function. 63 __ push(edi); // Callee's JS Function.
63 64
64 { Comment cmnt(masm_, "[ Allocate locals"); 65 { Comment cmnt(masm_, "[ Allocate locals");
65 int locals_count = fun->scope()->num_stack_slots(); 66 int locals_count = scope()->num_stack_slots();
66 if (locals_count == 1) { 67 if (locals_count == 1) {
67 __ push(Immediate(Factory::undefined_value())); 68 __ push(Immediate(Factory::undefined_value()));
68 } else if (locals_count > 1) { 69 } else if (locals_count > 1) {
69 __ mov(eax, Immediate(Factory::undefined_value())); 70 __ mov(eax, Immediate(Factory::undefined_value()));
70 for (int i = 0; i < locals_count; i++) { 71 for (int i = 0; i < locals_count; i++) {
71 __ push(eax); 72 __ push(eax);
72 } 73 }
73 } 74 }
74 } 75 }
75 76
76 bool function_in_register = true; 77 bool function_in_register = true;
77 78
78 // Possibly allocate a local context. 79 // Possibly allocate a local context.
79 if (fun->scope()->num_heap_slots() > 0) { 80 if (scope()->num_heap_slots() > 0) {
80 Comment cmnt(masm_, "[ Allocate local context"); 81 Comment cmnt(masm_, "[ Allocate local context");
81 // Argument to NewContext is the function, which is still in edi. 82 // Argument to NewContext is the function, which is still in edi.
82 __ push(edi); 83 __ push(edi);
83 __ CallRuntime(Runtime::kNewContext, 1); 84 __ CallRuntime(Runtime::kNewContext, 1);
84 function_in_register = false; 85 function_in_register = false;
85 // Context is returned in both eax and esi. It replaces the context 86 // Context is returned in both eax and esi. It replaces the context
86 // passed to us. It's saved in the stack and kept live in esi. 87 // passed to us. It's saved in the stack and kept live in esi.
87 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); 88 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi);
88 89
89 // Copy parameters into context if necessary. 90 // Copy parameters into context if necessary.
90 int num_parameters = fun->scope()->num_parameters(); 91 int num_parameters = scope()->num_parameters();
91 for (int i = 0; i < num_parameters; i++) { 92 for (int i = 0; i < num_parameters; i++) {
92 Slot* slot = fun->scope()->parameter(i)->slot(); 93 Slot* slot = scope()->parameter(i)->slot();
93 if (slot != NULL && slot->type() == Slot::CONTEXT) { 94 if (slot != NULL && slot->type() == Slot::CONTEXT) {
94 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 95 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
95 (num_parameters - 1 - i) * kPointerSize; 96 (num_parameters - 1 - i) * kPointerSize;
96 // Load parameter from stack. 97 // Load parameter from stack.
97 __ mov(eax, Operand(ebp, parameter_offset)); 98 __ mov(eax, Operand(ebp, parameter_offset));
98 // Store it in the context. 99 // Store it in the context.
99 int context_offset = Context::SlotOffset(slot->index()); 100 int context_offset = Context::SlotOffset(slot->index());
100 __ mov(Operand(esi, context_offset), eax); 101 __ mov(Operand(esi, context_offset), eax);
101 // Update the write barrier. This clobbers all involved 102 // Update the write barrier. This clobbers all involved
102 // registers, so we have use a third register to avoid 103 // registers, so we have use a third register to avoid
103 // clobbering esi. 104 // clobbering esi.
104 __ mov(ecx, esi); 105 __ mov(ecx, esi);
105 __ RecordWrite(ecx, context_offset, eax, ebx); 106 __ RecordWrite(ecx, context_offset, eax, ebx);
106 } 107 }
107 } 108 }
108 } 109 }
109 110
110 Variable* arguments = fun->scope()->arguments()->AsVariable(); 111 Variable* arguments = scope()->arguments()->AsVariable();
111 if (arguments != NULL) { 112 if (arguments != NULL) {
112 // Function uses arguments object. 113 // Function uses arguments object.
113 Comment cmnt(masm_, "[ Allocate arguments object"); 114 Comment cmnt(masm_, "[ Allocate arguments object");
114 if (function_in_register) { 115 if (function_in_register) {
115 __ push(edi); 116 __ push(edi);
116 } else { 117 } else {
117 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 118 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
118 } 119 }
119 // Receiver is just before the parameters on the caller's stack. 120 // Receiver is just before the parameters on the caller's stack.
120 __ lea(edx, Operand(ebp, StandardFrameConstants::kCallerSPOffset + 121 int offset = scope()->num_parameters() * kPointerSize;
121 fun->num_parameters() * kPointerSize)); 122 __ lea(edx,
123 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset));
122 __ push(edx); 124 __ push(edx);
123 __ push(Immediate(Smi::FromInt(fun->num_parameters()))); 125 __ push(Immediate(Smi::FromInt(scope()->num_parameters())));
124 // Arguments to ArgumentsAccessStub: 126 // Arguments to ArgumentsAccessStub:
125 // function, receiver address, parameter count. 127 // function, receiver address, parameter count.
126 // The stub will rewrite receiver and parameter count if the previous 128 // The stub will rewrite receiver and parameter count if the previous
127 // stack frame was an arguments adapter frame. 129 // stack frame was an arguments adapter frame.
128 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); 130 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
129 __ CallStub(&stub); 131 __ CallStub(&stub);
130 __ mov(ecx, eax); // Duplicate result. 132 __ mov(ecx, eax); // Duplicate result.
131 Move(arguments->slot(), eax, ebx, edx); 133 Move(arguments->slot(), eax, ebx, edx);
132 Slot* dot_arguments_slot = 134 Slot* dot_arguments_slot =
133 fun->scope()->arguments_shadow()->AsVariable()->slot(); 135 scope()->arguments_shadow()->AsVariable()->slot();
134 Move(dot_arguments_slot, ecx, ebx, edx); 136 Move(dot_arguments_slot, ecx, ebx, edx);
135 } 137 }
136 } 138 }
137 139
138 { Comment cmnt(masm_, "[ Declarations"); 140 { Comment cmnt(masm_, "[ Declarations");
139 VisitDeclarations(fun->scope()->declarations()); 141 VisitDeclarations(scope()->declarations());
140 } 142 }
141 143
142 { Comment cmnt(masm_, "[ Stack check"); 144 { Comment cmnt(masm_, "[ Stack check");
143 Label ok; 145 Label ok;
144 ExternalReference stack_limit = 146 ExternalReference stack_limit =
145 ExternalReference::address_of_stack_limit(); 147 ExternalReference::address_of_stack_limit();
146 __ cmp(esp, Operand::StaticVariable(stack_limit)); 148 __ cmp(esp, Operand::StaticVariable(stack_limit));
147 __ j(above_equal, &ok, taken); 149 __ j(above_equal, &ok, taken);
148 StackCheckStub stub; 150 StackCheckStub stub;
149 __ CallStub(&stub); 151 __ CallStub(&stub);
150 __ bind(&ok); 152 __ bind(&ok);
151 } 153 }
152 154
153 if (FLAG_trace) { 155 if (FLAG_trace) {
154 __ CallRuntime(Runtime::kTraceEnter, 0); 156 __ CallRuntime(Runtime::kTraceEnter, 0);
155 } 157 }
156 158
157 { Comment cmnt(masm_, "[ Body"); 159 { Comment cmnt(masm_, "[ Body");
158 ASSERT(loop_depth() == 0); 160 ASSERT(loop_depth() == 0);
159 VisitStatements(fun->body()); 161 VisitStatements(function()->body());
160 ASSERT(loop_depth() == 0); 162 ASSERT(loop_depth() == 0);
161 } 163 }
162 164
163 { Comment cmnt(masm_, "[ return <undefined>;"); 165 { Comment cmnt(masm_, "[ return <undefined>;");
164 // Emit a 'return undefined' in case control fell off the end of the body. 166 // Emit a 'return undefined' in case control fell off the end of the body.
165 __ mov(eax, Factory::undefined_value()); 167 __ mov(eax, Factory::undefined_value());
166 EmitReturnSequence(function_->end_position()); 168 EmitReturnSequence(function()->end_position());
167 } 169 }
168 } 170 }
169 171
170 172
171 void FullCodeGenerator::EmitReturnSequence(int position) { 173 void FullCodeGenerator::EmitReturnSequence(int position) {
172 Comment cmnt(masm_, "[ Return sequence"); 174 Comment cmnt(masm_, "[ Return sequence");
173 if (return_label_.is_bound()) { 175 if (return_label_.is_bound()) {
174 __ jmp(&return_label_); 176 __ jmp(&return_label_);
175 } else { 177 } else {
176 // Common return label 178 // Common return label
177 __ bind(&return_label_); 179 __ bind(&return_label_);
178 if (FLAG_trace) { 180 if (FLAG_trace) {
179 __ push(eax); 181 __ push(eax);
180 __ CallRuntime(Runtime::kTraceExit, 1); 182 __ CallRuntime(Runtime::kTraceExit, 1);
181 } 183 }
182 #ifdef DEBUG 184 #ifdef DEBUG
183 // Add a label for checking the size of the code used for returning. 185 // Add a label for checking the size of the code used for returning.
184 Label check_exit_codesize; 186 Label check_exit_codesize;
185 masm_->bind(&check_exit_codesize); 187 masm_->bind(&check_exit_codesize);
186 #endif 188 #endif
187 CodeGenerator::RecordPositions(masm_, position); 189 CodeGenerator::RecordPositions(masm_, position);
188 __ RecordJSReturn(); 190 __ RecordJSReturn();
189 // Do not use the leave instruction here because it is too short to 191 // Do not use the leave instruction here because it is too short to
190 // patch with the code required by the debugger. 192 // patch with the code required by the debugger.
191 __ mov(esp, ebp); 193 __ mov(esp, ebp);
192 __ pop(ebp); 194 __ pop(ebp);
193 __ ret((function_->scope()->num_parameters() + 1) * kPointerSize); 195 __ ret((scope()->num_parameters() + 1) * kPointerSize);
194 #ifdef ENABLE_DEBUGGER_SUPPORT 196 #ifdef ENABLE_DEBUGGER_SUPPORT
195 // Check that the size of the code used for returning matches what is 197 // Check that the size of the code used for returning matches what is
196 // expected by the debugger. 198 // expected by the debugger.
197 ASSERT_EQ(Assembler::kJSReturnSequenceLength, 199 ASSERT_EQ(Assembler::kJSReturnSequenceLength,
198 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); 200 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
199 #endif 201 #endif
200 } 202 }
201 } 203 }
202 204
203 205
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 } 622 }
621 623
622 624
623 MemOperand FullCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) { 625 MemOperand FullCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
624 switch (slot->type()) { 626 switch (slot->type()) {
625 case Slot::PARAMETER: 627 case Slot::PARAMETER:
626 case Slot::LOCAL: 628 case Slot::LOCAL:
627 return Operand(ebp, SlotOffset(slot)); 629 return Operand(ebp, SlotOffset(slot));
628 case Slot::CONTEXT: { 630 case Slot::CONTEXT: {
629 int context_chain_length = 631 int context_chain_length =
630 function_->scope()->ContextChainLength(slot->var()->scope()); 632 scope()->ContextChainLength(slot->var()->scope());
631 __ LoadContext(scratch, context_chain_length); 633 __ LoadContext(scratch, context_chain_length);
632 return CodeGenerator::ContextOperand(scratch, slot->index()); 634 return CodeGenerator::ContextOperand(scratch, slot->index());
633 } 635 }
634 case Slot::LOOKUP: 636 case Slot::LOOKUP:
635 UNREACHABLE(); 637 UNREACHABLE();
636 } 638 }
637 UNREACHABLE(); 639 UNREACHABLE();
638 return Operand(eax, 0); 640 return Operand(eax, 0);
639 } 641 }
640 642
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 VisitForValue(decl->fun(), kAccumulator); 681 VisitForValue(decl->fun(), kAccumulator);
680 __ mov(Operand(ebp, SlotOffset(slot)), result_register()); 682 __ mov(Operand(ebp, SlotOffset(slot)), result_register());
681 } 683 }
682 break; 684 break;
683 685
684 case Slot::CONTEXT: 686 case Slot::CONTEXT:
685 // We bypass the general EmitSlotSearch because we know more about 687 // We bypass the general EmitSlotSearch because we know more about
686 // this specific context. 688 // this specific context.
687 689
688 // The variable in the decl always resides in the current context. 690 // The variable in the decl always resides in the current context.
689 ASSERT_EQ(0, function_->scope()->ContextChainLength(var->scope())); 691 ASSERT_EQ(0, scope()->ContextChainLength(var->scope()));
690 if (FLAG_debug_code) { 692 if (FLAG_debug_code) {
691 // Check if we have the correct context pointer. 693 // Check if we have the correct context pointer.
692 __ mov(ebx, 694 __ mov(ebx,
693 CodeGenerator::ContextOperand(esi, Context::FCONTEXT_INDEX)); 695 CodeGenerator::ContextOperand(esi, Context::FCONTEXT_INDEX));
694 __ cmp(ebx, Operand(esi)); 696 __ cmp(ebx, Operand(esi));
695 __ Check(equal, "Unexpected declaration in current context."); 697 __ Check(equal, "Unexpected declaration in current context.");
696 } 698 }
697 if (decl->mode() == Variable::CONST) { 699 if (decl->mode() == Variable::CONST) {
698 __ mov(eax, Immediate(Factory::the_hole_value())); 700 __ mov(eax, Immediate(Factory::the_hole_value()));
699 __ mov(CodeGenerator::ContextOperand(esi, slot->index()), eax); 701 __ mov(CodeGenerator::ContextOperand(esi, slot->index()), eax);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 __ Drop(2); 759 __ Drop(2);
758 } 760 }
759 } 761 }
760 } 762 }
761 763
762 764
763 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 765 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
764 // Call the runtime to declare the globals. 766 // Call the runtime to declare the globals.
765 __ push(esi); // The context is the first argument. 767 __ push(esi); // The context is the first argument.
766 __ push(Immediate(pairs)); 768 __ push(Immediate(pairs));
767 __ push(Immediate(Smi::FromInt(is_eval_ ? 1 : 0))); 769 __ push(Immediate(Smi::FromInt(is_eval() ? 1 : 0)));
768 __ CallRuntime(Runtime::kDeclareGlobals, 3); 770 __ CallRuntime(Runtime::kDeclareGlobals, 3);
769 // Return value is ignored. 771 // Return value is ignored.
770 } 772 }
771 773
772 774
773 void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 775 void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
774 Comment cmnt(masm_, "[ FunctionLiteral"); 776 Comment cmnt(masm_, "[ FunctionLiteral");
775 777
776 // Build the function boilerplate and instantiate it. 778 // Build the function boilerplate and instantiate it.
777 Handle<JSFunction> boilerplate = 779 Handle<JSFunction> boilerplate =
778 Compiler::BuildBoilerplate(expr, script_, this); 780 Compiler::BuildBoilerplate(expr, script(), this);
779 if (HasStackOverflow()) return; 781 if (HasStackOverflow()) return;
780 782
781 ASSERT(boilerplate->IsBoilerplate()); 783 ASSERT(boilerplate->IsBoilerplate());
782 784
783 // Create a new closure. 785 // Create a new closure.
784 __ push(esi); 786 __ push(esi);
785 __ push(Immediate(boilerplate)); 787 __ push(Immediate(boilerplate));
786 __ CallRuntime(Runtime::kNewClosure, 2); 788 __ CallRuntime(Runtime::kNewClosure, 2);
787 Apply(context_, eax); 789 Apply(context_, eax);
788 } 790 }
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 __ add(Operand(edx), Immediate(masm_->CodeObject())); 1893 __ add(Operand(edx), Immediate(masm_->CodeObject()));
1892 __ mov(Operand(esp, 0), edx); 1894 __ mov(Operand(esp, 0), edx);
1893 // And return. 1895 // And return.
1894 __ ret(0); 1896 __ ret(0);
1895 } 1897 }
1896 1898
1897 1899
1898 #undef __ 1900 #undef __
1899 1901
1900 } } // namespace v8::internal 1902 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/fast-codegen-ia32.cc ('k') | src/x64/codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698