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

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

Issue 342073: Refactor the somewhat complicated code generation for assignments into... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 1 month 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 | « no previous file | src/compiler.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 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 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 // r0 contains boilerplate. 373 // r0 contains boilerplate.
374 // Clone boilerplate. 374 // Clone boilerplate.
375 __ push(r0); 375 __ push(r0);
376 if (expr->depth() > 1) { 376 if (expr->depth() > 1) {
377 __ CallRuntime(Runtime::kCloneLiteralBoilerplate, 1); 377 __ CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
378 } else { 378 } else {
379 __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1); 379 __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1);
380 } 380 }
381 381
382 // If result_saved == true: the result is saved on top of the stack. 382 // If result_saved == true: the result is saved on top of the stack.
383 // If result_saved == false: the result is in eax. 383 // If result_saved == false: the result is in r0.
384 bool result_saved = false; 384 bool result_saved = false;
385 385
386 for (int i = 0; i < expr->properties()->length(); i++) { 386 for (int i = 0; i < expr->properties()->length(); i++) {
387 ObjectLiteral::Property* property = expr->properties()->at(i); 387 ObjectLiteral::Property* property = expr->properties()->at(i);
388 if (property->IsCompileTimeValue()) continue; 388 if (property->IsCompileTimeValue()) continue;
389 389
390 Literal* key = property->key(); 390 Literal* key = property->key();
391 Expression* value = property->value(); 391 Expression* value = property->value();
392 if (!result_saved) { 392 if (!result_saved) {
393 __ push(r0); // Save result on stack 393 __ push(r0); // Save result on stack
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 TestAndBranch(r0, &discard, false_label_); 565 TestAndBranch(r0, &discard, false_label_);
566 __ bind(&discard); 566 __ bind(&discard);
567 __ pop(); 567 __ pop();
568 __ jmp(true_label_); 568 __ jmp(true_label_);
569 break; 569 break;
570 } 570 }
571 } 571 }
572 } 572 }
573 573
574 574
575 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 575 void FastCodeGenerator::EmitVariableAssignment(Expression::Context context,
576 Comment cmnt(masm_, "[ Assignment"); 576 Variable* var) {
577 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); 577 if (var->is_global()) {
578
579 // Record the source position for the assignment.
580 SetSourcePosition(expr->position());
581
582 // Left-hand side can only be a property, a global or
583 // a (parameter or local) slot.
584 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
585 Expression* rhs = expr->value();
586 if (var == NULL) {
587 // Assignment to a property.
588 ASSERT(expr->target()->AsProperty() != NULL);
589 Property* prop = expr->target()->AsProperty();
590 Visit(prop->obj());
591 Literal* literal_key = prop->key()->AsLiteral();
592 uint32_t dummy;
593 if (literal_key != NULL &&
594 literal_key->handle()->IsSymbol() &&
595 !String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) {
596 // NAMED property assignment
597 Visit(rhs);
598 ASSERT_EQ(Expression::kValue, rhs->context());
599 __ pop(r0);
600 __ mov(r2, Operand(literal_key->handle()));
601 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
602 __ Call(ic, RelocInfo::CODE_TARGET);
603 } else {
604 // KEYED property assignment
605 Visit(prop->key());
606 Visit(rhs);
607 ASSERT_EQ(Expression::kValue, rhs->context());
608 __ pop(r0);
609 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
610 __ Call(ic, RelocInfo::CODE_TARGET);
611 // Drop key from the stack
612 __ pop();
613 }
614 // Overwrite the receiver on the stack with the result if needed.
615 DropAndMove(expr->context(), r0);
616 } else if (var->is_global()) {
617 // Assignment to a global variable, use inline caching. Right-hand-side 578 // Assignment to a global variable, use inline caching. Right-hand-side
618 // value is passed in r0, variable name in r2, and the global object on 579 // value is passed in r0, variable name in r2, and the global object
619 // the stack. 580 // on the stack.
620 581 __ pop(r0);
621 // Code for the right-hand-side expression depends on its type.
622 if (rhs->AsLiteral() != NULL) {
623 __ mov(r0, Operand(rhs->AsLiteral()->handle()));
624 } else {
625 ASSERT_EQ(Expression::kValue, rhs->context());
626 Visit(rhs);
627 __ pop(r0);
628 }
629 __ mov(r2, Operand(var->name())); 582 __ mov(r2, Operand(var->name()));
630 __ ldr(ip, CodeGenerator::GlobalObject()); 583 __ ldr(ip, CodeGenerator::GlobalObject());
631 __ push(ip); 584 __ push(ip);
632 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 585 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
633 __ Call(ic, RelocInfo::CODE_TARGET); 586 __ Call(ic, RelocInfo::CODE_TARGET);
634 // Overwrite the global object on the stack with the result if needed. 587 // Overwrite the global object on the stack with the result if needed.
635 DropAndMove(expr->context(), r0); 588 DropAndMove(context, r0);
636 } else { 589 } else {
637 // Local or parameter assignment. 590 switch (context) {
638 591 case Expression::kUninitialized:
639 // Code for the right-hand side expression depends on its type. 592 UNREACHABLE();
640 if (rhs->AsLiteral() != NULL) { 593 case Expression::kEffect:
641 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a 594 // Perform assignment and discard value.
642 // discarded result. Always perform the assignment. 595 __ pop(r0);
643 __ mov(ip, Operand(rhs->AsLiteral()->handle())); 596 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
644 __ str(ip, MemOperand(fp, SlotOffset(var->slot()))); 597 break;
645 Move(expr->context(), ip); 598 case Expression::kValue:
646 } else { 599 // Perform assignment and preserve value.
647 ASSERT_EQ(Expression::kValue, rhs->context()); 600 __ ldr(r0, MemOperand(sp));
648 Visit(rhs); 601 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
649 // Load right-hand side into ip. 602 break;
650 switch (expr->context()) { 603 case Expression::kTest:
651 case Expression::kUninitialized: 604 // Perform assignment and test (and discard) value.
652 UNREACHABLE(); 605 __ pop(r0);
653 case Expression::kEffect: 606 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
654 // Case 'var = temp'. Discard right-hand-side temporary. 607 TestAndBranch(r0, true_label_, false_label_);
655 __ pop(r0); 608 break;
656 __ str(r0, MemOperand(fp, SlotOffset(var->slot()))); 609 case Expression::kValueTest: {
657 break; 610 Label discard;
658 case Expression::kValue: 611 __ ldr(r0, MemOperand(sp));
659 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side 612 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
660 // temporary on the stack. 613 TestAndBranch(r0, true_label_, &discard);
661 __ ldr(r0, MemOperand(sp)); 614 __ bind(&discard);
662 __ str(r0, MemOperand(fp, SlotOffset(var->slot()))); 615 __ pop();
663 break; 616 __ jmp(false_label_);
664 case Expression::kTest: 617 break;
665 // Case 'if (var = temp) ...'. 618 }
666 __ pop(r0); 619 case Expression::kTestValue: {
667 __ str(r0, MemOperand(fp, SlotOffset(var->slot()))); 620 Label discard;
668 TestAndBranch(r0, true_label_, false_label_); 621 __ ldr(r0, MemOperand(sp));
669 break; 622 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
670 case Expression::kValueTest: { 623 TestAndBranch(r0, &discard, false_label_);
671 // Case '(var = temp) || ...' in value context. 624 __ bind(&discard);
672 Label discard; 625 __ pop();
673 __ ldr(r0, MemOperand(sp)); 626 __ jmp(true_label_);
674 __ str(r0, MemOperand(fp, SlotOffset(var->slot()))); 627 break;
675 TestAndBranch(r0, true_label_, &discard);
676 __ bind(&discard);
677 __ pop();
678 __ jmp(false_label_);
679 break;
680 }
681 case Expression::kTestValue: {
682 // Case '(var = temp) && ...' in value context.
683 Label discard;
684 __ ldr(r0, MemOperand(sp));
685 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
686 TestAndBranch(r0, &discard, false_label_);
687 __ bind(&discard);
688 __ pop();
689 __ jmp(true_label_);
690 break;
691 }
692 } 628 }
693 } 629 }
694 } 630 }
695 } 631 }
696 632
697 633
634 void FastCodeGenerator::EmitNamedPropertyAssignment(
635 Expression::Context context,
636 Handle<Object> name) {
637 __ pop(r0);
638 __ mov(r2, Operand(name));
639 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
640 __ Call(ic, RelocInfo::CODE_TARGET);
641 DropAndMove(context, r0);
642 }
643
644
645 void FastCodeGenerator::EmitKeyedPropertyAssignment(
646 Expression::Context context) {
647 __ pop(r0);
648 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
649 __ Call(ic, RelocInfo::CODE_TARGET);
650 // Receiver and key are still on stack.
651 __ add(sp, sp, Operand(2 * kPointerSize));
652 Move(context, r0);
653 }
654
655
698 void FastCodeGenerator::VisitProperty(Property* expr) { 656 void FastCodeGenerator::VisitProperty(Property* expr) {
699 Comment cmnt(masm_, "[ Property"); 657 Comment cmnt(masm_, "[ Property");
700 Expression* key = expr->key(); 658 Expression* key = expr->key();
701 uint32_t dummy; 659 uint32_t dummy;
702 660
703 // Record the source position for the property load. 661 // Record the source position for the property load.
704 SetSourcePosition(expr->position()); 662 SetSourcePosition(expr->position());
705 663
706 // Evaluate receiver. 664 // Evaluate receiver.
707 Visit(expr->obj()); 665 Visit(expr->obj());
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 904
947 break; 905 break;
948 } 906 }
949 default: 907 default:
950 UNREACHABLE(); 908 UNREACHABLE();
951 } 909 }
952 } 910 }
953 911
954 912
955 } } // namespace v8::internal 913 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698