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

Side by Side Diff: src/ia32/fast-codegen-ia32.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 | « src/compiler.cc ('k') | src/x64/fast-codegen-x64.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 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 __ push(Immediate(boilerplate)); 403 __ push(Immediate(boilerplate));
404 __ CallRuntime(Runtime::kNewClosure, 2); 404 __ CallRuntime(Runtime::kNewClosure, 2);
405 Move(expr->context(), eax); 405 Move(expr->context(), eax);
406 } 406 }
407 407
408 408
409 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 409 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
410 Comment cmnt(masm_, "[ VariableProxy"); 410 Comment cmnt(masm_, "[ VariableProxy");
411 Expression* rewrite = expr->var()->rewrite(); 411 Expression* rewrite = expr->var()->rewrite();
412 if (rewrite == NULL) { 412 if (rewrite == NULL) {
413 ASSERT(expr->var()->is_global());
413 Comment cmnt(masm_, "Global variable"); 414 Comment cmnt(masm_, "Global variable");
414 // Use inline caching. Variable name is passed in ecx and the global 415 // Use inline caching. Variable name is passed in ecx and the global
415 // object on the stack. 416 // object on the stack.
416 __ push(CodeGenerator::GlobalObject()); 417 __ push(CodeGenerator::GlobalObject());
417 __ mov(ecx, expr->name()); 418 __ mov(ecx, expr->name());
418 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 419 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
419 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 420 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
420 // By emitting a nop we make sure that we do not have a test eax 421 // By emitting a nop we make sure that we do not have a test eax
421 // instruction after the call it is treated specially by the LoadIC code 422 // instruction after the call it is treated specially by the LoadIC code
422 // Remember that the assembler may choose to do peephole optimization 423 // Remember that the assembler may choose to do peephole optimization
423 // (eg, push/pop elimination). 424 // (eg, push/pop elimination).
424 __ nop(); 425 __ nop();
425 426
426 DropAndMove(expr->context(), eax); 427 DropAndMove(expr->context(), eax);
427 } else { 428 } else {
428 Comment cmnt(masm_, "Stack slot"); 429 Slot* slot = rewrite->AsSlot();
429 Move(expr->context(), rewrite->AsSlot()); 430 ASSERT_NE(NULL, slot);
431 switch (slot->type()) {
432 case Slot::LOCAL:
433 case Slot::PARAMETER: {
434 Comment cmnt(masm_, "Stack slot");
435 Move(expr->context(), slot);
436 break;
437 }
438
439 case Slot::CONTEXT: {
440 Comment cmnt(masm_, "Context slot");
441 int chain_length =
442 function_->scope()->ContextChainLength(slot->var()->scope());
443 if (chain_length > 0) {
444 // Move up the chain of contexts to the context containing the slot.
445 __ mov(eax,
446 Operand(esi, Context::SlotOffset(Context::CLOSURE_INDEX)));
447 // Load the function context (which is the incoming, outer context).
448 __ mov(eax, FieldOperand(eax, JSFunction::kContextOffset));
449 for (int i = 1; i < chain_length; i++) {
450 __ mov(eax,
451 Operand(eax, Context::SlotOffset(Context::CLOSURE_INDEX)));
452 __ mov(eax, FieldOperand(eax, JSFunction::kContextOffset));
453 }
454 // The context may be an intermediate context, not a function context.
455 __ mov(eax,
456 Operand(eax, Context::SlotOffset(Context::FCONTEXT_INDEX)));
457 } else { // Slot is in the current function context.
458 // The context may be an intermediate context, not a function context.
459 __ mov(eax,
460 Operand(esi, Context::SlotOffset(Context::FCONTEXT_INDEX)));
461 }
462 __ mov(eax, Operand(eax, Context::SlotOffset(slot->index())));
463 Move(expr->context(), eax);
464 break;
465 }
466
467 case Slot::LOOKUP:
468 UNREACHABLE();
469 break;
470 }
430 } 471 }
431 } 472 }
432 473
433 474
434 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 475 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
435 Comment cmnt(masm_, "[ RegExpLiteral"); 476 Comment cmnt(masm_, "[ RegExpLiteral");
436 Label done; 477 Label done;
437 // Registers will be used as follows: 478 // Registers will be used as follows:
438 // edi = JS function. 479 // edi = JS function.
439 // ebx = literals array. 480 // ebx = literals array.
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 // ecx, and the global object on the stack. 727 // ecx, and the global object on the stack.
687 __ pop(eax); 728 __ pop(eax);
688 __ mov(ecx, var->name()); 729 __ mov(ecx, var->name());
689 __ push(CodeGenerator::GlobalObject()); 730 __ push(CodeGenerator::GlobalObject());
690 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 731 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
691 __ call(ic, RelocInfo::CODE_TARGET); 732 __ call(ic, RelocInfo::CODE_TARGET);
692 // Overwrite the receiver on the stack with the result if needed. 733 // Overwrite the receiver on the stack with the result if needed.
693 DropAndMove(expr->context(), eax); 734 DropAndMove(expr->context(), eax);
694 735
695 } else { 736 } else {
696 switch (expr->context()) { 737 Slot* slot = var->slot();
697 case Expression::kUninitialized: 738 ASSERT_NOT_NULL(slot); // Variables rewritten as properties not handled.
698 UNREACHABLE(); 739 switch (slot->type()) {
699 case Expression::kEffect: 740 case Slot::LOCAL:
700 // Perform assignment and discard value. 741 case Slot::PARAMETER: {
701 __ pop(Operand(ebp, SlotOffset(var->slot()))); 742 switch (expr->context()) {
702 break; 743 case Expression::kUninitialized:
703 case Expression::kValue: 744 UNREACHABLE();
704 // Perform assignment and preserve value. 745 case Expression::kEffect:
705 __ mov(eax, Operand(esp, 0)); 746 // Perform assignment and discard value.
706 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); 747 __ pop(Operand(ebp, SlotOffset(var->slot())));
707 break; 748 break;
708 case Expression::kTest: 749 case Expression::kValue:
709 // Perform assignment and test (and discard) value. 750 // Perform assignment and preserve value.
710 __ pop(eax); 751 __ mov(eax, Operand(esp, 0));
711 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); 752 __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
712 TestAndBranch(eax, true_label_, false_label_); 753 break;
713 break; 754 case Expression::kTest:
714 case Expression::kValueTest: { 755 // Perform assignment and test (and discard) value.
715 Label discard; 756 __ pop(eax);
716 __ mov(eax, Operand(esp, 0)); 757 __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
717 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); 758 TestAndBranch(eax, true_label_, false_label_);
718 TestAndBranch(eax, true_label_, &discard); 759 break;
719 __ bind(&discard); 760 case Expression::kValueTest: {
720 __ add(Operand(esp), Immediate(kPointerSize)); 761 Label discard;
721 __ jmp(false_label_); 762 __ mov(eax, Operand(esp, 0));
763 __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
764 TestAndBranch(eax, true_label_, &discard);
765 __ bind(&discard);
766 __ add(Operand(esp), Immediate(kPointerSize));
767 __ jmp(false_label_);
768 break;
769 }
770 case Expression::kTestValue: {
771 Label discard;
772 __ mov(eax, Operand(esp, 0));
773 __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
774 TestAndBranch(eax, &discard, false_label_);
775 __ bind(&discard);
776 __ add(Operand(esp), Immediate(kPointerSize));
777 __ jmp(true_label_);
778 break;
779 }
780 }
722 break; 781 break;
723 } 782 }
724 case Expression::kTestValue: { 783
725 Label discard; 784 case Slot::CONTEXT: {
726 __ mov(eax, Operand(esp, 0)); 785 int chain_length =
727 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); 786 function_->scope()->ContextChainLength(slot->var()->scope());
728 TestAndBranch(eax, &discard, false_label_); 787 if (chain_length > 0) {
729 __ bind(&discard); 788 // Move up the context chain to the context containing the slot.
730 __ add(Operand(esp), Immediate(kPointerSize)); 789 __ mov(eax,
731 __ jmp(true_label_); 790 Operand(esi, Context::SlotOffset(Context::CLOSURE_INDEX)));
791 // Load the function context (which is the incoming, outer context).
792 __ mov(eax, FieldOperand(eax, JSFunction::kContextOffset));
793 for (int i = 1; i < chain_length; i++) {
794 __ mov(eax,
795 Operand(eax, Context::SlotOffset(Context::CLOSURE_INDEX)));
796 __ mov(eax, FieldOperand(eax, JSFunction::kContextOffset));
797 }
798 } else { // Slot is in the current context. Generate optimized code.
799 __ mov(eax, esi); // RecordWrite destroys the object register.
800 }
801 if (FLAG_debug_code) {
802 __ cmp(eax,
803 Operand(eax, Context::SlotOffset(Context::FCONTEXT_INDEX)));
804 __ Check(equal, "Context Slot chain length wrong.");
805 }
806 __ pop(ecx);
807 __ mov(Operand(eax, Context::SlotOffset(slot->index())), ecx);
808
809 // RecordWrite may destroy all its register arguments.
810 if (expr->context() == Expression::kValue) {
811 __ push(ecx);
812 } else if (expr->context() != Expression::kEffect) {
813 __ mov(edx, ecx);
814 }
815 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
816 __ RecordWrite(eax, offset, ecx, ebx);
817 if (expr->context() != Expression::kEffect &&
818 expr->context() != Expression::kValue) {
819 Move(expr->context(), edx);
820 }
732 break; 821 break;
733 } 822 }
823
824 case Slot::LOOKUP:
825 UNREACHABLE();
826 break;
734 } 827 }
735 } 828 }
736 } 829 }
737 830
738 831
739 void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 832 void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
740 // Assignment to a property, using a named store IC. 833 // Assignment to a property, using a named store IC.
741 Property* prop = expr->target()->AsProperty(); 834 Property* prop = expr->target()->AsProperty();
742 ASSERT(prop != NULL); 835 ASSERT(prop != NULL);
743 ASSERT(prop->key()->AsLiteral() != NULL); 836 ASSERT(prop->key()->AsLiteral() != NULL);
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 true_label_ = saved_true; 1502 true_label_ = saved_true;
1410 false_label_ = saved_false; 1503 false_label_ = saved_false;
1411 // Convert current context to test context: End post-test code. 1504 // Convert current context to test context: End post-test code.
1412 } 1505 }
1413 1506
1414 1507
1415 #undef __ 1508 #undef __
1416 1509
1417 1510
1418 } } // namespace v8::internal 1511 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/compiler.cc ('k') | src/x64/fast-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698