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

Side by Side Diff: src/arm/codegen-arm.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/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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 114
115 CodeGenState::~CodeGenState() { 115 CodeGenState::~CodeGenState() {
116 ASSERT(owner_->state() == this); 116 ASSERT(owner_->state() == this);
117 owner_->set_state(previous_); 117 owner_->set_state(previous_);
118 } 118 }
119 119
120 120
121 // ------------------------------------------------------------------------- 121 // -------------------------------------------------------------------------
122 // CodeGenerator implementation 122 // CodeGenerator implementation
123 123
124 CodeGenerator::CodeGenerator(MacroAssembler* masm, 124 CodeGenerator::CodeGenerator(MacroAssembler* masm)
125 Handle<Script> script, 125 : deferred_(8),
126 bool is_eval)
127 : is_eval_(is_eval),
128 script_(script),
129 deferred_(8),
130 masm_(masm), 126 masm_(masm),
131 scope_(NULL), 127 info_(NULL),
132 frame_(NULL), 128 frame_(NULL),
133 allocator_(NULL), 129 allocator_(NULL),
134 cc_reg_(al), 130 cc_reg_(al),
135 state_(NULL), 131 state_(NULL),
136 function_return_is_shadowed_(false) { 132 function_return_is_shadowed_(false) {
137 } 133 }
138 134
139 135
136 Scope* CodeGenerator::scope() { return info_->function()->scope(); }
137
138
140 // Calling conventions: 139 // Calling conventions:
141 // fp: caller's frame pointer 140 // fp: caller's frame pointer
142 // sp: stack pointer 141 // sp: stack pointer
143 // r1: called JS function 142 // r1: called JS function
144 // cp: callee's context 143 // cp: callee's context
145 144
146 void CodeGenerator::Generate(FunctionLiteral* fun, 145 void CodeGenerator::Generate(CompilationInfo* info, Mode mode) {
147 Mode mode,
148 CompilationInfo* info) {
149 // Record the position for debugging purposes. 146 // Record the position for debugging purposes.
150 CodeForFunctionPosition(fun); 147 CodeForFunctionPosition(info->function());
151
152 ZoneList<Statement*>* body = fun->body();
153 148
154 // Initialize state. 149 // Initialize state.
155 ASSERT(scope_ == NULL); 150 info_ = info;
156 scope_ = fun->scope();
157 ASSERT(allocator_ == NULL); 151 ASSERT(allocator_ == NULL);
158 RegisterAllocator register_allocator(this); 152 RegisterAllocator register_allocator(this);
159 allocator_ = &register_allocator; 153 allocator_ = &register_allocator;
160 ASSERT(frame_ == NULL); 154 ASSERT(frame_ == NULL);
161 frame_ = new VirtualFrame(); 155 frame_ = new VirtualFrame();
162 cc_reg_ = al; 156 cc_reg_ = al;
163 { 157 {
164 CodeGenState state(this); 158 CodeGenState state(this);
165 159
166 // Entry: 160 // Entry:
167 // Stack: receiver, arguments 161 // Stack: receiver, arguments
168 // lr: return address 162 // lr: return address
169 // fp: caller's frame pointer 163 // fp: caller's frame pointer
170 // sp: stack pointer 164 // sp: stack pointer
171 // r1: called JS function 165 // r1: called JS function
172 // cp: callee's context 166 // cp: callee's context
173 allocator_->Initialize(); 167 allocator_->Initialize();
174 168
175 #ifdef DEBUG 169 #ifdef DEBUG
176 if (strlen(FLAG_stop_at) > 0 && 170 if (strlen(FLAG_stop_at) > 0 &&
177 fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { 171 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
178 frame_->SpillAll(); 172 frame_->SpillAll();
179 __ stop("stop-at"); 173 __ stop("stop-at");
180 } 174 }
181 #endif 175 #endif
182 176
183 if (mode == PRIMARY) { 177 if (mode == PRIMARY) {
184 frame_->Enter(); 178 frame_->Enter();
185 // tos: code slot 179 // tos: code slot
186 180
187 // Allocate space for locals and initialize them. This also checks 181 // Allocate space for locals and initialize them. This also checks
188 // for stack overflow. 182 // for stack overflow.
189 frame_->AllocateStackSlots(); 183 frame_->AllocateStackSlots();
190 184
191 VirtualFrame::SpilledScope spilled_scope; 185 VirtualFrame::SpilledScope spilled_scope;
192 int heap_slots = scope_->num_heap_slots(); 186 int heap_slots = scope()->num_heap_slots();
193 if (heap_slots > 0) { 187 if (heap_slots > 0) {
194 // Allocate local context. 188 // Allocate local context.
195 // Get outer context and create a new context based on it. 189 // Get outer context and create a new context based on it.
196 __ ldr(r0, frame_->Function()); 190 __ ldr(r0, frame_->Function());
197 frame_->EmitPush(r0); 191 frame_->EmitPush(r0);
198 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 192 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
199 FastNewContextStub stub(heap_slots); 193 FastNewContextStub stub(heap_slots);
200 frame_->CallStub(&stub, 1); 194 frame_->CallStub(&stub, 1);
201 } else { 195 } else {
202 frame_->CallRuntime(Runtime::kNewContext, 1); 196 frame_->CallRuntime(Runtime::kNewContext, 1);
203 } 197 }
204 198
205 #ifdef DEBUG 199 #ifdef DEBUG
206 JumpTarget verified_true; 200 JumpTarget verified_true;
207 __ cmp(r0, Operand(cp)); 201 __ cmp(r0, Operand(cp));
208 verified_true.Branch(eq); 202 verified_true.Branch(eq);
209 __ stop("NewContext: r0 is expected to be the same as cp"); 203 __ stop("NewContext: r0 is expected to be the same as cp");
210 verified_true.Bind(); 204 verified_true.Bind();
211 #endif 205 #endif
212 // Update context local. 206 // Update context local.
213 __ str(cp, frame_->Context()); 207 __ str(cp, frame_->Context());
214 } 208 }
215 209
216 // TODO(1241774): Improve this code: 210 // TODO(1241774): Improve this code:
217 // 1) only needed if we have a context 211 // 1) only needed if we have a context
218 // 2) no need to recompute context ptr every single time 212 // 2) no need to recompute context ptr every single time
219 // 3) don't copy parameter operand code from SlotOperand! 213 // 3) don't copy parameter operand code from SlotOperand!
220 { 214 {
221 Comment cmnt2(masm_, "[ copy context parameters into .context"); 215 Comment cmnt2(masm_, "[ copy context parameters into .context");
222
223 // Note that iteration order is relevant here! If we have the same 216 // Note that iteration order is relevant here! If we have the same
224 // parameter twice (e.g., function (x, y, x)), and that parameter 217 // 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 218 // 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 219 // 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 220 // 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 221 // order: such a parameter is copied repeatedly into the same
229 // context location and thus the last value is what is seen inside 222 // context location and thus the last value is what is seen inside
230 // the function. 223 // the function.
231 for (int i = 0; i < scope_->num_parameters(); i++) { 224 for (int i = 0; i < scope()->num_parameters(); i++) {
232 Variable* par = scope_->parameter(i); 225 Variable* par = scope()->parameter(i);
233 Slot* slot = par->slot(); 226 Slot* slot = par->slot();
234 if (slot != NULL && slot->type() == Slot::CONTEXT) { 227 if (slot != NULL && slot->type() == Slot::CONTEXT) {
235 // No parameters in global scope. 228 ASSERT(!scope()->is_global_scope()); // no parameters in global sco pe
236 ASSERT(!scope_->is_global_scope());
237 __ ldr(r1, frame_->ParameterAt(i)); 229 __ ldr(r1, frame_->ParameterAt(i));
238 // Loads r2 with context; used below in RecordWrite. 230 // Loads r2 with context; used below in RecordWrite.
239 __ str(r1, SlotOperand(slot, r2)); 231 __ str(r1, SlotOperand(slot, r2));
240 // Load the offset into r3. 232 // Load the offset into r3.
241 int slot_offset = 233 int slot_offset =
242 FixedArray::kHeaderSize + slot->index() * kPointerSize; 234 FixedArray::kHeaderSize + slot->index() * kPointerSize;
243 __ mov(r3, Operand(slot_offset)); 235 __ mov(r3, Operand(slot_offset));
244 __ RecordWrite(r2, r3, r1); 236 __ RecordWrite(r2, r3, r1);
245 } 237 }
246 } 238 }
247 } 239 }
248 240
249 // Store the arguments object. This must happen after context 241 // Store the arguments object. This must happen after context
250 // initialization because the arguments object may be stored in the 242 // initialization because the arguments object may be stored in the
251 // context. 243 // context.
252 if (scope_->arguments() != NULL) { 244 if (scope()->arguments() != NULL) {
253 Comment cmnt(masm_, "[ allocate arguments object"); 245 Comment cmnt(masm_, "[ allocate arguments object");
254 ASSERT(scope_->arguments_shadow() != NULL); 246 ASSERT(scope()->arguments_shadow() != NULL);
255 Variable* arguments = scope_->arguments()->var(); 247 Variable* arguments = scope()->arguments()->var();
256 Variable* shadow = scope_->arguments_shadow()->var(); 248 Variable* shadow = scope()->arguments_shadow()->var();
257 ASSERT(arguments != NULL && arguments->slot() != NULL); 249 ASSERT(arguments != NULL && arguments->slot() != NULL);
258 ASSERT(shadow != NULL && shadow->slot() != NULL); 250 ASSERT(shadow != NULL && shadow->slot() != NULL);
259 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); 251 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
260 __ ldr(r2, frame_->Function()); 252 __ ldr(r2, frame_->Function());
261 // The receiver is below the arguments, the return address, and the 253 // The receiver is below the arguments, the return address, and the
262 // frame pointer on the stack. 254 // frame pointer on the stack.
263 const int kReceiverDisplacement = 2 + scope_->num_parameters(); 255 const int kReceiverDisplacement = 2 + scope()->num_parameters();
264 __ add(r1, fp, Operand(kReceiverDisplacement * kPointerSize)); 256 __ add(r1, fp, Operand(kReceiverDisplacement * kPointerSize));
265 __ mov(r0, Operand(Smi::FromInt(scope_->num_parameters()))); 257 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
266 frame_->Adjust(3); 258 frame_->Adjust(3);
267 __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit()); 259 __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit());
268 frame_->CallStub(&stub, 3); 260 frame_->CallStub(&stub, 3);
269 frame_->EmitPush(r0); 261 frame_->EmitPush(r0);
270 StoreToSlot(arguments->slot(), NOT_CONST_INIT); 262 StoreToSlot(arguments->slot(), NOT_CONST_INIT);
271 StoreToSlot(shadow->slot(), NOT_CONST_INIT); 263 StoreToSlot(shadow->slot(), NOT_CONST_INIT);
272 frame_->Drop(); // Value is no longer needed. 264 frame_->Drop(); // Value is no longer needed.
273 } 265 }
274 266
275 // Initialize ThisFunction reference if present. 267 // Initialize ThisFunction reference if present.
276 if (scope_->is_function_scope() && scope_->function() != NULL) { 268 if (scope()->is_function_scope() && scope()->function() != NULL) {
277 __ mov(ip, Operand(Factory::the_hole_value())); 269 __ mov(ip, Operand(Factory::the_hole_value()));
278 frame_->EmitPush(ip); 270 frame_->EmitPush(ip);
279 StoreToSlot(scope_->function()->slot(), NOT_CONST_INIT); 271 StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT);
280 } 272 }
281 } else { 273 } else {
282 // When used as the secondary compiler for splitting, r1, cp, 274 // When used as the secondary compiler for splitting, r1, cp,
283 // fp, and lr have been pushed on the stack. Adjust the virtual 275 // fp, and lr have been pushed on the stack. Adjust the virtual
284 // frame to match this state. 276 // frame to match this state.
285 frame_->Adjust(4); 277 frame_->Adjust(4);
286 allocator_->Unuse(r1); 278 allocator_->Unuse(r1);
287 allocator_->Unuse(lr); 279 allocator_->Unuse(lr);
288 } 280 }
289 281
290 // Initialize the function return target after the locals are set 282 // Initialize the function return target after the locals are set
291 // up, because it needs the expected frame height from the frame. 283 // up, because it needs the expected frame height from the frame.
292 function_return_.set_direction(JumpTarget::BIDIRECTIONAL); 284 function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
293 function_return_is_shadowed_ = false; 285 function_return_is_shadowed_ = false;
294 286
295 // Generate code to 'execute' declarations and initialize functions 287 // Generate code to 'execute' declarations and initialize functions
296 // (source elements). In case of an illegal redeclaration we need to 288 // (source elements). In case of an illegal redeclaration we need to
297 // handle that instead of processing the declarations. 289 // handle that instead of processing the declarations.
298 if (scope_->HasIllegalRedeclaration()) { 290 if (scope()->HasIllegalRedeclaration()) {
299 Comment cmnt(masm_, "[ illegal redeclarations"); 291 Comment cmnt(masm_, "[ illegal redeclarations");
300 scope_->VisitIllegalRedeclaration(this); 292 scope()->VisitIllegalRedeclaration(this);
301 } else { 293 } else {
302 Comment cmnt(masm_, "[ declarations"); 294 Comment cmnt(masm_, "[ declarations");
303 ProcessDeclarations(scope_->declarations()); 295 ProcessDeclarations(scope()->declarations());
304 // Bail out if a stack-overflow exception occurred when processing 296 // Bail out if a stack-overflow exception occurred when processing
305 // declarations. 297 // declarations.
306 if (HasStackOverflow()) return; 298 if (HasStackOverflow()) return;
307 } 299 }
308 300
309 if (FLAG_trace) { 301 if (FLAG_trace) {
310 frame_->CallRuntime(Runtime::kTraceEnter, 0); 302 frame_->CallRuntime(Runtime::kTraceEnter, 0);
311 // Ignore the return value. 303 // Ignore the return value.
312 } 304 }
313 305
314 // Compile the body of the function in a vanilla state. Don't 306 // Compile the body of the function in a vanilla state. Don't
315 // bother compiling all the code if the scope has an illegal 307 // bother compiling all the code if the scope has an illegal
316 // redeclaration. 308 // redeclaration.
317 if (!scope_->HasIllegalRedeclaration()) { 309 if (!scope()->HasIllegalRedeclaration()) {
318 Comment cmnt(masm_, "[ function body"); 310 Comment cmnt(masm_, "[ function body");
319 #ifdef DEBUG 311 #ifdef DEBUG
320 bool is_builtin = Bootstrapper::IsActive(); 312 bool is_builtin = Bootstrapper::IsActive();
321 bool should_trace = 313 bool should_trace =
322 is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls; 314 is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls;
323 if (should_trace) { 315 if (should_trace) {
324 frame_->CallRuntime(Runtime::kDebugTrace, 0); 316 frame_->CallRuntime(Runtime::kDebugTrace, 0);
325 // Ignore the return value. 317 // Ignore the return value.
326 } 318 }
327 #endif 319 #endif
328 VisitStatementsAndSpill(body); 320 VisitStatementsAndSpill(info->function()->body());
329 } 321 }
330 } 322 }
331 323
332 // Generate the return sequence if necessary. 324 // Generate the return sequence if necessary.
333 if (has_valid_frame() || function_return_.is_linked()) { 325 if (has_valid_frame() || function_return_.is_linked()) {
334 if (!function_return_.is_linked()) { 326 if (!function_return_.is_linked()) {
335 CodeForReturnPosition(fun); 327 CodeForReturnPosition(info->function());
336 } 328 }
337 // exit 329 // exit
338 // r0: result 330 // r0: result
339 // sp: stack pointer 331 // sp: stack pointer
340 // fp: frame pointer 332 // fp: frame pointer
341 // cp: callee's context 333 // cp: callee's context
342 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 334 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
343 335
344 function_return_.Bind(); 336 function_return_.Bind();
345 if (FLAG_trace) { 337 if (FLAG_trace) {
346 // Push the return value on the stack as the parameter. 338 // Push the return value on the stack as the parameter.
347 // Runtime::TraceExit returns the parameter as it is. 339 // Runtime::TraceExit returns the parameter as it is.
348 frame_->EmitPush(r0); 340 frame_->EmitPush(r0);
349 frame_->CallRuntime(Runtime::kTraceExit, 1); 341 frame_->CallRuntime(Runtime::kTraceExit, 1);
350 } 342 }
351 343
352 // Add a label for checking the size of the code used for returning. 344 // Add a label for checking the size of the code used for returning.
353 Label check_exit_codesize; 345 Label check_exit_codesize;
354 masm_->bind(&check_exit_codesize); 346 masm_->bind(&check_exit_codesize);
355 347
356 // Calculate the exact length of the return sequence and make sure that 348 // Calculate the exact length of the return sequence and make sure that
357 // the constant pool is not emitted inside of the return sequence. 349 // the constant pool is not emitted inside of the return sequence.
358 int32_t sp_delta = (scope_->num_parameters() + 1) * kPointerSize; 350 int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize;
359 int return_sequence_length = Assembler::kJSReturnSequenceLength; 351 int return_sequence_length = Assembler::kJSReturnSequenceLength;
360 if (!masm_->ImmediateFitsAddrMode1Instruction(sp_delta)) { 352 if (!masm_->ImmediateFitsAddrMode1Instruction(sp_delta)) {
361 // Additional mov instruction generated. 353 // Additional mov instruction generated.
362 return_sequence_length++; 354 return_sequence_length++;
363 } 355 }
364 masm_->BlockConstPoolFor(return_sequence_length); 356 masm_->BlockConstPoolFor(return_sequence_length);
365 357
366 // Tear down the frame which will restore the caller's frame pointer and 358 // Tear down the frame which will restore the caller's frame pointer and
367 // the link register. 359 // the link register.
368 frame_->Exit(); 360 frame_->Exit();
(...skipping 19 matching lines...) Expand all
388 ASSERT(!function_return_is_shadowed_); 380 ASSERT(!function_return_is_shadowed_);
389 function_return_.Unuse(); 381 function_return_.Unuse();
390 DeleteFrame(); 382 DeleteFrame();
391 383
392 // Process any deferred code using the register allocator. 384 // Process any deferred code using the register allocator.
393 if (!HasStackOverflow()) { 385 if (!HasStackOverflow()) {
394 ProcessDeferred(); 386 ProcessDeferred();
395 } 387 }
396 388
397 allocator_ = NULL; 389 allocator_ = NULL;
398 scope_ = NULL;
399 } 390 }
400 391
401 392
402 MemOperand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { 393 MemOperand CodeGenerator::SlotOperand(Slot* slot, Register tmp) {
403 // Currently, this assertion will fail if we try to assign to 394 // Currently, this assertion will fail if we try to assign to
404 // a constant variable that is constant because it is read-only 395 // a constant variable that is constant because it is read-only
405 // (such as the variable referring to a named function expression). 396 // (such as the variable referring to a named function expression).
406 // We need to implement assignments to read-only variables. 397 // We need to implement assignments to read-only variables.
407 // Ideally, we should do this during AST generation (by converting 398 // Ideally, we should do this during AST generation (by converting
408 // such assignments into expression statements); however, in general 399 // such assignments into expression statements); however, in general
(...skipping 1925 matching lines...) Expand 10 before | Expand all | Expand 10 after
2334 2325
2335 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) { 2326 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) {
2336 #ifdef DEBUG 2327 #ifdef DEBUG
2337 int original_height = frame_->height(); 2328 int original_height = frame_->height();
2338 #endif 2329 #endif
2339 VirtualFrame::SpilledScope spilled_scope; 2330 VirtualFrame::SpilledScope spilled_scope;
2340 Comment cmnt(masm_, "[ FunctionLiteral"); 2331 Comment cmnt(masm_, "[ FunctionLiteral");
2341 2332
2342 // Build the function boilerplate and instantiate it. 2333 // Build the function boilerplate and instantiate it.
2343 Handle<JSFunction> boilerplate = 2334 Handle<JSFunction> boilerplate =
2344 Compiler::BuildBoilerplate(node, script_, this); 2335 Compiler::BuildBoilerplate(node, script(), this);
2345 // Check for stack-overflow exception. 2336 // Check for stack-overflow exception.
2346 if (HasStackOverflow()) { 2337 if (HasStackOverflow()) {
2347 ASSERT(frame_->height() == original_height); 2338 ASSERT(frame_->height() == original_height);
2348 return; 2339 return;
2349 } 2340 }
2350 InstantiateBoilerplate(boilerplate); 2341 InstantiateBoilerplate(boilerplate);
2351 ASSERT(frame_->height() == original_height + 1); 2342 ASSERT(frame_->height() == original_height + 1);
2352 } 2343 }
2353 2344
2354 2345
(...skipping 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after
3512 cc_reg_ = eq; 3503 cc_reg_ = eq;
3513 } 3504 }
3514 3505
3515 3506
3516 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { 3507 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
3517 VirtualFrame::SpilledScope spilled_scope; 3508 VirtualFrame::SpilledScope spilled_scope;
3518 ASSERT(args->length() == 0); 3509 ASSERT(args->length() == 0);
3519 3510
3520 // Seed the result with the formal parameters count, which will be used 3511 // Seed the result with the formal parameters count, which will be used
3521 // in case no arguments adaptor frame is found below the current frame. 3512 // in case no arguments adaptor frame is found below the current frame.
3522 __ mov(r0, Operand(Smi::FromInt(scope_->num_parameters()))); 3513 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
3523 3514
3524 // Call the shared stub to get to the arguments.length. 3515 // Call the shared stub to get to the arguments.length.
3525 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH); 3516 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH);
3526 frame_->CallStub(&stub, 0); 3517 frame_->CallStub(&stub, 0);
3527 frame_->EmitPush(r0); 3518 frame_->EmitPush(r0);
3528 } 3519 }
3529 3520
3530 3521
3531 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { 3522 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) {
3532 VirtualFrame::SpilledScope spilled_scope; 3523 VirtualFrame::SpilledScope spilled_scope;
3533 ASSERT(args->length() == 1); 3524 ASSERT(args->length() == 1);
3534 3525
3535 // Satisfy contract with ArgumentsAccessStub: 3526 // Satisfy contract with ArgumentsAccessStub:
3536 // Load the key into r1 and the formal parameters count into r0. 3527 // Load the key into r1 and the formal parameters count into r0.
3537 LoadAndSpill(args->at(0)); 3528 LoadAndSpill(args->at(0));
3538 frame_->EmitPop(r1); 3529 frame_->EmitPop(r1);
3539 __ mov(r0, Operand(Smi::FromInt(scope_->num_parameters()))); 3530 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
3540 3531
3541 // Call the shared stub to get to arguments[key]. 3532 // Call the shared stub to get to arguments[key].
3542 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); 3533 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
3543 frame_->CallStub(&stub, 0); 3534 frame_->CallStub(&stub, 0);
3544 frame_->EmitPush(r0); 3535 frame_->EmitPush(r0);
3545 } 3536 }
3546 3537
3547 3538
3548 void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* args) { 3539 void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* args) {
3549 VirtualFrame::SpilledScope spilled_scope; 3540 VirtualFrame::SpilledScope spilled_scope;
(...skipping 3377 matching lines...) Expand 10 before | Expand all | Expand 10 after
6927 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 6918 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
6928 // tagged as a small integer. 6919 // tagged as a small integer.
6929 __ bind(&runtime); 6920 __ bind(&runtime);
6930 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); 6921 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1);
6931 } 6922 }
6932 6923
6933 6924
6934 #undef __ 6925 #undef __
6935 6926
6936 } } // namespace v8::internal 6927 } } // 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