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

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

Issue 546006: Some cleanup of the toplevel code generator:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 11 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
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 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 // mode 1 instruction where there are restrictions on which immediate values 207 // mode 1 instruction where there are restrictions on which immediate values
208 // can be encoded in the instruction and which immediate values requires 208 // can be encoded in the instruction and which immediate values requires
209 // use of an additional instruction for moving the immediate to a temporary 209 // use of an additional instruction for moving the immediate to a temporary
210 // register. 210 // register.
211 ASSERT_EQ(return_sequence_length, 211 ASSERT_EQ(return_sequence_length,
212 masm_->InstructionsGeneratedSince(&check_exit_codesize)); 212 masm_->InstructionsGeneratedSince(&check_exit_codesize));
213 } 213 }
214 } 214 }
215 215
216 216
217 void FastCodeGenerator::Move(Expression::Context context, Register source) { 217 void FastCodeGenerator::Apply(Expression::Context context,
218 Slot* slot,
219 Register scratch) {
218 switch (context) { 220 switch (context) {
219 case Expression::kUninitialized: 221 case Expression::kUninitialized:
220 UNREACHABLE(); 222 UNREACHABLE();
221 case Expression::kEffect: 223 case Expression::kEffect:
222 break; 224 break;
223 case Expression::kValue: 225 case Expression::kValue:
224 __ push(source); 226 case Expression::kTest:
227 case Expression::kValueTest:
228 case Expression::kTestValue:
229 Move(scratch, slot);
230 Apply(context, scratch);
225 break; 231 break;
226 case Expression::kTest:
227 TestAndBranch(source, true_label_, false_label_);
228 break;
229 case Expression::kValueTest: {
230 Label discard;
231 __ push(source);
232 TestAndBranch(source, true_label_, &discard);
233 __ bind(&discard);
234 __ pop();
235 __ jmp(false_label_);
236 break;
237 }
238 case Expression::kTestValue: {
239 Label discard;
240 __ push(source);
241 TestAndBranch(source, &discard, false_label_);
242 __ bind(&discard);
243 __ pop();
244 __ jmp(true_label_);
245 }
246 } 232 }
247 } 233 }
248 234
249 235
250 void FastCodeGenerator::MoveTOS(Expression::Context context) { 236 void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) {
237 switch (context) {
238 case Expression::kUninitialized:
239 UNREACHABLE();
240 case Expression::kEffect:
241 break;
242 case Expression::kValue:
243 case Expression::kTest:
244 case Expression::kValueTest:
245 case Expression::kTestValue:
246 __ mov(ip, Operand(lit->handle()));
247 Apply(context, ip);
248 break;
249 }
250 }
251
252
253 void FastCodeGenerator::ApplyTOS(Expression::Context context) {
251 switch (context) { 254 switch (context) {
252 case Expression::kUninitialized: 255 case Expression::kUninitialized:
253 UNREACHABLE(); 256 UNREACHABLE();
254 case Expression::kEffect: 257 case Expression::kEffect:
255 __ Drop(1); 258 __ Drop(1);
256 break; 259 break;
257 case Expression::kValue: 260 case Expression::kValue:
258 break; 261 break;
259 case Expression::kTest: 262 case Expression::kTest:
260 __ pop(r0); 263 __ pop(r0);
261 TestAndBranch(r0, true_label_, false_label_); 264 TestAndBranch(r0, true_label_, false_label_);
262 break; 265 break;
263 case Expression::kValueTest: { 266 case Expression::kValueTest: {
264 Label discard; 267 Label discard;
265 __ ldr(r0, MemOperand(sp, 0)); 268 __ ldr(r0, MemOperand(sp, 0));
266 TestAndBranch(r0, true_label_, &discard); 269 TestAndBranch(r0, true_label_, &discard);
267 __ bind(&discard); 270 __ bind(&discard);
268 __ Drop(1); 271 __ Drop(1);
269 __ jmp(false_label_); 272 __ jmp(false_label_);
273 break;
274 }
275 case Expression::kTestValue: {
276 Label discard;
277 __ ldr(r0, MemOperand(sp, 0));
278 TestAndBranch(r0, &discard, false_label_);
279 __ bind(&discard);
280 __ Drop(1);
281 __ jmp(true_label_);
282 }
283 }
284 }
285
286
287 void FastCodeGenerator::DropAndApply(int count,
288 Expression::Context context,
289 Register reg) {
290 ASSERT(count > 0);
291 ASSERT(!reg.is(sp));
292 switch (context) {
293 case Expression::kUninitialized:
294 UNREACHABLE();
295 case Expression::kEffect:
296 __ Drop(count);
297 break;
298 case Expression::kValue:
299 if (count > 1) __ Drop(count - 1);
300 __ str(reg, MemOperand(sp));
301 break;
302 case Expression::kTest:
303 __ Drop(count);
304 TestAndBranch(reg, true_label_, false_label_);
305 break;
306 case Expression::kValueTest: {
307 Label discard;
308 if (count > 1) __ Drop(count - 1);
309 __ str(reg, MemOperand(sp));
310 TestAndBranch(reg, true_label_, &discard);
311 __ bind(&discard);
312 __ Drop(1);
313 __ jmp(false_label_);
270 break; 314 break;
271 } 315 }
272 case Expression::kTestValue: { 316 case Expression::kTestValue: {
273 Label discard; 317 Label discard;
274 __ ldr(r0, MemOperand(sp, 0)); 318 if (count > 1) __ Drop(count - 1);
275 TestAndBranch(r0, &discard, false_label_); 319 __ str(reg, MemOperand(sp));
320 TestAndBranch(reg, &discard, false_label_);
276 __ bind(&discard); 321 __ bind(&discard);
277 __ Drop(1); 322 __ Drop(1);
278 __ jmp(true_label_); 323 __ jmp(true_label_);
324 break;
279 } 325 }
280 } 326 }
281 } 327 }
282 328
283 329
284 MemOperand FastCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) { 330 MemOperand FastCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
285 switch (slot->type()) { 331 switch (slot->type()) {
286 case Slot::PARAMETER: 332 case Slot::PARAMETER:
287 case Slot::LOCAL: 333 case Slot::LOCAL:
288 return MemOperand(fp, SlotOffset(slot)); 334 return MemOperand(fp, SlotOffset(slot));
(...skipping 12 matching lines...) Expand all
301 347
302 348
303 void FastCodeGenerator::Move(Register destination, Slot* source) { 349 void FastCodeGenerator::Move(Register destination, Slot* source) {
304 // Use destination as scratch. 350 // Use destination as scratch.
305 MemOperand location = EmitSlotSearch(source, destination); 351 MemOperand location = EmitSlotSearch(source, destination);
306 __ ldr(destination, location); 352 __ ldr(destination, location);
307 } 353 }
308 354
309 355
310 356
311 void FastCodeGenerator::Move(Expression::Context context,
312 Slot* source,
313 Register scratch) {
314 switch (context) {
315 case Expression::kUninitialized:
316 UNREACHABLE();
317 case Expression::kEffect:
318 break;
319 case Expression::kValue:
320 case Expression::kTest:
321 case Expression::kValueTest:
322 case Expression::kTestValue:
323 Move(scratch, source);
324 Move(context, scratch);
325 break;
326 }
327 }
328
329
330 void FastCodeGenerator::Move(Expression::Context context, Literal* expr) {
331 switch (context) {
332 case Expression::kUninitialized:
333 UNREACHABLE();
334 case Expression::kEffect:
335 break;
336 case Expression::kValue:
337 case Expression::kTest:
338 case Expression::kValueTest:
339 case Expression::kTestValue:
340 __ mov(ip, Operand(expr->handle()));
341 Move(context, ip);
342 break;
343 }
344 }
345
346
347 void FastCodeGenerator::Move(Slot* dst, 357 void FastCodeGenerator::Move(Slot* dst,
348 Register src, 358 Register src,
349 Register scratch1, 359 Register scratch1,
350 Register scratch2) { 360 Register scratch2) {
351 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented. 361 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented.
352 ASSERT(!scratch1.is(src) && !scratch2.is(src)); 362 ASSERT(!scratch1.is(src) && !scratch2.is(src));
353 MemOperand location = EmitSlotSearch(dst, scratch1); 363 MemOperand location = EmitSlotSearch(dst, scratch1);
354 __ str(src, location); 364 __ str(src, location);
355 // Emit the write barrier code if the location is in the heap. 365 // Emit the write barrier code if the location is in the heap.
356 if (dst->type() == Slot::CONTEXT) { 366 if (dst->type() == Slot::CONTEXT) {
357 __ mov(scratch2, Operand(Context::SlotOffset(dst->index()))); 367 __ mov(scratch2, Operand(Context::SlotOffset(dst->index())));
358 __ RecordWrite(scratch1, scratch2, src); 368 __ RecordWrite(scratch1, scratch2, src);
359 } 369 }
360 } 370 }
361 371
362 372
363 373
364 void FastCodeGenerator::DropAndMove(Expression::Context context,
365 Register source,
366 int drop_count) {
367 ASSERT(drop_count > 0);
368 switch (context) {
369 case Expression::kUninitialized:
370 UNREACHABLE();
371 case Expression::kEffect:
372 __ add(sp, sp, Operand(drop_count * kPointerSize));
373 break;
374 case Expression::kValue:
375 if (drop_count > 1) {
376 __ add(sp, sp, Operand((drop_count - 1) * kPointerSize));
377 }
378 __ str(source, MemOperand(sp));
379 break;
380 case Expression::kTest:
381 ASSERT(!source.is(sp));
382 __ add(sp, sp, Operand(drop_count * kPointerSize));
383 TestAndBranch(source, true_label_, false_label_);
384 break;
385 case Expression::kValueTest: {
386 Label discard;
387 if (drop_count > 1) {
388 __ add(sp, sp, Operand((drop_count - 1) * kPointerSize));
389 }
390 __ str(source, MemOperand(sp));
391 TestAndBranch(source, true_label_, &discard);
392 __ bind(&discard);
393 __ pop();
394 __ jmp(false_label_);
395 break;
396 }
397 case Expression::kTestValue: {
398 Label discard;
399 if (drop_count > 1) {
400 __ add(sp, sp, Operand((drop_count - 1) * kPointerSize));
401 }
402 __ str(source, MemOperand(sp));
403 TestAndBranch(source, &discard, false_label_);
404 __ bind(&discard);
405 __ pop();
406 __ jmp(true_label_);
407 break;
408 }
409 }
410 }
411
412
413 void FastCodeGenerator::TestAndBranch(Register source, 374 void FastCodeGenerator::TestAndBranch(Register source,
414 Label* true_label, 375 Label* true_label,
415 Label* false_label) { 376 Label* false_label) {
416 ASSERT_NE(NULL, true_label); 377 ASSERT_NE(NULL, true_label);
417 ASSERT_NE(NULL, false_label); 378 ASSERT_NE(NULL, false_label);
418 // Call the runtime to find the boolean value of the source and then 379 // Call the runtime to find the boolean value of the source and then
419 // translate it into control flow to the pair of labels. 380 // translate it into control flow to the pair of labels.
420 __ push(source); 381 __ push(source);
421 __ CallRuntime(Runtime::kToBool, 1); 382 __ CallRuntime(Runtime::kToBool, 1);
422 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 383 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 __ pop(r0); 478 __ pop(r0);
518 } else { 479 } else {
519 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); 480 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
520 } 481 }
521 482
522 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 483 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
523 __ Call(ic, RelocInfo::CODE_TARGET); 484 __ Call(ic, RelocInfo::CODE_TARGET);
524 485
525 // Value in r0 is ignored (declarations are statements). Receiver 486 // Value in r0 is ignored (declarations are statements). Receiver
526 // and key on stack are discarded. 487 // and key on stack are discarded.
527 __ add(sp, sp, Operand(2 * kPointerSize)); 488 __ Drop(2);
528 } 489 }
529 } 490 }
530 } 491 }
531 492
532 493
533 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 494 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
534 // Call the runtime to declare the globals. 495 // Call the runtime to declare the globals.
535 // The context is the first argument. 496 // The context is the first argument.
536 __ mov(r1, Operand(pairs)); 497 __ mov(r1, Operand(pairs));
537 __ mov(r0, Operand(Smi::FromInt(is_eval_ ? 1 : 0))); 498 __ mov(r0, Operand(Smi::FromInt(is_eval_ ? 1 : 0)));
(...skipping 10 matching lines...) Expand all
548 Handle<JSFunction> boilerplate = 509 Handle<JSFunction> boilerplate =
549 Compiler::BuildBoilerplate(expr, script_, this); 510 Compiler::BuildBoilerplate(expr, script_, this);
550 if (HasStackOverflow()) return; 511 if (HasStackOverflow()) return;
551 512
552 ASSERT(boilerplate->IsBoilerplate()); 513 ASSERT(boilerplate->IsBoilerplate());
553 514
554 // Create a new closure. 515 // Create a new closure.
555 __ mov(r0, Operand(boilerplate)); 516 __ mov(r0, Operand(boilerplate));
556 __ stm(db_w, sp, cp.bit() | r0.bit()); 517 __ stm(db_w, sp, cp.bit() | r0.bit());
557 __ CallRuntime(Runtime::kNewClosure, 2); 518 __ CallRuntime(Runtime::kNewClosure, 2);
558 Move(expr->context(), r0); 519 Apply(expr->context(), r0);
559 } 520 }
560 521
561 522
562 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 523 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
563 Comment cmnt(masm_, "[ VariableProxy"); 524 Comment cmnt(masm_, "[ VariableProxy");
564 EmitVariableLoad(expr->var(), expr->context()); 525 EmitVariableLoad(expr->var(), expr->context());
565 } 526 }
566 527
567 528
568 void FastCodeGenerator::EmitVariableLoad(Variable* var, 529 void FastCodeGenerator::EmitVariableLoad(Variable* var,
569 Expression::Context context) { 530 Expression::Context context) {
570 Expression* rewrite = var->rewrite(); 531 Expression* rewrite = var->rewrite();
571 if (rewrite == NULL) { 532 if (rewrite == NULL) {
572 ASSERT(var->is_global()); 533 ASSERT(var->is_global());
573 Comment cmnt(masm_, "Global variable"); 534 Comment cmnt(masm_, "Global variable");
574 // Use inline caching. Variable name is passed in r2 and the global 535 // Use inline caching. Variable name is passed in r2 and the global
575 // object on the stack. 536 // object on the stack.
576 __ ldr(ip, CodeGenerator::GlobalObject()); 537 __ ldr(ip, CodeGenerator::GlobalObject());
577 __ push(ip); 538 __ push(ip);
578 __ mov(r2, Operand(var->name())); 539 __ mov(r2, Operand(var->name()));
579 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 540 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
580 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); 541 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
581 DropAndMove(context, r0); 542 DropAndApply(1, context, r0);
582 } else if (rewrite->AsSlot() != NULL) { 543 } else if (rewrite->AsSlot() != NULL) {
583 Slot* slot = rewrite->AsSlot(); 544 Slot* slot = rewrite->AsSlot();
584 if (FLAG_debug_code) { 545 if (FLAG_debug_code) {
585 switch (slot->type()) { 546 switch (slot->type()) {
586 case Slot::PARAMETER: 547 case Slot::PARAMETER:
587 case Slot::LOCAL: { 548 case Slot::LOCAL: {
588 Comment cmnt(masm_, "Stack slot"); 549 Comment cmnt(masm_, "Stack slot");
589 break; 550 break;
590 } 551 }
591 case Slot::CONTEXT: { 552 case Slot::CONTEXT: {
592 Comment cmnt(masm_, "Context slot"); 553 Comment cmnt(masm_, "Context slot");
593 break; 554 break;
594 } 555 }
595 case Slot::LOOKUP: 556 case Slot::LOOKUP:
596 UNIMPLEMENTED(); 557 UNIMPLEMENTED();
597 break; 558 break;
598 } 559 }
599 } 560 }
600 Move(context, slot, r0); 561 Apply(context, slot, r0);
601 } else { 562 } else {
602 // A variable has been rewritten into an explicit access to 563 Comment cmnt(masm_, "Variable rewritten to property");
603 // an object property. 564 // A variable has been rewritten into an explicit access to an object
565 // property.
604 Property* property = rewrite->AsProperty(); 566 Property* property = rewrite->AsProperty();
605 ASSERT_NOT_NULL(property); 567 ASSERT_NOT_NULL(property);
606 568
607 // Currently the only parameter expressions that can occur are 569 // The only property expressions that can occur are of the form
608 // on the form "slot[literal]". 570 // "slot[literal]".
609 571
610 // Check that the object is in a slot. 572 // Assert that the object is in a slot.
611 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); 573 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
612 ASSERT_NOT_NULL(object_var); 574 ASSERT_NOT_NULL(object_var);
613 Slot* object_slot = object_var->slot(); 575 Slot* object_slot = object_var->slot();
614 ASSERT_NOT_NULL(object_slot); 576 ASSERT_NOT_NULL(object_slot);
615 577
616 // Load the object. 578 // Load the object.
617 Move(r2, object_slot); 579 Move(r2, object_slot);
618 580
619 // Check that the key is a smi. 581 // Assert that the key is a smi.
620 Literal* key_literal = property->key()->AsLiteral(); 582 Literal* key_literal = property->key()->AsLiteral();
621 ASSERT_NOT_NULL(key_literal); 583 ASSERT_NOT_NULL(key_literal);
622 ASSERT(key_literal->handle()->IsSmi()); 584 ASSERT(key_literal->handle()->IsSmi());
623 585
624 // Load the key. 586 // Load the key.
625 __ mov(r1, Operand(key_literal->handle())); 587 __ mov(r1, Operand(key_literal->handle()));
626 588
627 // Push both as arguments to ic. 589 // Push both as arguments to ic.
628 __ stm(db_w, sp, r2.bit() | r1.bit()); 590 __ stm(db_w, sp, r2.bit() | r1.bit());
629 591
630 // Do a KEYED property load. 592 // Do a keyed property load.
631 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 593 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
632 __ Call(ic, RelocInfo::CODE_TARGET); 594 __ Call(ic, RelocInfo::CODE_TARGET);
633 595
634 // Drop key and object left on the stack by IC, and push the result. 596 // Drop key and object left on the stack by IC, and push the result.
635 DropAndMove(context, r0, 2); 597 DropAndApply(2, context, r0);
636 } 598 }
637 } 599 }
638 600
639 601
640 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 602 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
641 Comment cmnt(masm_, "[ RegExpLiteral"); 603 Comment cmnt(masm_, "[ RegExpLiteral");
642 Label done; 604 Label done;
643 // Registers will be used as follows: 605 // Registers will be used as follows:
644 // r4 = JS function, literals array 606 // r4 = JS function, literals array
645 // r3 = literal index 607 // r3 = literal index
646 // r2 = RegExp pattern 608 // r2 = RegExp pattern
647 // r1 = RegExp flags 609 // r1 = RegExp flags
648 // r0 = temp + return value (RegExp literal) 610 // r0 = temp + return value (RegExp literal)
649 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 611 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
650 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); 612 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
651 int literal_offset = 613 int literal_offset =
652 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 614 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
653 __ ldr(r0, FieldMemOperand(r4, literal_offset)); 615 __ ldr(r0, FieldMemOperand(r4, literal_offset));
654 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 616 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
655 __ cmp(r0, ip); 617 __ cmp(r0, ip);
656 __ b(ne, &done); 618 __ b(ne, &done);
657 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); 619 __ mov(r3, Operand(Smi::FromInt(expr->literal_index())));
658 __ mov(r2, Operand(expr->pattern())); 620 __ mov(r2, Operand(expr->pattern()));
659 __ mov(r1, Operand(expr->flags())); 621 __ mov(r1, Operand(expr->flags()));
660 __ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit()); 622 __ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit());
661 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 623 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
662 __ bind(&done); 624 __ bind(&done);
663 Move(expr->context(), r0); 625 Apply(expr->context(), r0);
664 } 626 }
665 627
666 628
667 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 629 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
668 Comment cmnt(masm_, "[ ObjectLiteral"); 630 Comment cmnt(masm_, "[ ObjectLiteral");
669 __ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 631 __ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
670 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset)); 632 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset));
671 __ mov(r1, Operand(Smi::FromInt(expr->literal_index()))); 633 __ mov(r1, Operand(Smi::FromInt(expr->literal_index())));
672 __ mov(r0, Operand(expr->constant_properties())); 634 __ mov(r0, Operand(expr->constant_properties()));
673 __ stm(db_w, sp, r2.bit() | r1.bit() | r0.bit()); 635 __ stm(db_w, sp, r2.bit() | r1.bit() | r0.bit());
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 ASSERT_EQ(Expression::kValue, value->context()); 697 ASSERT_EQ(Expression::kValue, value->context());
736 __ CallRuntime(Runtime::kDefineAccessor, 4); 698 __ CallRuntime(Runtime::kDefineAccessor, 4);
737 __ ldr(r0, MemOperand(sp)); // Restore result into r0 699 __ ldr(r0, MemOperand(sp)); // Restore result into r0
738 break; 700 break;
739 } 701 }
740 } 702 }
741 switch (expr->context()) { 703 switch (expr->context()) {
742 case Expression::kUninitialized: 704 case Expression::kUninitialized:
743 UNREACHABLE(); 705 UNREACHABLE();
744 case Expression::kEffect: 706 case Expression::kEffect:
745 if (result_saved) __ pop(); 707 if (result_saved) __ Drop(1);
746 break; 708 break;
747 case Expression::kValue: 709 case Expression::kValue:
748 if (!result_saved) __ push(r0); 710 if (!result_saved) __ push(r0);
749 break; 711 break;
750 case Expression::kTest: 712 case Expression::kTest:
751 if (result_saved) __ pop(r0); 713 if (result_saved) __ pop(r0);
752 TestAndBranch(r0, true_label_, false_label_); 714 TestAndBranch(r0, true_label_, false_label_);
753 break; 715 break;
754 case Expression::kValueTest: { 716 case Expression::kValueTest: {
755 Label discard; 717 Label discard;
756 if (!result_saved) __ push(r0); 718 if (!result_saved) __ push(r0);
757 TestAndBranch(r0, true_label_, &discard); 719 TestAndBranch(r0, true_label_, &discard);
758 __ bind(&discard); 720 __ bind(&discard);
759 __ pop(); 721 __ Drop(1);
760 __ jmp(false_label_); 722 __ jmp(false_label_);
761 break; 723 break;
762 } 724 }
763 case Expression::kTestValue: { 725 case Expression::kTestValue: {
764 Label discard; 726 Label discard;
765 if (!result_saved) __ push(r0); 727 if (!result_saved) __ push(r0);
766 TestAndBranch(r0, &discard, false_label_); 728 TestAndBranch(r0, &discard, false_label_);
767 __ bind(&discard); 729 __ bind(&discard);
768 __ pop(); 730 __ Drop(1);
769 __ jmp(true_label_); 731 __ jmp(true_label_);
770 break; 732 break;
771 } 733 }
772 } 734 }
773 } 735 }
774 736
775 737
776 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 738 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
777 Comment cmnt(masm_, "[ ArrayLiteral"); 739 Comment cmnt(masm_, "[ ArrayLiteral");
778 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 740 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset)); 775 __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset));
814 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 776 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
815 __ str(r0, FieldMemOperand(r1, offset)); 777 __ str(r0, FieldMemOperand(r1, offset));
816 778
817 // Update the write barrier for the array store with r0 as the scratch 779 // Update the write barrier for the array store with r0 as the scratch
818 // register. 780 // register.
819 __ mov(r2, Operand(offset)); 781 __ mov(r2, Operand(offset));
820 __ RecordWrite(r1, r2, r0); 782 __ RecordWrite(r1, r2, r0);
821 } 783 }
822 784
823 switch (expr->context()) { 785 switch (expr->context()) {
Lasse Reichstein 2010/01/12 08:30:05 This switch is identical to the one at line 703. C
824 case Expression::kUninitialized: 786 case Expression::kUninitialized:
825 UNREACHABLE(); 787 UNREACHABLE();
826 case Expression::kEffect: 788 case Expression::kEffect:
827 if (result_saved) __ pop(); 789 if (result_saved) __ Drop(1);
828 break; 790 break;
829 case Expression::kValue: 791 case Expression::kValue:
830 if (!result_saved) __ push(r0); 792 if (!result_saved) __ push(r0);
831 break; 793 break;
832 case Expression::kTest: 794 case Expression::kTest:
833 if (result_saved) __ pop(r0); 795 if (result_saved) __ pop(r0);
834 TestAndBranch(r0, true_label_, false_label_); 796 TestAndBranch(r0, true_label_, false_label_);
835 break; 797 break;
836 case Expression::kValueTest: { 798 case Expression::kValueTest: {
837 Label discard; 799 Label discard;
838 if (!result_saved) __ push(r0); 800 if (!result_saved) __ push(r0);
839 TestAndBranch(r0, true_label_, &discard); 801 TestAndBranch(r0, true_label_, &discard);
840 __ bind(&discard); 802 __ bind(&discard);
841 __ pop(); 803 __ Drop(1);
842 __ jmp(false_label_); 804 __ jmp(false_label_);
843 break; 805 break;
844 } 806 }
845 case Expression::kTestValue: { 807 case Expression::kTestValue: {
846 Label discard; 808 Label discard;
847 if (!result_saved) __ push(r0); 809 if (!result_saved) __ push(r0);
848 TestAndBranch(r0, &discard, false_label_); 810 TestAndBranch(r0, &discard, false_label_);
849 __ bind(&discard); 811 __ bind(&discard);
850 __ pop(); 812 __ Drop(1);
851 __ jmp(true_label_); 813 __ jmp(true_label_);
852 break; 814 break;
853 } 815 }
854 } 816 }
855 } 817 }
856 818
857 819
858 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop, 820 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop,
859 Expression::Context context) { 821 Expression::Context context) {
860 SetSourcePosition(prop->position()); 822 SetSourcePosition(prop->position());
861 Literal* key = prop->key()->AsLiteral(); 823 Literal* key = prop->key()->AsLiteral();
862 __ mov(r2, Operand(key->handle())); 824 __ mov(r2, Operand(key->handle()));
863 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 825 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
864 __ Call(ic, RelocInfo::CODE_TARGET); 826 __ Call(ic, RelocInfo::CODE_TARGET);
865 Move(context, r0); 827 Apply(context, r0);
866 } 828 }
867 829
868 830
869 void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop, 831 void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop,
870 Expression::Context context) { 832 Expression::Context context) {
871 SetSourcePosition(prop->position()); 833 SetSourcePosition(prop->position());
872 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 834 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
873 __ Call(ic, RelocInfo::CODE_TARGET); 835 __ Call(ic, RelocInfo::CODE_TARGET);
874 Move(context, r0); 836 Apply(context, r0);
875 } 837 }
876 838
877 839
878 void FastCodeGenerator::EmitCompoundAssignmentOp(Token::Value op, 840 void FastCodeGenerator::EmitCompoundAssignmentOp(Token::Value op,
879 Expression::Context context) { 841 Expression::Context context) {
880 __ pop(r0); 842 __ pop(r0);
881 __ pop(r1); 843 __ pop(r1);
882 GenericBinaryOpStub stub(op, 844 GenericBinaryOpStub stub(op,
883 NO_OVERWRITE); 845 NO_OVERWRITE);
884 __ CallStub(&stub); 846 __ CallStub(&stub);
885 Move(context, r0); 847 Apply(context, r0);
886 } 848 }
887 849
888 850
889 void FastCodeGenerator::EmitVariableAssignment(Variable* var, 851 void FastCodeGenerator::EmitVariableAssignment(Variable* var,
890 Expression::Context context) { 852 Expression::Context context) {
891 ASSERT(var != NULL); 853 ASSERT(var != NULL);
892 ASSERT(var->is_global() || var->slot() != NULL); 854 ASSERT(var->is_global() || var->slot() != NULL);
893 if (var->is_global()) { 855 if (var->is_global()) {
894 // Assignment to a global variable. Use inline caching for the 856 // Assignment to a global variable. Use inline caching for the
895 // assignment. Right-hand-side value is passed in r0, variable name in 857 // assignment. Right-hand-side value is passed in r0, variable name in
896 // r2, and the global object on the stack. 858 // r2, and the global object on the stack.
897 __ pop(r0); 859 __ pop(r0);
898 __ mov(r2, Operand(var->name())); 860 __ mov(r2, Operand(var->name()));
899 __ ldr(ip, CodeGenerator::GlobalObject()); 861 __ ldr(ip, CodeGenerator::GlobalObject());
900 __ push(ip); 862 __ push(ip);
901 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 863 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
902 __ Call(ic, RelocInfo::CODE_TARGET); 864 __ Call(ic, RelocInfo::CODE_TARGET);
903 // Overwrite the global object on the stack with the result if needed. 865 // Overwrite the global object on the stack with the result if needed.
904 DropAndMove(context, r0); 866 DropAndApply(1, context, r0);
905 867
906 } else if (var->slot() != NULL) { 868 } else if (var->slot() != NULL) {
907 Slot* slot = var->slot(); 869 Slot* slot = var->slot();
908 switch (slot->type()) { 870 switch (slot->type()) {
909 case Slot::LOCAL: 871 case Slot::LOCAL:
910 case Slot::PARAMETER: { 872 case Slot::PARAMETER: {
911 MemOperand target = MemOperand(fp, SlotOffset(slot)); 873 MemOperand target = MemOperand(fp, SlotOffset(slot));
912 switch (context) { 874 switch (context) {
913 case Expression::kUninitialized: 875 case Expression::kUninitialized:
914 UNREACHABLE(); 876 UNREACHABLE();
(...skipping 12 matching lines...) Expand all
927 __ pop(r0); 889 __ pop(r0);
928 __ str(r0, target); 890 __ str(r0, target);
929 TestAndBranch(r0, true_label_, false_label_); 891 TestAndBranch(r0, true_label_, false_label_);
930 break; 892 break;
931 case Expression::kValueTest: { 893 case Expression::kValueTest: {
932 Label discard; 894 Label discard;
933 __ ldr(r0, MemOperand(sp)); 895 __ ldr(r0, MemOperand(sp));
934 __ str(r0, target); 896 __ str(r0, target);
935 TestAndBranch(r0, true_label_, &discard); 897 TestAndBranch(r0, true_label_, &discard);
936 __ bind(&discard); 898 __ bind(&discard);
937 __ pop(); 899 __ Drop(1);
938 __ jmp(false_label_); 900 __ jmp(false_label_);
939 break; 901 break;
940 } 902 }
941 case Expression::kTestValue: { 903 case Expression::kTestValue: {
942 Label discard; 904 Label discard;
943 __ ldr(r0, MemOperand(sp)); 905 __ ldr(r0, MemOperand(sp));
944 __ str(r0, target); 906 __ str(r0, target);
945 TestAndBranch(r0, &discard, false_label_); 907 TestAndBranch(r0, &discard, false_label_);
946 __ bind(&discard); 908 __ bind(&discard);
947 __ pop(); 909 __ Drop(1);
948 __ jmp(true_label_); 910 __ jmp(true_label_);
949 break; 911 break;
950 } 912 }
951 } 913 }
952 break; 914 break;
953 } 915 }
954 916
955 case Slot::CONTEXT: { 917 case Slot::CONTEXT: {
956 MemOperand target = EmitSlotSearch(slot, r1); 918 MemOperand target = EmitSlotSearch(slot, r1);
957 __ pop(r0); 919 __ pop(r0);
(...skipping 11 matching lines...) Expand all
969 // register. Skip the write barrier if the value written (r1) is a smi. 931 // register. Skip the write barrier if the value written (r1) is a smi.
970 // The smi test is part of RecordWrite on other platforms, not on arm. 932 // The smi test is part of RecordWrite on other platforms, not on arm.
971 Label exit; 933 Label exit;
972 __ tst(r0, Operand(kSmiTagMask)); 934 __ tst(r0, Operand(kSmiTagMask));
973 __ b(eq, &exit); 935 __ b(eq, &exit);
974 936
975 __ mov(r2, Operand(offset)); 937 __ mov(r2, Operand(offset));
976 __ RecordWrite(r1, r2, r0); 938 __ RecordWrite(r1, r2, r0);
977 __ bind(&exit); 939 __ bind(&exit);
978 if (context != Expression::kEffect && context != Expression::kValue) { 940 if (context != Expression::kEffect && context != Expression::kValue) {
979 Move(context, r3); 941 Apply(context, r3);
980 } 942 }
981 break; 943 break;
982 } 944 }
983 945
984 case Slot::LOOKUP: 946 case Slot::LOOKUP:
985 UNREACHABLE(); 947 UNREACHABLE();
986 break; 948 break;
987 } 949 }
988 } else { 950 } else {
989 // Variables rewritten as properties are not treated as variables in 951 // Variables rewritten as properties are not treated as variables in
(...skipping 25 matching lines...) Expand all
1015 977
1016 // If the assignment ends an initialization block, revert to fast case. 978 // If the assignment ends an initialization block, revert to fast case.
1017 if (expr->ends_initialization_block()) { 979 if (expr->ends_initialization_block()) {
1018 __ push(r0); // Result of assignment, saved even if not needed. 980 __ push(r0); // Result of assignment, saved even if not needed.
1019 __ ldr(ip, MemOperand(sp, kPointerSize)); // Receiver is under value. 981 __ ldr(ip, MemOperand(sp, kPointerSize)); // Receiver is under value.
1020 __ push(ip); 982 __ push(ip);
1021 __ CallRuntime(Runtime::kToFastProperties, 1); 983 __ CallRuntime(Runtime::kToFastProperties, 1);
1022 __ pop(r0); 984 __ pop(r0);
1023 } 985 }
1024 986
1025 DropAndMove(expr->context(), r0); 987 DropAndApply(1, expr->context(), r0);
1026 } 988 }
1027 989
1028 990
1029 void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 991 void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
1030 // Assignment to a property, using a keyed store IC. 992 // Assignment to a property, using a keyed store IC.
1031 993
1032 // If the assignment starts a block of assignments to the same object, 994 // If the assignment starts a block of assignments to the same object,
1033 // change to slow case to avoid the quadratic behavior of repeatedly 995 // change to slow case to avoid the quadratic behavior of repeatedly
1034 // adding fast properties. 996 // adding fast properties.
1035 if (expr->starts_initialization_block()) { 997 if (expr->starts_initialization_block()) {
(...skipping 11 matching lines...) Expand all
1047 if (expr->ends_initialization_block()) { 1009 if (expr->ends_initialization_block()) {
1048 __ push(r0); // Result of assignment, saved even if not needed. 1010 __ push(r0); // Result of assignment, saved even if not needed.
1049 // Reciever is under the key and value. 1011 // Reciever is under the key and value.
1050 __ ldr(ip, MemOperand(sp, 2 * kPointerSize)); 1012 __ ldr(ip, MemOperand(sp, 2 * kPointerSize));
1051 __ push(ip); 1013 __ push(ip);
1052 __ CallRuntime(Runtime::kToFastProperties, 1); 1014 __ CallRuntime(Runtime::kToFastProperties, 1);
1053 __ pop(r0); 1015 __ pop(r0);
1054 } 1016 }
1055 1017
1056 // Receiver and key are still on stack. 1018 // Receiver and key are still on stack.
1057 __ add(sp, sp, Operand(2 * kPointerSize)); 1019 DropAndApply(2, expr->context(), r0);
1058 Move(expr->context(), r0);
1059 } 1020 }
1060 1021
1061 1022
1062 void FastCodeGenerator::VisitProperty(Property* expr) { 1023 void FastCodeGenerator::VisitProperty(Property* expr) {
1063 Comment cmnt(masm_, "[ Property"); 1024 Comment cmnt(masm_, "[ Property");
1064 Expression* key = expr->key(); 1025 Expression* key = expr->key();
1065 uint32_t dummy;
1066 1026
1067 // Record the source position for the property load. 1027 // Record the source position for the property load.
1068 SetSourcePosition(expr->position()); 1028 SetSourcePosition(expr->position());
1069 1029
1070 // Evaluate receiver. 1030 // Evaluate receiver.
1071 Visit(expr->obj()); 1031 Visit(expr->obj());
1072 1032
1073 if (key->AsLiteral() != NULL && key->AsLiteral()->handle()->IsSymbol() && 1033 if (key->IsPropertyName()) {
1074 !String::cast(*(key->AsLiteral()->handle()))->AsArrayIndex(&dummy)) { 1034 // Do a named property load. The IC expects the property name in r2 and
1075 // Do a NAMED property load. 1035 // the receiver on the stack.
1076 // The IC expects the property name in r2 and the receiver on the stack.
1077 __ mov(r2, Operand(key->AsLiteral()->handle())); 1036 __ mov(r2, Operand(key->AsLiteral()->handle()));
1078 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1037 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1079 __ Call(ic, RelocInfo::CODE_TARGET); 1038 __ Call(ic, RelocInfo::CODE_TARGET);
1039 DropAndApply(1, expr->context(), r0);
1080 } else { 1040 } else {
1081 // Do a KEYED property load. 1041 // Do a keyed property load.
1082 Visit(expr->key()); 1042 Visit(expr->key());
1083 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1043 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1084 __ Call(ic, RelocInfo::CODE_TARGET); 1044 __ Call(ic, RelocInfo::CODE_TARGET);
1085 // Drop key and receiver left on the stack by IC. 1045 // Drop key and receiver left on the stack by IC.
1086 __ pop(); 1046 DropAndApply(2, expr->context(), r0);
1087 } 1047 }
1088 DropAndMove(expr->context(), r0);
1089 } 1048 }
1090 1049
1091 void FastCodeGenerator::EmitCallWithIC(Call* expr, 1050 void FastCodeGenerator::EmitCallWithIC(Call* expr,
1092 Handle<Object> ignored, 1051 Handle<Object> ignored,
1093 RelocInfo::Mode mode) { 1052 RelocInfo::Mode mode) {
1094 // Code common for calls using the IC. 1053 // Code common for calls using the IC.
1095 ZoneList<Expression*>* args = expr->arguments(); 1054 ZoneList<Expression*>* args = expr->arguments();
1096 int arg_count = args->length(); 1055 int arg_count = args->length();
1097 for (int i = 0; i < arg_count; i++) { 1056 for (int i = 0; i < arg_count; i++) {
1098 Visit(args->at(i)); 1057 Visit(args->at(i));
1099 ASSERT_EQ(Expression::kValue, args->at(i)->context()); 1058 ASSERT_EQ(Expression::kValue, args->at(i)->context());
1100 } 1059 }
1101 // Record source position for debugger. 1060 // Record source position for debugger.
1102 SetSourcePosition(expr->position()); 1061 SetSourcePosition(expr->position());
1103 // Call the IC initialization code. 1062 // Call the IC initialization code.
1104 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 1063 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
1105 NOT_IN_LOOP); 1064 NOT_IN_LOOP);
1106 __ Call(ic, mode); 1065 __ Call(ic, mode);
1107 // Restore context register. 1066 // Restore context register.
1108 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1067 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1109 // Discard the function left on TOS. 1068 // Discard the function left on TOS.
1110 DropAndMove(expr->context(), r0); 1069 DropAndApply(1, expr->context(), r0);
1111 } 1070 }
1112 1071
1113 1072
1114 void FastCodeGenerator::EmitCallWithStub(Call* expr) { 1073 void FastCodeGenerator::EmitCallWithStub(Call* expr) {
1115 // Code common for calls using the call stub. 1074 // Code common for calls using the call stub.
1116 ZoneList<Expression*>* args = expr->arguments(); 1075 ZoneList<Expression*>* args = expr->arguments();
1117 int arg_count = args->length(); 1076 int arg_count = args->length();
1118 for (int i = 0; i < arg_count; i++) { 1077 for (int i = 0; i < arg_count; i++) {
1119 Visit(args->at(i)); 1078 Visit(args->at(i));
1120 } 1079 }
1121 // Record source position for debugger. 1080 // Record source position for debugger.
1122 SetSourcePosition(expr->position()); 1081 SetSourcePosition(expr->position());
1123 CallFunctionStub stub(arg_count, NOT_IN_LOOP); 1082 CallFunctionStub stub(arg_count, NOT_IN_LOOP);
1124 __ CallStub(&stub); 1083 __ CallStub(&stub);
1125 // Restore context register. 1084 // Restore context register.
1126 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1085 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1127 // Discard the function left on TOS. 1086 // Discard the function left on TOS.
1128 DropAndMove(expr->context(), r0); 1087 DropAndApply(1, expr->context(), r0);
1129 } 1088 }
1130 1089
1131 1090
1132 void FastCodeGenerator::VisitCall(Call* expr) { 1091 void FastCodeGenerator::VisitCall(Call* expr) {
1133 Comment cmnt(masm_, "[ Call"); 1092 Comment cmnt(masm_, "[ Call");
1134 Expression* fun = expr->expression(); 1093 Expression* fun = expr->expression();
1135 Variable* var = fun->AsVariableProxy()->AsVariable(); 1094 Variable* var = fun->AsVariableProxy()->AsVariable();
1136 1095
1137 if (var != NULL && var->is_possibly_eval()) { 1096 if (var != NULL && var->is_possibly_eval()) {
1138 // Call to the identifier 'eval'. 1097 // Call to the identifier 'eval'.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 1186
1228 // Load function, arg_count into r1 and r0. 1187 // Load function, arg_count into r1 and r0.
1229 __ mov(r0, Operand(arg_count)); 1188 __ mov(r0, Operand(arg_count));
1230 // Function is in sp[arg_count + 1]. 1189 // Function is in sp[arg_count + 1].
1231 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 1190 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
1232 1191
1233 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); 1192 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall));
1234 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 1193 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
1235 1194
1236 // Replace function on TOS with result in r0, or pop it. 1195 // Replace function on TOS with result in r0, or pop it.
1237 DropAndMove(expr->context(), r0); 1196 DropAndApply(1, expr->context(), r0);
1238 } 1197 }
1239 1198
1240 1199
1241 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 1200 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
1242 Comment cmnt(masm_, "[ CallRuntime"); 1201 Comment cmnt(masm_, "[ CallRuntime");
1243 ZoneList<Expression*>* args = expr->arguments(); 1202 ZoneList<Expression*>* args = expr->arguments();
1244 1203
1245 if (expr->is_jsruntime()) { 1204 if (expr->is_jsruntime()) {
1246 // Prepare for calling JS runtime function. 1205 // Prepare for calling JS runtime function.
1247 __ mov(r1, Operand(expr->name())); 1206 __ mov(r1, Operand(expr->name()));
(...skipping 10 matching lines...) Expand all
1258 } 1217 }
1259 1218
1260 if (expr->is_jsruntime()) { 1219 if (expr->is_jsruntime()) {
1261 // Call the JS runtime function. 1220 // Call the JS runtime function.
1262 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 1221 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
1263 NOT_IN_LOOP); 1222 NOT_IN_LOOP);
1264 __ Call(ic, RelocInfo::CODE_TARGET); 1223 __ Call(ic, RelocInfo::CODE_TARGET);
1265 // Restore context register. 1224 // Restore context register.
1266 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1225 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1267 // Discard the function left on TOS. 1226 // Discard the function left on TOS.
1268 DropAndMove(expr->context(), r0); 1227 DropAndApply(1, expr->context(), r0);
1269 } else { 1228 } else {
1270 // Call the C runtime function. 1229 // Call the C runtime function.
1271 __ CallRuntime(expr->function(), arg_count); 1230 __ CallRuntime(expr->function(), arg_count);
1272 Move(expr->context(), r0); 1231 Apply(expr->context(), r0);
1273 } 1232 }
1274 } 1233 }
1275 1234
1276 1235
1277 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 1236 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
1278 switch (expr->op()) { 1237 switch (expr->op()) {
1279 case Token::VOID: { 1238 case Token::VOID: {
1280 Comment cmnt(masm_, "[ UnaryOperation (VOID)"); 1239 Comment cmnt(masm_, "[ UnaryOperation (VOID)");
1281 Visit(expr->expression()); 1240 Visit(expr->expression());
1282 ASSERT_EQ(Expression::kEffect, expr->expression()->context()); 1241 ASSERT_EQ(Expression::kEffect, expr->expression()->context());
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 __ mov(r0, Operand(proxy->name())); 1350 __ mov(r0, Operand(proxy->name()));
1392 __ stm(db_w, sp, cp.bit() | r0.bit()); 1351 __ stm(db_w, sp, cp.bit() | r0.bit());
1393 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); 1352 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
1394 __ push(r0); 1353 __ push(r0);
1395 } else { 1354 } else {
1396 // This expression cannot throw a reference error at the top level. 1355 // This expression cannot throw a reference error at the top level.
1397 Visit(expr->expression()); 1356 Visit(expr->expression());
1398 } 1357 }
1399 1358
1400 __ CallRuntime(Runtime::kTypeof, 1); 1359 __ CallRuntime(Runtime::kTypeof, 1);
1401 Move(expr->context(), r0); 1360 Apply(expr->context(), r0);
1402 break; 1361 break;
1403 } 1362 }
1404 1363
1405 default: 1364 default:
1406 UNREACHABLE(); 1365 UNREACHABLE();
1407 } 1366 }
1408 } 1367 }
1409 1368
1410 1369
1411 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { 1370 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1492 // Store the value returned in r0. 1451 // Store the value returned in r0.
1493 switch (assign_type) { 1452 switch (assign_type) {
1494 case VARIABLE: 1453 case VARIABLE:
1495 __ push(r0); 1454 __ push(r0);
1496 if (expr->is_postfix()) { 1455 if (expr->is_postfix()) {
1497 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 1456 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
1498 Expression::kEffect); 1457 Expression::kEffect);
1499 // For all contexts except kEffect: We have the result on 1458 // For all contexts except kEffect: We have the result on
1500 // top of the stack. 1459 // top of the stack.
1501 if (expr->context() != Expression::kEffect) { 1460 if (expr->context() != Expression::kEffect) {
1502 MoveTOS(expr->context()); 1461 ApplyTOS(expr->context());
1503 } 1462 }
1504 } else { 1463 } else {
1505 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 1464 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
1506 expr->context()); 1465 expr->context());
1507 } 1466 }
1508 break; 1467 break;
1509 case NAMED_PROPERTY: { 1468 case NAMED_PROPERTY: {
1510 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); 1469 __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
1511 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1470 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1512 __ Call(ic, RelocInfo::CODE_TARGET); 1471 __ Call(ic, RelocInfo::CODE_TARGET);
1513 if (expr->is_postfix()) { 1472 if (expr->is_postfix()) {
1514 __ Drop(1); // Result is on the stack under the receiver. 1473 __ Drop(1); // Result is on the stack under the receiver.
1515 if (expr->context() != Expression::kEffect) { 1474 if (expr->context() != Expression::kEffect) {
1516 MoveTOS(expr->context()); 1475 ApplyTOS(expr->context());
1517 } 1476 }
1518 } else { 1477 } else {
1519 DropAndMove(expr->context(), r0); 1478 DropAndApply(1, expr->context(), r0);
1520 } 1479 }
1521 break; 1480 break;
1522 } 1481 }
1523 case KEYED_PROPERTY: { 1482 case KEYED_PROPERTY: {
1524 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 1483 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
1525 __ Call(ic, RelocInfo::CODE_TARGET); 1484 __ Call(ic, RelocInfo::CODE_TARGET);
1526 if (expr->is_postfix()) { 1485 if (expr->is_postfix()) {
1527 __ Drop(2); // Result is on the stack under the key and the receiver. 1486 __ Drop(2); // Result is on the stack under the key and the receiver.
1528 if (expr->context() != Expression::kEffect) { 1487 if (expr->context() != Expression::kEffect) {
1529 MoveTOS(expr->context()); 1488 ApplyTOS(expr->context());
1530 } 1489 }
1531 } else { 1490 } else {
1532 DropAndMove(expr->context(), r0, 2); 1491 DropAndApply(2, expr->context(), r0);
1533 } 1492 }
1534 break; 1493 break;
1535 } 1494 }
1536 } 1495 }
1537 } 1496 }
1538 1497
1539 1498
1540 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 1499 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
1541 Comment cmnt(masm_, "[ BinaryOperation"); 1500 Comment cmnt(masm_, "[ BinaryOperation");
1542 switch (expr->op()) { 1501 switch (expr->op()) {
(...skipping 23 matching lines...) Expand all
1566 ASSERT_EQ(Expression::kValue, expr->left()->context()); 1525 ASSERT_EQ(Expression::kValue, expr->left()->context());
1567 ASSERT_EQ(Expression::kValue, expr->right()->context()); 1526 ASSERT_EQ(Expression::kValue, expr->right()->context());
1568 1527
1569 Visit(expr->left()); 1528 Visit(expr->left());
1570 Visit(expr->right()); 1529 Visit(expr->right());
1571 __ pop(r0); 1530 __ pop(r0);
1572 __ pop(r1); 1531 __ pop(r1);
1573 GenericBinaryOpStub stub(expr->op(), 1532 GenericBinaryOpStub stub(expr->op(),
1574 NO_OVERWRITE); 1533 NO_OVERWRITE);
1575 __ CallStub(&stub); 1534 __ CallStub(&stub);
1576 Move(expr->context(), r0); 1535 Apply(expr->context(), r0);
1577 1536
1578 break; 1537 break;
1579 } 1538 }
1580 default: 1539 default:
1581 UNREACHABLE(); 1540 UNREACHABLE();
1582 } 1541 }
1583 } 1542 }
1584 1543
1585 1544
1586 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 1545 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1741 break; 1700 break;
1742 } 1701 }
1743 true_label_ = saved_true; 1702 true_label_ = saved_true;
1744 false_label_ = saved_false; 1703 false_label_ = saved_false;
1745 // Convert current context to test context: End post-test code. 1704 // Convert current context to test context: End post-test code.
1746 } 1705 }
1747 1706
1748 1707
1749 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { 1708 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
1750 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1709 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1751 Move(expr->context(), r0); 1710 Apply(expr->context(), r0);
1752 } 1711 }
1753 1712
1754 1713
1755 Register FastCodeGenerator::result_register() { return r0; } 1714 Register FastCodeGenerator::result_register() { return r0; }
1756 1715
1757 1716
1758 Register FastCodeGenerator::context_register() { return cp; } 1717 Register FastCodeGenerator::context_register() { return cp; }
1759 1718
1760 1719
1761 void FastCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 1720 void FastCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1793 __ pop(result_register()); 1752 __ pop(result_register());
1794 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); 1753 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
1795 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 1754 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
1796 __ add(pc, r1, Operand(masm_->CodeObject())); 1755 __ add(pc, r1, Operand(masm_->CodeObject()));
1797 } 1756 }
1798 1757
1799 1758
1800 #undef __ 1759 #undef __
1801 1760
1802 } } // namespace v8::internal 1761 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698