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

Side by Side Diff: src/arm/codegen-arm.cc

Issue 569010: Use the virtual-frame based optimizing compiler for split-compilation... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' 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 | Annotate | Revision Log
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/arm/fast-codegen-arm.cc » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 function_return_is_shadowed_(false) { 136 function_return_is_shadowed_(false) {
137 } 137 }
138 138
139 139
140 // Calling conventions: 140 // Calling conventions:
141 // fp: caller's frame pointer 141 // fp: caller's frame pointer
142 // sp: stack pointer 142 // sp: stack pointer
143 // r1: called JS function 143 // r1: called JS function
144 // cp: callee's context 144 // cp: callee's context
145 145
146 void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) { 146 void CodeGenerator::Generate(FunctionLiteral* fun,
147 Mode mode,
148 CompilationInfo* info) {
147 // Record the position for debugging purposes. 149 // Record the position for debugging purposes.
148 CodeForFunctionPosition(fun); 150 CodeForFunctionPosition(fun);
149 151
150 ZoneList<Statement*>* body = fun->body(); 152 ZoneList<Statement*>* body = fun->body();
151 153
152 // Initialize state. 154 // Initialize state.
153 ASSERT(scope_ == NULL); 155 ASSERT(scope_ == NULL);
154 scope_ = fun->scope(); 156 scope_ = fun->scope();
155 ASSERT(allocator_ == NULL); 157 ASSERT(allocator_ == NULL);
156 RegisterAllocator register_allocator(this); 158 RegisterAllocator register_allocator(this);
157 allocator_ = &register_allocator; 159 allocator_ = &register_allocator;
158 ASSERT(frame_ == NULL); 160 ASSERT(frame_ == NULL);
159 frame_ = new VirtualFrame(); 161 frame_ = new VirtualFrame();
160 cc_reg_ = al; 162 cc_reg_ = al;
161 { 163 {
162 CodeGenState state(this); 164 CodeGenState state(this);
163 165
164 // Entry: 166 // Entry:
165 // Stack: receiver, arguments 167 // Stack: receiver, arguments
166 // lr: return address 168 // lr: return address
167 // fp: caller's frame pointer 169 // fp: caller's frame pointer
168 // sp: stack pointer 170 // sp: stack pointer
169 // r1: called JS function 171 // r1: called JS function
170 // cp: callee's context 172 // cp: callee's context
171 allocator_->Initialize(); 173 allocator_->Initialize();
172 frame_->Enter(); 174
173 // tos: code slot
174 #ifdef DEBUG 175 #ifdef DEBUG
175 if (strlen(FLAG_stop_at) > 0 && 176 if (strlen(FLAG_stop_at) > 0 &&
176 fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { 177 fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
177 frame_->SpillAll(); 178 frame_->SpillAll();
178 __ stop("stop-at"); 179 __ stop("stop-at");
179 } 180 }
180 #endif 181 #endif
181 182
182 // Allocate space for locals and initialize them. This also checks 183 if (mode == PRIMARY) {
183 // for stack overflow. 184 frame_->Enter();
184 frame_->AllocateStackSlots(); 185 // tos: code slot
186
187 // Allocate space for locals and initialize them. This also checks
188 // for stack overflow.
189 frame_->AllocateStackSlots();
190
191 VirtualFrame::SpilledScope spilled_scope;
192 int heap_slots = scope_->num_heap_slots();
193 if (heap_slots > 0) {
194 // Allocate local context.
195 // Get outer context and create a new context based on it.
196 __ ldr(r0, frame_->Function());
197 frame_->EmitPush(r0);
198 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
199 FastNewContextStub stub(heap_slots);
200 frame_->CallStub(&stub, 1);
201 } else {
202 frame_->CallRuntime(Runtime::kNewContext, 1);
203 }
204
205 #ifdef DEBUG
206 JumpTarget verified_true;
207 __ cmp(r0, Operand(cp));
208 verified_true.Branch(eq);
209 __ stop("NewContext: r0 is expected to be the same as cp");
210 verified_true.Bind();
211 #endif
212 // Update context local.
213 __ str(cp, frame_->Context());
214 }
215
216 // TODO(1241774): Improve this code:
217 // 1) only needed if we have a context
218 // 2) no need to recompute context ptr every single time
219 // 3) don't copy parameter operand code from SlotOperand!
220 {
221 Comment cmnt2(masm_, "[ copy context parameters into .context");
222
223 // Note that iteration order is relevant here! If we have the same
224 // parameter twice (e.g., function (x, y, x)), and that parameter
225 // needs to be copied into the context, it must be the last argument
226 // passed to the parameter that needs to be copied. This is a rare
227 // case so we don't check for it, instead we rely on the copying
228 // order: such a parameter is copied repeatedly into the same
229 // context location and thus the last value is what is seen inside
230 // the function.
231 for (int i = 0; i < scope_->num_parameters(); i++) {
232 Variable* par = scope_->parameter(i);
233 Slot* slot = par->slot();
234 if (slot != NULL && slot->type() == Slot::CONTEXT) {
235 // No parameters in global scope.
236 ASSERT(!scope_->is_global_scope());
237 __ ldr(r1, frame_->ParameterAt(i));
238 // Loads r2 with context; used below in RecordWrite.
239 __ str(r1, SlotOperand(slot, r2));
240 // Load the offset into r3.
241 int slot_offset =
242 FixedArray::kHeaderSize + slot->index() * kPointerSize;
243 __ mov(r3, Operand(slot_offset));
244 __ RecordWrite(r2, r3, r1);
245 }
246 }
247 }
248
249 // Store the arguments object. This must happen after context
250 // initialization because the arguments object may be stored in the
251 // context.
252 if (scope_->arguments() != NULL) {
253 Comment cmnt(masm_, "[ allocate arguments object");
254 ASSERT(scope_->arguments_shadow() != NULL);
255 Variable* arguments = scope_->arguments()->var();
256 Variable* shadow = scope_->arguments_shadow()->var();
257 ASSERT(arguments != NULL && arguments->slot() != NULL);
258 ASSERT(shadow != NULL && shadow->slot() != NULL);
259 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
260 __ ldr(r2, frame_->Function());
261 // The receiver is below the arguments, the return address, and the
262 // frame pointer on the stack.
263 const int kReceiverDisplacement = 2 + scope_->num_parameters();
264 __ add(r1, fp, Operand(kReceiverDisplacement * kPointerSize));
265 __ mov(r0, Operand(Smi::FromInt(scope_->num_parameters())));
266 frame_->Adjust(3);
267 __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit());
268 frame_->CallStub(&stub, 3);
269 frame_->EmitPush(r0);
270 StoreToSlot(arguments->slot(), NOT_CONST_INIT);
271 StoreToSlot(shadow->slot(), NOT_CONST_INIT);
272 frame_->Drop(); // Value is no longer needed.
273 }
274
275 // Initialize ThisFunction reference if present.
276 if (scope_->is_function_scope() && scope_->function() != NULL) {
277 __ mov(ip, Operand(Factory::the_hole_value()));
278 frame_->EmitPush(ip);
279 StoreToSlot(scope_->function()->slot(), NOT_CONST_INIT);
280 }
281 } else {
282 // When used as the secondary compiler for splitting, r1, cp,
283 // fp, and lr have been pushed on the stack. Adjust the virtual
284 // frame to match this state.
285 frame_->Adjust(4);
286 allocator_->Unuse(r1);
287 allocator_->Unuse(lr);
288 }
289
185 // Initialize the function return target after the locals are set 290 // Initialize the function return target after the locals are set
186 // up, because it needs the expected frame height from the frame. 291 // up, because it needs the expected frame height from the frame.
187 function_return_.set_direction(JumpTarget::BIDIRECTIONAL); 292 function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
188 function_return_is_shadowed_ = false; 293 function_return_is_shadowed_ = false;
189 294
190 VirtualFrame::SpilledScope spilled_scope;
191 int heap_slots = scope_->num_heap_slots();
192 if (heap_slots > 0) {
193 // Allocate local context.
194 // Get outer context and create a new context based on it.
195 __ ldr(r0, frame_->Function());
196 frame_->EmitPush(r0);
197 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
198 FastNewContextStub stub(heap_slots);
199 frame_->CallStub(&stub, 1);
200 } else {
201 frame_->CallRuntime(Runtime::kNewContext, 1);
202 }
203
204 #ifdef DEBUG
205 JumpTarget verified_true;
206 __ cmp(r0, Operand(cp));
207 verified_true.Branch(eq);
208 __ stop("NewContext: r0 is expected to be the same as cp");
209 verified_true.Bind();
210 #endif
211 // Update context local.
212 __ str(cp, frame_->Context());
213 }
214
215 // TODO(1241774): Improve this code:
216 // 1) only needed if we have a context
217 // 2) no need to recompute context ptr every single time
218 // 3) don't copy parameter operand code from SlotOperand!
219 {
220 Comment cmnt2(masm_, "[ copy context parameters into .context");
221
222 // Note that iteration order is relevant here! If we have the same
223 // parameter twice (e.g., function (x, y, x)), and that parameter
224 // needs to be copied into the context, it must be the last argument
225 // passed to the parameter that needs to be copied. This is a rare
226 // case so we don't check for it, instead we rely on the copying
227 // order: such a parameter is copied repeatedly into the same
228 // context location and thus the last value is what is seen inside
229 // the function.
230 for (int i = 0; i < scope_->num_parameters(); i++) {
231 Variable* par = scope_->parameter(i);
232 Slot* slot = par->slot();
233 if (slot != NULL && slot->type() == Slot::CONTEXT) {
234 ASSERT(!scope_->is_global_scope()); // no parameters in global scope
235 __ ldr(r1, frame_->ParameterAt(i));
236 // Loads r2 with context; used below in RecordWrite.
237 __ str(r1, SlotOperand(slot, r2));
238 // Load the offset into r3.
239 int slot_offset =
240 FixedArray::kHeaderSize + slot->index() * kPointerSize;
241 __ mov(r3, Operand(slot_offset));
242 __ RecordWrite(r2, r3, r1);
243 }
244 }
245 }
246
247 // Store the arguments object. This must happen after context
248 // initialization because the arguments object may be stored in the
249 // context.
250 if (scope_->arguments() != NULL) {
251 Comment cmnt(masm_, "[ allocate arguments object");
252 ASSERT(scope_->arguments_shadow() != NULL);
253 Variable* arguments = scope_->arguments()->var();
254 Variable* shadow = scope_->arguments_shadow()->var();
255 ASSERT(arguments != NULL && arguments->slot() != NULL);
256 ASSERT(shadow != NULL && shadow->slot() != NULL);
257 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
258 __ ldr(r2, frame_->Function());
259 // The receiver is below the arguments, the return address, and the
260 // frame pointer on the stack.
261 const int kReceiverDisplacement = 2 + scope_->num_parameters();
262 __ add(r1, fp, Operand(kReceiverDisplacement * kPointerSize));
263 __ mov(r0, Operand(Smi::FromInt(scope_->num_parameters())));
264 frame_->Adjust(3);
265 __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit());
266 frame_->CallStub(&stub, 3);
267 frame_->EmitPush(r0);
268 StoreToSlot(arguments->slot(), NOT_CONST_INIT);
269 StoreToSlot(shadow->slot(), NOT_CONST_INIT);
270 frame_->Drop(); // Value is no longer needed.
271 }
272
273 // Initialize ThisFunction reference if present.
274 if (scope_->is_function_scope() && scope_->function() != NULL) {
275 __ mov(ip, Operand(Factory::the_hole_value()));
276 frame_->EmitPush(ip);
277 StoreToSlot(scope_->function()->slot(), NOT_CONST_INIT);
278 }
279
280 // Generate code to 'execute' declarations and initialize functions 295 // Generate code to 'execute' declarations and initialize functions
281 // (source elements). In case of an illegal redeclaration we need to 296 // (source elements). In case of an illegal redeclaration we need to
282 // handle that instead of processing the declarations. 297 // handle that instead of processing the declarations.
283 if (scope_->HasIllegalRedeclaration()) { 298 if (scope_->HasIllegalRedeclaration()) {
284 Comment cmnt(masm_, "[ illegal redeclarations"); 299 Comment cmnt(masm_, "[ illegal redeclarations");
285 scope_->VisitIllegalRedeclaration(this); 300 scope_->VisitIllegalRedeclaration(this);
286 } else { 301 } else {
287 Comment cmnt(masm_, "[ declarations"); 302 Comment cmnt(masm_, "[ declarations");
288 ProcessDeclarations(scope_->declarations()); 303 ProcessDeclarations(scope_->declarations());
289 // Bail out if a stack-overflow exception occurred when processing 304 // Bail out if a stack-overflow exception occurred when processing
(...skipping 6623 matching lines...) Expand 10 before | Expand all | Expand 10 after
6913 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 6928 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
6914 // tagged as a small integer. 6929 // tagged as a small integer.
6915 __ bind(&runtime); 6930 __ bind(&runtime);
6916 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); 6931 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1);
6917 } 6932 }
6918 6933
6919 6934
6920 #undef __ 6935 #undef __
6921 6936
6922 } } // namespace v8::internal 6937 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/arm/fast-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698