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

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

Issue 6878009: Fix x64 typefeedback for property assignments. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 8 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/ia32/full-codegen-ia32.cc ('k') | no next file » | 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 1113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 } 1124 }
1125 1125
1126 // All extension objects were empty and it is safe to use a global 1126 // All extension objects were empty and it is safe to use a global
1127 // load IC call. 1127 // load IC call.
1128 __ movq(rax, GlobalObjectOperand()); 1128 __ movq(rax, GlobalObjectOperand());
1129 __ Move(rcx, slot->var()->name()); 1129 __ Move(rcx, slot->var()->name());
1130 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1130 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1131 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 1131 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
1132 ? RelocInfo::CODE_TARGET 1132 ? RelocInfo::CODE_TARGET
1133 : RelocInfo::CODE_TARGET_CONTEXT; 1133 : RelocInfo::CODE_TARGET_CONTEXT;
1134 EmitCallIC(ic, mode); 1134 EmitCallIC(ic, mode, AstNode::kNoNumber);
1135 } 1135 }
1136 1136
1137 1137
1138 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( 1138 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(
1139 Slot* slot, 1139 Slot* slot,
1140 Label* slow) { 1140 Label* slow) {
1141 ASSERT(slot->type() == Slot::CONTEXT); 1141 ASSERT(slot->type() == Slot::CONTEXT);
1142 Register context = rsi; 1142 Register context = rsi;
1143 Register temp = rbx; 1143 Register temp = rbx;
1144 1144
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 Slot* slot = var->AsSlot(); 1228 Slot* slot = var->AsSlot();
1229 Property* property = var->AsProperty(); 1229 Property* property = var->AsProperty();
1230 1230
1231 if (var->is_global() && !var->is_this()) { 1231 if (var->is_global() && !var->is_this()) {
1232 Comment cmnt(masm_, "Global variable"); 1232 Comment cmnt(masm_, "Global variable");
1233 // Use inline caching. Variable name is passed in rcx and the global 1233 // Use inline caching. Variable name is passed in rcx and the global
1234 // object on the stack. 1234 // object on the stack.
1235 __ Move(rcx, var->name()); 1235 __ Move(rcx, var->name());
1236 __ movq(rax, GlobalObjectOperand()); 1236 __ movq(rax, GlobalObjectOperand());
1237 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1237 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1238 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1238 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
1239 context()->Plug(rax); 1239 context()->Plug(rax);
1240 1240
1241 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 1241 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
1242 Label done, slow; 1242 Label done, slow;
1243 1243
1244 // Generate code for loading from variables potentially shadowed 1244 // Generate code for loading from variables potentially shadowed
1245 // by eval-introduced variables. 1245 // by eval-introduced variables.
1246 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1246 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
1247 1247
1248 __ bind(&slow); 1248 __ bind(&slow);
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
1762 } 1762 }
1763 case NAMED_PROPERTY: { 1763 case NAMED_PROPERTY: {
1764 __ push(rax); // Preserve value. 1764 __ push(rax); // Preserve value.
1765 VisitForAccumulatorValue(prop->obj()); 1765 VisitForAccumulatorValue(prop->obj());
1766 __ movq(rdx, rax); 1766 __ movq(rdx, rax);
1767 __ pop(rax); // Restore value. 1767 __ pop(rax); // Restore value.
1768 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1768 __ Move(rcx, prop->key()->AsLiteral()->handle());
1769 Handle<Code> ic = is_strict_mode() 1769 Handle<Code> ic = is_strict_mode()
1770 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1770 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1771 : isolate()->builtins()->StoreIC_Initialize(); 1771 : isolate()->builtins()->StoreIC_Initialize();
1772 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1772 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
1773 break; 1773 break;
1774 } 1774 }
1775 case KEYED_PROPERTY: { 1775 case KEYED_PROPERTY: {
1776 __ push(rax); // Preserve value. 1776 __ push(rax); // Preserve value.
1777 if (prop->is_synthetic()) { 1777 if (prop->is_synthetic()) {
1778 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1778 ASSERT(prop->obj()->AsVariableProxy() != NULL);
1779 ASSERT(prop->key()->AsLiteral() != NULL); 1779 ASSERT(prop->key()->AsLiteral() != NULL);
1780 { AccumulatorValueContext for_object(this); 1780 { AccumulatorValueContext for_object(this);
1781 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); 1781 EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
1782 } 1782 }
1783 __ movq(rdx, rax); 1783 __ movq(rdx, rax);
1784 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1784 __ Move(rcx, prop->key()->AsLiteral()->handle());
1785 } else { 1785 } else {
1786 VisitForStackValue(prop->obj()); 1786 VisitForStackValue(prop->obj());
1787 VisitForAccumulatorValue(prop->key()); 1787 VisitForAccumulatorValue(prop->key());
1788 __ movq(rcx, rax); 1788 __ movq(rcx, rax);
1789 __ pop(rdx); 1789 __ pop(rdx);
1790 } 1790 }
1791 __ pop(rax); // Restore value. 1791 __ pop(rax); // Restore value.
1792 Handle<Code> ic = is_strict_mode() 1792 Handle<Code> ic = is_strict_mode()
1793 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1793 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1794 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1794 : isolate()->builtins()->KeyedStoreIC_Initialize();
1795 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1795 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
1796 break; 1796 break;
1797 } 1797 }
1798 } 1798 }
1799 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1799 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1800 context()->Plug(rax); 1800 context()->Plug(rax);
1801 } 1801 }
1802 1802
1803 1803
1804 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1804 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1805 Token::Value op) { 1805 Token::Value op) {
1806 // Left-hand sides that rewrite to explicit property accesses do not reach 1806 // Left-hand sides that rewrite to explicit property accesses do not reach
1807 // here. 1807 // here.
1808 ASSERT(var != NULL); 1808 ASSERT(var != NULL);
1809 ASSERT(var->is_global() || var->AsSlot() != NULL); 1809 ASSERT(var->is_global() || var->AsSlot() != NULL);
1810 1810
1811 if (var->is_global()) { 1811 if (var->is_global()) {
1812 ASSERT(!var->is_this()); 1812 ASSERT(!var->is_this());
1813 // Assignment to a global variable. Use inline caching for the 1813 // Assignment to a global variable. Use inline caching for the
1814 // assignment. Right-hand-side value is passed in rax, variable name in 1814 // assignment. Right-hand-side value is passed in rax, variable name in
1815 // rcx, and the global object on the stack. 1815 // rcx, and the global object on the stack.
1816 __ Move(rcx, var->name()); 1816 __ Move(rcx, var->name());
1817 __ movq(rdx, GlobalObjectOperand()); 1817 __ movq(rdx, GlobalObjectOperand());
1818 Handle<Code> ic = is_strict_mode() 1818 Handle<Code> ic = is_strict_mode()
1819 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1819 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1820 : isolate()->builtins()->StoreIC_Initialize(); 1820 : isolate()->builtins()->StoreIC_Initialize();
1821 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1821 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
1822 1822
1823 } else if (op == Token::INIT_CONST) { 1823 } else if (op == Token::INIT_CONST) {
1824 // Like var declarations, const declarations are hoisted to function 1824 // Like var declarations, const declarations are hoisted to function
1825 // scope. However, unlike var initializers, const initializers are able 1825 // scope. However, unlike var initializers, const initializers are able
1826 // to drill a hole to that function context, even from inside a 'with' 1826 // to drill a hole to that function context, even from inside a 'with'
1827 // context. We thus bypass the normal static scope lookup. 1827 // context. We thus bypass the normal static scope lookup.
1828 Slot* slot = var->AsSlot(); 1828 Slot* slot = var->AsSlot();
1829 Label skip; 1829 Label skip;
1830 switch (slot->type()) { 1830 switch (slot->type()) {
1831 case Slot::PARAMETER: 1831 case Slot::PARAMETER:
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1914 SetSourcePosition(expr->position()); 1914 SetSourcePosition(expr->position());
1915 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1915 __ Move(rcx, prop->key()->AsLiteral()->handle());
1916 if (expr->ends_initialization_block()) { 1916 if (expr->ends_initialization_block()) {
1917 __ movq(rdx, Operand(rsp, 0)); 1917 __ movq(rdx, Operand(rsp, 0));
1918 } else { 1918 } else {
1919 __ pop(rdx); 1919 __ pop(rdx);
1920 } 1920 }
1921 Handle<Code> ic = is_strict_mode() 1921 Handle<Code> ic = is_strict_mode()
1922 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1922 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1923 : isolate()->builtins()->StoreIC_Initialize(); 1923 : isolate()->builtins()->StoreIC_Initialize();
1924 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1924 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
1925 1925
1926 // If the assignment ends an initialization block, revert to fast case. 1926 // If the assignment ends an initialization block, revert to fast case.
1927 if (expr->ends_initialization_block()) { 1927 if (expr->ends_initialization_block()) {
1928 __ push(rax); // Result of assignment, saved even if not needed. 1928 __ push(rax); // Result of assignment, saved even if not needed.
1929 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. 1929 __ push(Operand(rsp, kPointerSize)); // Receiver is under value.
1930 __ CallRuntime(Runtime::kToFastProperties, 1); 1930 __ CallRuntime(Runtime::kToFastProperties, 1);
1931 __ pop(rax); 1931 __ pop(rax);
1932 __ Drop(1); 1932 __ Drop(1);
1933 } 1933 }
1934 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1934 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
(...skipping 2020 matching lines...) Expand 10 before | Expand all | Expand 10 after
3955 ASSERT(!context()->IsEffect()); 3955 ASSERT(!context()->IsEffect());
3956 ASSERT(!context()->IsTest()); 3956 ASSERT(!context()->IsTest());
3957 3957
3958 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3958 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3959 Comment cmnt(masm_, "Global variable"); 3959 Comment cmnt(masm_, "Global variable");
3960 __ Move(rcx, proxy->name()); 3960 __ Move(rcx, proxy->name());
3961 __ movq(rax, GlobalObjectOperand()); 3961 __ movq(rax, GlobalObjectOperand());
3962 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 3962 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
3963 // Use a regular load, not a contextual load, to avoid a reference 3963 // Use a regular load, not a contextual load, to avoid a reference
3964 // error. 3964 // error.
3965 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3965 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
3966 PrepareForBailout(expr, TOS_REG); 3966 PrepareForBailout(expr, TOS_REG);
3967 context()->Plug(rax); 3967 context()->Plug(rax);
3968 } else if (proxy != NULL && 3968 } else if (proxy != NULL &&
3969 proxy->var()->AsSlot() != NULL && 3969 proxy->var()->AsSlot() != NULL &&
3970 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { 3970 proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
3971 Label done, slow; 3971 Label done, slow;
3972 3972
3973 // Generate code for loading from variables potentially shadowed 3973 // Generate code for loading from variables potentially shadowed
3974 // by eval-introduced variables. 3974 // by eval-introduced variables.
3975 Slot* slot = proxy->var()->AsSlot(); 3975 Slot* slot = proxy->var()->AsSlot();
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
4317 __ ret(0); 4317 __ ret(0);
4318 } 4318 }
4319 4319
4320 4320
4321 #undef __ 4321 #undef __
4322 4322
4323 4323
4324 } } // namespace v8::internal 4324 } } // namespace v8::internal
4325 4325
4326 #endif // V8_TARGET_ARCH_X64 4326 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698