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

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 7753030: Remove code handling parameters rewritten to properties (aka synthetic properties). (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 3 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
« no previous file with comments | « src/hydrogen.cc ('k') | src/mips/full-codegen-mips.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 28 matching lines...) Expand all
39 #include "stub-cache.h" 39 #include "stub-cache.h"
40 40
41 namespace v8 { 41 namespace v8 {
42 namespace internal { 42 namespace internal {
43 43
44 44
45 #define __ ACCESS_MASM(masm_) 45 #define __ ACCESS_MASM(masm_)
46 46
47 47
48 static unsigned GetPropertyId(Property* property) { 48 static unsigned GetPropertyId(Property* property) {
49 if (property->is_synthetic()) return AstNode::kNoNumber;
50 return property->id(); 49 return property->id();
51 } 50 }
52 51
53 52
54 class JumpPatchSite BASE_EMBEDDED { 53 class JumpPatchSite BASE_EMBEDDED {
55 public: 54 public:
56 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) { 55 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) {
57 #ifdef DEBUG 56 #ifdef DEBUG
58 info_emitted_ = false; 57 info_emitted_ = false;
59 #endif 58 #endif
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 } 682 }
684 } 683 }
685 684
686 685
687 void FullCodeGenerator::EmitDeclaration(Variable* variable, 686 void FullCodeGenerator::EmitDeclaration(Variable* variable,
688 Variable::Mode mode, 687 Variable::Mode mode,
689 FunctionLiteral* function) { 688 FunctionLiteral* function) {
690 Comment cmnt(masm_, "[ Declaration"); 689 Comment cmnt(masm_, "[ Declaration");
691 ASSERT(variable != NULL); // Must have been resolved. 690 ASSERT(variable != NULL); // Must have been resolved.
692 Slot* slot = variable->AsSlot(); 691 Slot* slot = variable->AsSlot();
693 Property* prop = variable->AsProperty(); 692 ASSERT(slot != NULL);
693 switch (slot->type()) {
694 case Slot::PARAMETER:
695 case Slot::LOCAL:
696 if (mode == Variable::CONST) {
697 __ mov(Operand(ebp, SlotOffset(slot)),
698 Immediate(isolate()->factory()->the_hole_value()));
699 } else if (function != NULL) {
700 VisitForAccumulatorValue(function);
701 __ mov(Operand(ebp, SlotOffset(slot)), result_register());
702 }
703 break;
694 704
695 if (slot != NULL) { 705 case Slot::CONTEXT:
696 switch (slot->type()) { 706 // We bypass the general EmitSlotSearch because we know more about
697 case Slot::PARAMETER: 707 // this specific context.
698 case Slot::LOCAL:
699 if (mode == Variable::CONST) {
700 __ mov(Operand(ebp, SlotOffset(slot)),
701 Immediate(isolate()->factory()->the_hole_value()));
702 } else if (function != NULL) {
703 VisitForAccumulatorValue(function);
704 __ mov(Operand(ebp, SlotOffset(slot)), result_register());
705 }
706 break;
707 708
708 case Slot::CONTEXT: 709 // The variable in the decl always resides in the current function
709 // We bypass the general EmitSlotSearch because we know more about 710 // context.
710 // this specific context. 711 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
712 if (FLAG_debug_code) {
713 // Check that we're not inside a with or catch context.
714 __ mov(ebx, FieldOperand(esi, HeapObject::kMapOffset));
715 __ cmp(ebx, isolate()->factory()->with_context_map());
716 __ Check(not_equal, "Declaration in with context.");
717 __ cmp(ebx, isolate()->factory()->catch_context_map());
718 __ Check(not_equal, "Declaration in catch context.");
719 }
720 if (mode == Variable::CONST) {
721 __ mov(ContextOperand(esi, slot->index()),
722 Immediate(isolate()->factory()->the_hole_value()));
723 // No write barrier since the hole value is in old space.
724 } else if (function != NULL) {
725 VisitForAccumulatorValue(function);
726 __ mov(ContextOperand(esi, slot->index()), result_register());
727 int offset = Context::SlotOffset(slot->index());
728 __ mov(ebx, esi);
729 __ RecordWrite(ebx, offset, result_register(), ecx);
730 }
731 break;
711 732
712 // The variable in the decl always resides in the current function 733 case Slot::LOOKUP: {
713 // context. 734 __ push(esi);
714 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); 735 __ push(Immediate(variable->name()));
715 if (FLAG_debug_code) { 736 // Declaration nodes are always introduced in one of two modes.
716 // Check that we're not inside a with or catch context. 737 ASSERT(mode == Variable::VAR ||
717 __ mov(ebx, FieldOperand(esi, HeapObject::kMapOffset)); 738 mode == Variable::CONST ||
718 __ cmp(ebx, isolate()->factory()->with_context_map()); 739 mode == Variable::LET);
719 __ Check(not_equal, "Declaration in with context."); 740 PropertyAttributes attr = (mode == Variable::CONST) ? READ_ONLY : NONE;
720 __ cmp(ebx, isolate()->factory()->catch_context_map()); 741 __ push(Immediate(Smi::FromInt(attr)));
721 __ Check(not_equal, "Declaration in catch context."); 742 // Push initial value, if any.
722 } 743 // Note: For variables we must not push an initial value (such as
723 if (mode == Variable::CONST) { 744 // 'undefined') because we may have a (legal) redeclaration and we
724 __ mov(ContextOperand(esi, slot->index()), 745 // must not destroy the current value.
725 Immediate(isolate()->factory()->the_hole_value())); 746 increment_stack_height(3);
726 // No write barrier since the hole value is in old space. 747 if (mode == Variable::CONST) {
727 } else if (function != NULL) { 748 __ push(Immediate(isolate()->factory()->the_hole_value()));
728 VisitForAccumulatorValue(function); 749 increment_stack_height();
729 __ mov(ContextOperand(esi, slot->index()), result_register()); 750 } else if (function != NULL) {
730 int offset = Context::SlotOffset(slot->index()); 751 VisitForStackValue(function);
731 __ mov(ebx, esi); 752 } else {
732 __ RecordWrite(ebx, offset, result_register(), ecx); 753 __ push(Immediate(Smi::FromInt(0))); // No initial value!
733 } 754 increment_stack_height();
734 break;
735
736 case Slot::LOOKUP: {
737 __ push(esi);
738 __ push(Immediate(variable->name()));
739 // Declaration nodes are always introduced in one of two modes.
740 ASSERT(mode == Variable::VAR ||
741 mode == Variable::CONST ||
742 mode == Variable::LET);
743 PropertyAttributes attr = (mode == Variable::CONST) ? READ_ONLY : NONE;
744 __ push(Immediate(Smi::FromInt(attr)));
745 // Push initial value, if any.
746 // Note: For variables we must not push an initial value (such as
747 // 'undefined') because we may have a (legal) redeclaration and we
748 // must not destroy the current value.
749 increment_stack_height(3);
750 if (mode == Variable::CONST) {
751 __ push(Immediate(isolate()->factory()->the_hole_value()));
752 increment_stack_height();
753 } else if (function != NULL) {
754 VisitForStackValue(function);
755 } else {
756 __ push(Immediate(Smi::FromInt(0))); // No initial value!
757 increment_stack_height();
758 }
759 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
760 decrement_stack_height(4);
761 break;
762 } 755 }
763 } 756 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
764 757 decrement_stack_height(4);
765 } else if (prop != NULL) { 758 break;
766 // A const declaration aliasing a parameter is an illegal redeclaration.
767 ASSERT(mode != Variable::CONST);
768 if (function != NULL) {
769 // We are declaring a function that rewrites to a property.
770 // Use (keyed) IC to set the initial value. We cannot visit the
771 // rewrite because it's shared and we risk recording duplicate AST
772 // IDs for bailouts from optimized code.
773 ASSERT(prop->obj()->AsVariableProxy() != NULL);
774 { AccumulatorValueContext for_object(this);
775 EmitVariableLoad(prop->obj()->AsVariableProxy());
776 }
777
778 __ push(eax);
779 increment_stack_height();
780 VisitForAccumulatorValue(function);
781 __ pop(edx);
782 decrement_stack_height();
783
784 ASSERT(prop->key()->AsLiteral() != NULL &&
785 prop->key()->AsLiteral()->handle()->IsSmi());
786 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle()));
787
788 Handle<Code> ic = is_strict_mode()
789 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
790 : isolate()->builtins()->KeyedStoreIC_Initialize();
791 __ call(ic);
792 } 759 }
793 } 760 }
794 } 761 }
795 762
796 763
797 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 764 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
798 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 765 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
799 } 766 }
800 767
801 768
(...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after
1817 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1784 __ mov(ecx, prop->key()->AsLiteral()->handle());
1818 Handle<Code> ic = is_strict_mode() 1785 Handle<Code> ic = is_strict_mode()
1819 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1786 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1820 : isolate()->builtins()->StoreIC_Initialize(); 1787 : isolate()->builtins()->StoreIC_Initialize();
1821 __ call(ic); 1788 __ call(ic);
1822 break; 1789 break;
1823 } 1790 }
1824 case KEYED_PROPERTY: { 1791 case KEYED_PROPERTY: {
1825 __ push(eax); // Preserve value. 1792 __ push(eax); // Preserve value.
1826 increment_stack_height(); 1793 increment_stack_height();
1827 if (prop->is_synthetic()) { 1794 VisitForStackValue(prop->obj());
1828 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1795 VisitForAccumulatorValue(prop->key());
1829 ASSERT(prop->key()->AsLiteral() != NULL); 1796 __ mov(ecx, eax);
1830 { AccumulatorValueContext for_object(this); 1797 __ pop(edx);
1831 EmitVariableLoad(prop->obj()->AsVariableProxy()); 1798 decrement_stack_height();
1832 }
1833 __ mov(edx, eax);
1834 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle()));
1835 } else {
1836 VisitForStackValue(prop->obj());
1837 VisitForAccumulatorValue(prop->key());
1838 __ mov(ecx, eax);
1839 __ pop(edx);
1840 decrement_stack_height();
1841 }
1842 __ pop(eax); // Restore value. 1799 __ pop(eax); // Restore value.
1843 decrement_stack_height(); 1800 decrement_stack_height();
1844 Handle<Code> ic = is_strict_mode() 1801 Handle<Code> ic = is_strict_mode()
1845 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1802 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1846 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1803 : isolate()->builtins()->KeyedStoreIC_Initialize();
1847 __ call(ic); 1804 __ call(ic);
1848 break; 1805 break;
1849 } 1806 }
1850 } 1807 }
1851 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1808 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
2268 Property* prop = fun->AsProperty(); 2225 Property* prop = fun->AsProperty();
2269 Literal* key = prop->key()->AsLiteral(); 2226 Literal* key = prop->key()->AsLiteral();
2270 if (key != NULL && key->handle()->IsSymbol()) { 2227 if (key != NULL && key->handle()->IsSymbol()) {
2271 // Call to a named property, use call IC. 2228 // Call to a named property, use call IC.
2272 { PreservePositionScope scope(masm()->positions_recorder()); 2229 { PreservePositionScope scope(masm()->positions_recorder());
2273 VisitForStackValue(prop->obj()); 2230 VisitForStackValue(prop->obj());
2274 } 2231 }
2275 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 2232 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
2276 } else { 2233 } else {
2277 // Call to a keyed property. 2234 // Call to a keyed property.
2278 // For a synthetic property use keyed load IC followed by function call, 2235 { PreservePositionScope scope(masm()->positions_recorder());
2279 // for a regular property use EmitKeyedCallWithIC. 2236 VisitForStackValue(prop->obj());
2280 if (prop->is_synthetic()) {
2281 // Do not visit the object and key subexpressions (they are shared
2282 // by all occurrences of the same rewritten parameter).
2283 ASSERT(prop->obj()->AsVariableProxy() != NULL);
2284 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL);
2285 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot();
2286 MemOperand operand = EmitSlotSearch(slot, edx);
2287 __ mov(edx, operand);
2288
2289 ASSERT(prop->key()->AsLiteral() != NULL);
2290 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2291 __ mov(eax, prop->key()->AsLiteral()->handle());
2292
2293 // Record source code position for IC call.
2294 SetSourcePosition(prop->position());
2295
2296 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2297 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
2298 // Push result (function).
2299 __ push(eax);
2300 increment_stack_height();
2301 // Push Global receiver.
2302 __ mov(ecx, GlobalObjectOperand());
2303 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
2304 increment_stack_height();
2305 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
2306 } else {
2307 { PreservePositionScope scope(masm()->positions_recorder());
2308 VisitForStackValue(prop->obj());
2309 }
2310 EmitKeyedCallWithIC(expr, prop->key());
2311 } 2237 }
2238 EmitKeyedCallWithIC(expr, prop->key());
2312 } 2239 }
2313 } else { 2240 } else {
2314 { PreservePositionScope scope(masm()->positions_recorder()); 2241 { PreservePositionScope scope(masm()->positions_recorder());
2315 VisitForStackValue(fun); 2242 VisitForStackValue(fun);
2316 } 2243 }
2317 // Load global receiver object. 2244 // Load global receiver object.
2318 __ mov(ebx, GlobalObjectOperand()); 2245 __ mov(ebx, GlobalObjectOperand());
2319 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 2246 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
2320 increment_stack_height(); 2247 increment_stack_height();
2321 // Emit function call. 2248 // Emit function call.
(...skipping 1392 matching lines...) Expand 10 before | Expand all | Expand 10 after
3714 3641
3715 3642
3716 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3643 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3717 switch (expr->op()) { 3644 switch (expr->op()) {
3718 case Token::DELETE: { 3645 case Token::DELETE: {
3719 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 3646 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3720 Property* prop = expr->expression()->AsProperty(); 3647 Property* prop = expr->expression()->AsProperty();
3721 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 3648 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
3722 3649
3723 if (prop != NULL) { 3650 if (prop != NULL) {
3724 if (prop->is_synthetic()) { 3651 VisitForStackValue(prop->obj());
3725 // Result of deleting parameters is false, even when they rewrite 3652 VisitForStackValue(prop->key());
3726 // to accesses on the arguments object. 3653 __ push(Immediate(Smi::FromInt(strict_mode_flag())));
3727 context()->Plug(false); 3654 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3728 } else { 3655 decrement_stack_height(2);
3729 VisitForStackValue(prop->obj()); 3656 context()->Plug(eax);
3730 VisitForStackValue(prop->key());
3731 __ push(Immediate(Smi::FromInt(strict_mode_flag())));
3732 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3733 decrement_stack_height(2);
3734 context()->Plug(eax);
3735 }
3736 } else if (var != NULL) { 3657 } else if (var != NULL) {
3737 // Delete of an unqualified identifier is disallowed in strict mode 3658 // Delete of an unqualified identifier is disallowed in strict mode
3738 // but "delete this" is. 3659 // but "delete this" is.
3739 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this()); 3660 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this());
3740 if (var->is_global()) { 3661 if (var->is_global()) {
3741 __ push(GlobalObjectOperand()); 3662 __ push(GlobalObjectOperand());
3742 __ push(Immediate(var->name())); 3663 __ push(Immediate(var->name()));
3743 __ push(Immediate(Smi::FromInt(kNonStrictMode))); 3664 __ push(Immediate(Smi::FromInt(kNonStrictMode)));
3744 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3665 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3745 context()->Plug(eax); 3666 context()->Plug(eax);
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after
4372 __ add(Operand(edx), Immediate(masm_->CodeObject())); 4293 __ add(Operand(edx), Immediate(masm_->CodeObject()));
4373 __ jmp(Operand(edx)); 4294 __ jmp(Operand(edx));
4374 } 4295 }
4375 4296
4376 4297
4377 #undef __ 4298 #undef __
4378 4299
4379 } } // namespace v8::internal 4300 } } // namespace v8::internal
4380 4301
4381 #endif // V8_TARGET_ARCH_IA32 4302 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/mips/full-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698