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

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

Issue 360054: Enable writes and reads of context slots in fast compiler. (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 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 if (FLAG_debug_code) { 357 if (FLAG_debug_code) {
358 // Check if we have the correct context pointer. 358 // Check if we have the correct context pointer.
359 __ ldr(r1, CodeGenerator::ContextOperand( 359 __ ldr(r1, CodeGenerator::ContextOperand(
360 cp, Context::FCONTEXT_INDEX)); 360 cp, Context::FCONTEXT_INDEX));
361 __ cmp(r1, cp); 361 __ cmp(r1, cp);
362 __ Check(eq, "Unexpected declaration in current context."); 362 __ Check(eq, "Unexpected declaration in current context.");
363 } 363 }
364 __ str(r0, CodeGenerator::ContextOperand(cp, slot->index())); 364 __ str(r0, CodeGenerator::ContextOperand(cp, slot->index()));
365 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; 365 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
366 __ mov(r2, Operand(offset)); 366 __ mov(r2, Operand(offset));
367 // We know that we have written a function, which is not a smi.
367 __ RecordWrite(cp, r2, r0); 368 __ RecordWrite(cp, r2, r0);
368 } 369 }
369 break; 370 break;
370 default: 371 default:
371 UNREACHABLE(); 372 UNREACHABLE();
372 } 373 }
373 } 374 }
374 375
375 376
376 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 377 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 __ stm(db_w, sp, cp.bit() | r0.bit()); 415 __ stm(db_w, sp, cp.bit() | r0.bit());
415 __ CallRuntime(Runtime::kNewClosure, 2); 416 __ CallRuntime(Runtime::kNewClosure, 2);
416 Move(expr->context(), r0); 417 Move(expr->context(), r0);
417 } 418 }
418 419
419 420
420 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 421 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
421 Comment cmnt(masm_, "[ VariableProxy"); 422 Comment cmnt(masm_, "[ VariableProxy");
422 Expression* rewrite = expr->var()->rewrite(); 423 Expression* rewrite = expr->var()->rewrite();
423 if (rewrite == NULL) { 424 if (rewrite == NULL) {
425 ASSERT(expr->var()->is_global());
424 Comment cmnt(masm_, "Global variable"); 426 Comment cmnt(masm_, "Global variable");
425 // Use inline caching. Variable name is passed in r2 and the global 427 // Use inline caching. Variable name is passed in r2 and the global
426 // object on the stack. 428 // object on the stack.
427 __ ldr(ip, CodeGenerator::GlobalObject()); 429 __ ldr(ip, CodeGenerator::GlobalObject());
428 __ push(ip); 430 __ push(ip);
429 __ mov(r2, Operand(expr->name())); 431 __ mov(r2, Operand(expr->name()));
430 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 432 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
431 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); 433 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
432 DropAndMove(expr->context(), r0); 434 DropAndMove(expr->context(), r0);
433 } else { 435 } else {
434 Comment cmnt(masm_, "Stack slot"); 436 Slot* slot = rewrite->AsSlot();
435 Move(expr->context(), rewrite->AsSlot()); 437 ASSERT_NE(NULL, slot);
438 switch (slot->type()) {
439 case Slot::LOCAL:
440 case Slot::PARAMETER: {
441 Comment cmnt(masm_, "Stack slot");
442 Move(expr->context(), rewrite->AsSlot());
443 break;
444 }
445
446 case Slot::CONTEXT: {
447 Comment cmnt(masm_, "Context slot");
448 int chain_length =
449 function_->scope()->ContextChainLength(slot->var()->scope());
450 if (chain_length > 0) {
451 // Move up the chain of contexts to the context containing the slot.
452 __ ldr(r0, CodeGenerator::ContextOperand(cp, Context::CLOSURE_INDEX));
453 // Load the function context (which is the incoming, outer context).
454 __ ldr(r0, FieldMemOperand(r0, JSFunction::kContextOffset));
455 for (int i = 1; i < chain_length; i++) {
456 __ ldr(r0,
457 CodeGenerator::ContextOperand(r0, Context::CLOSURE_INDEX));
458 // Load the function context (which is the incoming, outer context).
459 __ ldr(r0, FieldMemOperand(r0, JSFunction::kContextOffset));
460 }
461 // The context may be an intermediate context, not a function context.
462 __ ldr(r0,
463 CodeGenerator::ContextOperand(r0, Context::FCONTEXT_INDEX));
464 } else { // Slot is in the current context.
465 __ ldr(r0,
466 CodeGenerator::ContextOperand(cp, Context::FCONTEXT_INDEX));
467 }
468 __ ldr(r0, CodeGenerator::ContextOperand(r0, slot->index()));
469 Move(expr->context(), r0);
470 break;
471 }
472
473 case Slot::LOOKUP:
474 UNREACHABLE();
475 break;
476 }
436 } 477 }
437 } 478 }
438 479
439 480
440 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 481 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
441 Comment cmnt(masm_, "[ RegExpLiteral"); 482 Comment cmnt(masm_, "[ RegExpLiteral");
442 Label done; 483 Label done;
443 // Registers will be used as follows: 484 // Registers will be used as follows:
444 // r4 = JS function, literals array 485 // r4 = JS function, literals array
445 // r3 = literal index 486 // r3 = literal index
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 __ pop(r0); 739 __ pop(r0);
699 __ mov(r2, Operand(var->name())); 740 __ mov(r2, Operand(var->name()));
700 __ ldr(ip, CodeGenerator::GlobalObject()); 741 __ ldr(ip, CodeGenerator::GlobalObject());
701 __ push(ip); 742 __ push(ip);
702 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 743 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
703 __ Call(ic, RelocInfo::CODE_TARGET); 744 __ Call(ic, RelocInfo::CODE_TARGET);
704 // Overwrite the global object on the stack with the result if needed. 745 // Overwrite the global object on the stack with the result if needed.
705 DropAndMove(expr->context(), r0); 746 DropAndMove(expr->context(), r0);
706 747
707 } else { 748 } else {
708 switch (expr->context()) { 749 Slot* slot = var->slot();
709 case Expression::kUninitialized: 750 ASSERT_NOT_NULL(slot); // Variables rewritten as properties not handled.
710 UNREACHABLE(); 751 switch (slot->type()) {
711 case Expression::kEffect: 752 case Slot::LOCAL:
712 // Perform assignment and discard value. 753 case Slot::PARAMETER: {
713 __ pop(r0); 754 switch (expr->context()) {
714 __ str(r0, MemOperand(fp, SlotOffset(var->slot()))); 755 case Expression::kUninitialized:
715 break; 756 UNREACHABLE();
716 case Expression::kValue: 757 case Expression::kEffect:
717 // Perform assignment and preserve value. 758 // Perform assignment and discard value.
718 __ ldr(r0, MemOperand(sp)); 759 __ pop(r0);
719 __ str(r0, MemOperand(fp, SlotOffset(var->slot()))); 760 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
720 break; 761 break;
721 case Expression::kTest: 762 case Expression::kValue:
722 // Perform assignment and test (and discard) value. 763 // Perform assignment and preserve value.
723 __ pop(r0); 764 __ ldr(r0, MemOperand(sp));
724 __ str(r0, MemOperand(fp, SlotOffset(var->slot()))); 765 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
725 TestAndBranch(r0, true_label_, false_label_); 766 break;
726 break; 767 case Expression::kTest:
727 case Expression::kValueTest: { 768 // Perform assignment and test (and discard) value.
728 Label discard; 769 __ pop(r0);
729 __ ldr(r0, MemOperand(sp)); 770 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
730 __ str(r0, MemOperand(fp, SlotOffset(var->slot()))); 771 TestAndBranch(r0, true_label_, false_label_);
731 TestAndBranch(r0, true_label_, &discard); 772 break;
732 __ bind(&discard); 773 case Expression::kValueTest: {
733 __ pop(); 774 Label discard;
734 __ jmp(false_label_); 775 __ ldr(r0, MemOperand(sp));
776 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
777 TestAndBranch(r0, true_label_, &discard);
778 __ bind(&discard);
779 __ pop();
780 __ jmp(false_label_);
781 break;
782 }
783 case Expression::kTestValue: {
784 Label discard;
785 __ ldr(r0, MemOperand(sp));
786 __ str(r0, MemOperand(fp, SlotOffset(var->slot())));
787 TestAndBranch(r0, &discard, false_label_);
788 __ bind(&discard);
789 __ pop();
790 __ jmp(true_label_);
791 break;
792 }
793 }
735 break; 794 break;
736 } 795 }
737 case Expression::kTestValue: { 796
738 Label discard; 797 case Slot::CONTEXT: {
739 __ ldr(r0, MemOperand(sp)); 798 int chain_length =
740 __ str(r0, MemOperand(fp, SlotOffset(var->slot()))); 799 function_->scope()->ContextChainLength(slot->var()->scope());
741 TestAndBranch(r0, &discard, false_label_); 800 if (chain_length > 0) {
742 __ bind(&discard); 801 // Move up the chain of contexts to the context containing the slot.
743 __ pop(); 802 __ ldr(r0, CodeGenerator::ContextOperand(cp, Context::CLOSURE_INDEX));
744 __ jmp(true_label_); 803 // Load the function context (which is the incoming, outer context).
804 __ ldr(r0, FieldMemOperand(r0, JSFunction::kContextOffset));
805 for (int i = 1; i < chain_length; i++) {
806 __ ldr(r0,
807 CodeGenerator::ContextOperand(r0, Context::CLOSURE_INDEX));
808 __ ldr(r0, FieldMemOperand(r0, JSFunction::kContextOffset));
809 }
810 } else { // Slot is in the current context. Generate optimized code.
811 __ mov(r0, cp);
812 }
813 // The context may be an intermediate context, not a function context.
814 __ ldr(r0, CodeGenerator::ContextOperand(r0, Context::FCONTEXT_INDEX));
815 __ pop(r1);
816 __ str(r1, CodeGenerator::ContextOperand(r0, slot->index()));
817
818 // RecordWrite may destroy all its register arguments.
819 if (expr->context() == Expression::kValue) {
820 __ push(r1);
821 } else if (expr->context() != Expression::kEffect) {
822 __ mov(r3, r1);
823 }
824 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
825
826 // Update the write barrier for the array store with r0 as the scratch
827 // register. Skip the write barrier if r0 is a smi.
828 // The smi test is part of RecordWrite on other platforms, not on arm.
829 Label exit;
830 __ tst(r0, Operand(kSmiTagMask));
831 __ b(eq, &exit);
832
833 __ mov(r2, Operand(offset));
834 __ RecordWrite(r0, r2, r1);
835 __ bind(&exit);
836 if (expr->context() != Expression::kEffect &&
837 expr->context() != Expression::kValue) {
838 Move(expr->context(), r3);
839 }
745 break; 840 break;
746 } 841 }
842
843 case Slot::LOOKUP:
844 UNREACHABLE();
845 break;
747 } 846 }
748 } 847 }
749 } 848 }
750 849
751 850
752 void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 851 void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
753 // Assignment to a property, using a named store IC. 852 // Assignment to a property, using a named store IC.
754 Property* prop = expr->target()->AsProperty(); 853 Property* prop = expr->target()->AsProperty();
755 ASSERT(prop != NULL); 854 ASSERT(prop != NULL);
756 ASSERT(prop->key()->AsLiteral() != NULL); 855 ASSERT(prop->key()->AsLiteral() != NULL);
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after
1426 true_label_ = saved_true; 1525 true_label_ = saved_true;
1427 false_label_ = saved_false; 1526 false_label_ = saved_false;
1428 // Convert current context to test context: End post-test code. 1527 // Convert current context to test context: End post-test code.
1429 } 1528 }
1430 1529
1431 1530
1432 #undef __ 1531 #undef __
1433 1532
1434 1533
1435 } } // namespace v8::internal 1534 } } // 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