| OLD | NEW |
| 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 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 VisitForAccumulatorValue(function); | 733 VisitForAccumulatorValue(function); |
| 734 __ pop(rdx); | 734 __ pop(rdx); |
| 735 } else { | 735 } else { |
| 736 __ movq(rdx, rax); | 736 __ movq(rdx, rax); |
| 737 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex); | 737 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex); |
| 738 } | 738 } |
| 739 ASSERT(prop->key()->AsLiteral() != NULL && | 739 ASSERT(prop->key()->AsLiteral() != NULL && |
| 740 prop->key()->AsLiteral()->handle()->IsSmi()); | 740 prop->key()->AsLiteral()->handle()->IsSmi()); |
| 741 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 741 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 742 | 742 |
| 743 Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode() | 743 Builtins::Name builtin = is_strict_mode() |
| 744 ? Builtins::KeyedStoreIC_Initialize_Strict | 744 ? Builtins::KeyedStoreIC_Initialize_Strict |
| 745 : Builtins::KeyedStoreIC_Initialize)); | 745 : Builtins::KeyedStoreIC_Initialize; |
| 746 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 746 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 747 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 747 } | 748 } |
| 748 } | 749 } |
| 749 } | 750 } |
| 750 | 751 |
| 751 | 752 |
| 752 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 753 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 753 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 754 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
| 754 } | 755 } |
| 755 | 756 |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1114 __ movq(temp, ContextOperand(temp, Context::CLOSURE_INDEX)); | 1115 __ movq(temp, ContextOperand(temp, Context::CLOSURE_INDEX)); |
| 1115 __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset)); | 1116 __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset)); |
| 1116 __ jmp(&next); | 1117 __ jmp(&next); |
| 1117 __ bind(&fast); | 1118 __ bind(&fast); |
| 1118 } | 1119 } |
| 1119 | 1120 |
| 1120 // All extension objects were empty and it is safe to use a global | 1121 // All extension objects were empty and it is safe to use a global |
| 1121 // load IC call. | 1122 // load IC call. |
| 1122 __ movq(rax, GlobalObjectOperand()); | 1123 __ movq(rax, GlobalObjectOperand()); |
| 1123 __ Move(rcx, slot->var()->name()); | 1124 __ Move(rcx, slot->var()->name()); |
| 1124 Handle<Code> ic(isolate()->builtins()->builtin( | 1125 Handle<Code> ic = |
| 1125 Builtins::LoadIC_Initialize)); | 1126 Builtins::builtin(Builtins::LoadIC_Initialize, isolate()); |
| 1126 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1127 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
| 1127 ? RelocInfo::CODE_TARGET | 1128 ? RelocInfo::CODE_TARGET |
| 1128 : RelocInfo::CODE_TARGET_CONTEXT; | 1129 : RelocInfo::CODE_TARGET_CONTEXT; |
| 1129 EmitCallIC(ic, mode); | 1130 EmitCallIC(ic, mode); |
| 1130 } | 1131 } |
| 1131 | 1132 |
| 1132 | 1133 |
| 1133 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( | 1134 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( |
| 1134 Slot* slot, | 1135 Slot* slot, |
| 1135 Label* slow) { | 1136 Label* slow) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1198 key_literal != NULL && | 1199 key_literal != NULL && |
| 1199 obj_proxy->IsArguments() && | 1200 obj_proxy->IsArguments() && |
| 1200 key_literal->handle()->IsSmi()) { | 1201 key_literal->handle()->IsSmi()) { |
| 1201 // Load arguments object if there are no eval-introduced | 1202 // Load arguments object if there are no eval-introduced |
| 1202 // variables. Then load the argument from the arguments | 1203 // variables. Then load the argument from the arguments |
| 1203 // object using keyed load. | 1204 // object using keyed load. |
| 1204 __ movq(rdx, | 1205 __ movq(rdx, |
| 1205 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1206 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
| 1206 slow)); | 1207 slow)); |
| 1207 __ Move(rax, key_literal->handle()); | 1208 __ Move(rax, key_literal->handle()); |
| 1208 Handle<Code> ic(isolate()->builtins()->builtin( | 1209 Handle<Code> ic = |
| 1209 Builtins::KeyedLoadIC_Initialize)); | 1210 Builtins::builtin(Builtins::KeyedLoadIC_Initialize, isolate()); |
| 1210 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1211 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1211 __ jmp(done); | 1212 __ jmp(done); |
| 1212 } | 1213 } |
| 1213 } | 1214 } |
| 1214 } | 1215 } |
| 1215 } | 1216 } |
| 1216 } | 1217 } |
| 1217 | 1218 |
| 1218 | 1219 |
| 1219 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1220 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
| 1220 // Four cases: non-this global variables, lookup slots, all other | 1221 // Four cases: non-this global variables, lookup slots, all other |
| 1221 // types of slots, and parameters that rewrite to explicit property | 1222 // types of slots, and parameters that rewrite to explicit property |
| 1222 // accesses on the arguments object. | 1223 // accesses on the arguments object. |
| 1223 Slot* slot = var->AsSlot(); | 1224 Slot* slot = var->AsSlot(); |
| 1224 Property* property = var->AsProperty(); | 1225 Property* property = var->AsProperty(); |
| 1225 | 1226 |
| 1226 if (var->is_global() && !var->is_this()) { | 1227 if (var->is_global() && !var->is_this()) { |
| 1227 Comment cmnt(masm_, "Global variable"); | 1228 Comment cmnt(masm_, "Global variable"); |
| 1228 // Use inline caching. Variable name is passed in rcx and the global | 1229 // Use inline caching. Variable name is passed in rcx and the global |
| 1229 // object on the stack. | 1230 // object on the stack. |
| 1230 __ Move(rcx, var->name()); | 1231 __ Move(rcx, var->name()); |
| 1231 __ movq(rax, GlobalObjectOperand()); | 1232 __ movq(rax, GlobalObjectOperand()); |
| 1232 Handle<Code> ic(isolate()->builtins()->builtin( | 1233 Handle<Code> ic = |
| 1233 Builtins::LoadIC_Initialize)); | 1234 Builtins::builtin(Builtins::LoadIC_Initialize, isolate()); |
| 1234 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1235 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1235 context()->Plug(rax); | 1236 context()->Plug(rax); |
| 1236 | 1237 |
| 1237 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1238 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 1238 Label done, slow; | 1239 Label done, slow; |
| 1239 | 1240 |
| 1240 // Generate code for loading from variables potentially shadowed | 1241 // Generate code for loading from variables potentially shadowed |
| 1241 // by eval-introduced variables. | 1242 // by eval-introduced variables. |
| 1242 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1243 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1243 | 1244 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1286 | 1287 |
| 1287 // Assert that the key is a smi. | 1288 // Assert that the key is a smi. |
| 1288 Literal* key_literal = property->key()->AsLiteral(); | 1289 Literal* key_literal = property->key()->AsLiteral(); |
| 1289 ASSERT_NOT_NULL(key_literal); | 1290 ASSERT_NOT_NULL(key_literal); |
| 1290 ASSERT(key_literal->handle()->IsSmi()); | 1291 ASSERT(key_literal->handle()->IsSmi()); |
| 1291 | 1292 |
| 1292 // Load the key. | 1293 // Load the key. |
| 1293 __ Move(rax, key_literal->handle()); | 1294 __ Move(rax, key_literal->handle()); |
| 1294 | 1295 |
| 1295 // Do a keyed property load. | 1296 // Do a keyed property load. |
| 1296 Handle<Code> ic(isolate()->builtins()->builtin( | 1297 Handle<Code> ic = |
| 1297 Builtins::KeyedLoadIC_Initialize)); | 1298 Builtins::builtin(Builtins::KeyedLoadIC_Initialize, isolate()); |
| 1298 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1299 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1299 context()->Plug(rax); | 1300 context()->Plug(rax); |
| 1300 } | 1301 } |
| 1301 } | 1302 } |
| 1302 | 1303 |
| 1303 | 1304 |
| 1304 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1305 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 1305 Comment cmnt(masm_, "[ RegExpLiteral"); | 1306 Comment cmnt(masm_, "[ RegExpLiteral"); |
| 1306 Label materialized; | 1307 Label materialized; |
| 1307 // Registers will be used as follows: | 1308 // Registers will be used as follows: |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1398 UNREACHABLE(); | 1399 UNREACHABLE(); |
| 1399 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1400 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1400 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 1401 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
| 1401 // Fall through. | 1402 // Fall through. |
| 1402 case ObjectLiteral::Property::COMPUTED: | 1403 case ObjectLiteral::Property::COMPUTED: |
| 1403 if (key->handle()->IsSymbol()) { | 1404 if (key->handle()->IsSymbol()) { |
| 1404 VisitForAccumulatorValue(value); | 1405 VisitForAccumulatorValue(value); |
| 1405 __ Move(rcx, key->handle()); | 1406 __ Move(rcx, key->handle()); |
| 1406 __ movq(rdx, Operand(rsp, 0)); | 1407 __ movq(rdx, Operand(rsp, 0)); |
| 1407 if (property->emit_store()) { | 1408 if (property->emit_store()) { |
| 1408 Handle<Code> ic(isolate()->builtins()->builtin( | 1409 Handle<Code> ic = |
| 1409 Builtins::StoreIC_Initialize)); | 1410 Builtins::builtin(Builtins::StoreIC_Initialize, isolate()); |
| 1410 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1411 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1411 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1412 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1412 } | 1413 } |
| 1413 break; | 1414 break; |
| 1414 } | 1415 } |
| 1415 // Fall through. | 1416 // Fall through. |
| 1416 case ObjectLiteral::Property::PROTOTYPE: | 1417 case ObjectLiteral::Property::PROTOTYPE: |
| 1417 __ push(Operand(rsp, 0)); // Duplicate receiver. | 1418 __ push(Operand(rsp, 0)); // Duplicate receiver. |
| 1418 VisitForStackValue(key); | 1419 VisitForStackValue(key); |
| 1419 VisitForStackValue(value); | 1420 VisitForStackValue(value); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1643 EmitKeyedPropertyAssignment(expr); | 1644 EmitKeyedPropertyAssignment(expr); |
| 1644 break; | 1645 break; |
| 1645 } | 1646 } |
| 1646 } | 1647 } |
| 1647 | 1648 |
| 1648 | 1649 |
| 1649 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1650 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1650 SetSourcePosition(prop->position()); | 1651 SetSourcePosition(prop->position()); |
| 1651 Literal* key = prop->key()->AsLiteral(); | 1652 Literal* key = prop->key()->AsLiteral(); |
| 1652 __ Move(rcx, key->handle()); | 1653 __ Move(rcx, key->handle()); |
| 1653 Handle<Code> ic(isolate()->builtins()->builtin( | 1654 Handle<Code> ic = |
| 1654 Builtins::LoadIC_Initialize)); | 1655 Builtins::builtin(Builtins::LoadIC_Initialize, isolate()); |
| 1655 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1656 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1656 } | 1657 } |
| 1657 | 1658 |
| 1658 | 1659 |
| 1659 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1660 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 1660 SetSourcePosition(prop->position()); | 1661 SetSourcePosition(prop->position()); |
| 1661 Handle<Code> ic(isolate()->builtins()->builtin( | 1662 Handle<Code> ic = |
| 1662 Builtins::KeyedLoadIC_Initialize)); | 1663 Builtins::builtin(Builtins::KeyedLoadIC_Initialize, isolate()); |
| 1663 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1664 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1664 } | 1665 } |
| 1665 | 1666 |
| 1666 | 1667 |
| 1667 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, | 1668 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, |
| 1668 Token::Value op, | 1669 Token::Value op, |
| 1669 OverwriteMode mode, | 1670 OverwriteMode mode, |
| 1670 Expression* left, | 1671 Expression* left, |
| 1671 Expression* right) { | 1672 Expression* right) { |
| 1672 // Do combined smi check of the operands. Left operand is on the | 1673 // Do combined smi check of the operands. Left operand is on the |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1758 EffectContext context(this); | 1759 EffectContext context(this); |
| 1759 EmitVariableAssignment(var, Token::ASSIGN); | 1760 EmitVariableAssignment(var, Token::ASSIGN); |
| 1760 break; | 1761 break; |
| 1761 } | 1762 } |
| 1762 case NAMED_PROPERTY: { | 1763 case NAMED_PROPERTY: { |
| 1763 __ push(rax); // Preserve value. | 1764 __ push(rax); // Preserve value. |
| 1764 VisitForAccumulatorValue(prop->obj()); | 1765 VisitForAccumulatorValue(prop->obj()); |
| 1765 __ movq(rdx, rax); | 1766 __ movq(rdx, rax); |
| 1766 __ pop(rax); // Restore value. | 1767 __ pop(rax); // Restore value. |
| 1767 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1768 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 1768 Handle<Code> ic(isolate()->builtins()->builtin( | 1769 Builtins::Name builtin = is_strict_mode() |
| 1769 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1770 ? Builtins::StoreIC_Initialize_Strict |
| 1770 : Builtins::StoreIC_Initialize)); | 1771 : Builtins::StoreIC_Initialize; |
| 1772 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 1771 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1773 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1772 break; | 1774 break; |
| 1773 } | 1775 } |
| 1774 case KEYED_PROPERTY: { | 1776 case KEYED_PROPERTY: { |
| 1775 __ push(rax); // Preserve value. | 1777 __ push(rax); // Preserve value. |
| 1776 if (prop->is_synthetic()) { | 1778 if (prop->is_synthetic()) { |
| 1777 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 1779 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
| 1778 ASSERT(prop->key()->AsLiteral() != NULL); | 1780 ASSERT(prop->key()->AsLiteral() != NULL); |
| 1779 { AccumulatorValueContext for_object(this); | 1781 { AccumulatorValueContext for_object(this); |
| 1780 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 1782 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
| 1781 } | 1783 } |
| 1782 __ movq(rdx, rax); | 1784 __ movq(rdx, rax); |
| 1783 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1785 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 1784 } else { | 1786 } else { |
| 1785 VisitForStackValue(prop->obj()); | 1787 VisitForStackValue(prop->obj()); |
| 1786 VisitForAccumulatorValue(prop->key()); | 1788 VisitForAccumulatorValue(prop->key()); |
| 1787 __ movq(rcx, rax); | 1789 __ movq(rcx, rax); |
| 1788 __ pop(rdx); | 1790 __ pop(rdx); |
| 1789 } | 1791 } |
| 1790 __ pop(rax); // Restore value. | 1792 __ pop(rax); // Restore value. |
| 1791 Handle<Code> ic(isolate()->builtins()->builtin( | 1793 Builtins::Name builtin = is_strict_mode() |
| 1792 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 1794 ? Builtins::KeyedStoreIC_Initialize_Strict |
| 1793 : Builtins::KeyedStoreIC_Initialize)); | 1795 : Builtins::KeyedStoreIC_Initialize; |
| 1796 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 1794 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1797 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1795 break; | 1798 break; |
| 1796 } | 1799 } |
| 1797 } | 1800 } |
| 1798 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1801 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
| 1799 context()->Plug(rax); | 1802 context()->Plug(rax); |
| 1800 } | 1803 } |
| 1801 | 1804 |
| 1802 | 1805 |
| 1803 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1806 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 1804 Token::Value op) { | 1807 Token::Value op) { |
| 1805 // Left-hand sides that rewrite to explicit property accesses do not reach | 1808 // Left-hand sides that rewrite to explicit property accesses do not reach |
| 1806 // here. | 1809 // here. |
| 1807 ASSERT(var != NULL); | 1810 ASSERT(var != NULL); |
| 1808 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1811 ASSERT(var->is_global() || var->AsSlot() != NULL); |
| 1809 | 1812 |
| 1810 if (var->is_global()) { | 1813 if (var->is_global()) { |
| 1811 ASSERT(!var->is_this()); | 1814 ASSERT(!var->is_this()); |
| 1812 // Assignment to a global variable. Use inline caching for the | 1815 // Assignment to a global variable. Use inline caching for the |
| 1813 // assignment. Right-hand-side value is passed in rax, variable name in | 1816 // assignment. Right-hand-side value is passed in rax, variable name in |
| 1814 // rcx, and the global object on the stack. | 1817 // rcx, and the global object on the stack. |
| 1815 __ Move(rcx, var->name()); | 1818 __ Move(rcx, var->name()); |
| 1816 __ movq(rdx, GlobalObjectOperand()); | 1819 __ movq(rdx, GlobalObjectOperand()); |
| 1817 Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode() | 1820 Builtins::Name builtin = is_strict_mode() |
| 1818 ? Builtins::StoreIC_Initialize_Strict | 1821 ? Builtins::StoreIC_Initialize_Strict |
| 1819 : Builtins::StoreIC_Initialize)); | 1822 : Builtins::StoreIC_Initialize; |
| 1823 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 1820 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1824 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1821 | 1825 |
| 1822 } else if (op == Token::INIT_CONST) { | 1826 } else if (op == Token::INIT_CONST) { |
| 1823 // Like var declarations, const declarations are hoisted to function | 1827 // Like var declarations, const declarations are hoisted to function |
| 1824 // scope. However, unlike var initializers, const initializers are able | 1828 // scope. However, unlike var initializers, const initializers are able |
| 1825 // to drill a hole to that function context, even from inside a 'with' | 1829 // to drill a hole to that function context, even from inside a 'with' |
| 1826 // context. We thus bypass the normal static scope lookup. | 1830 // context. We thus bypass the normal static scope lookup. |
| 1827 Slot* slot = var->AsSlot(); | 1831 Slot* slot = var->AsSlot(); |
| 1828 Label skip; | 1832 Label skip; |
| 1829 switch (slot->type()) { | 1833 switch (slot->type()) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1910 } | 1914 } |
| 1911 | 1915 |
| 1912 // Record source code position before IC call. | 1916 // Record source code position before IC call. |
| 1913 SetSourcePosition(expr->position()); | 1917 SetSourcePosition(expr->position()); |
| 1914 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1918 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 1915 if (expr->ends_initialization_block()) { | 1919 if (expr->ends_initialization_block()) { |
| 1916 __ movq(rdx, Operand(rsp, 0)); | 1920 __ movq(rdx, Operand(rsp, 0)); |
| 1917 } else { | 1921 } else { |
| 1918 __ pop(rdx); | 1922 __ pop(rdx); |
| 1919 } | 1923 } |
| 1920 Handle<Code> ic(isolate()->builtins()->builtin( | 1924 Builtins::Name builtin = is_strict_mode() |
| 1921 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1925 ? Builtins::StoreIC_Initialize_Strict |
| 1922 : Builtins::StoreIC_Initialize)); | 1926 : Builtins::StoreIC_Initialize; |
| 1927 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 1923 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1928 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1924 | 1929 |
| 1925 // If the assignment ends an initialization block, revert to fast case. | 1930 // If the assignment ends an initialization block, revert to fast case. |
| 1926 if (expr->ends_initialization_block()) { | 1931 if (expr->ends_initialization_block()) { |
| 1927 __ push(rax); // Result of assignment, saved even if not needed. | 1932 __ push(rax); // Result of assignment, saved even if not needed. |
| 1928 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. | 1933 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. |
| 1929 __ CallRuntime(Runtime::kToFastProperties, 1); | 1934 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1930 __ pop(rax); | 1935 __ pop(rax); |
| 1931 __ Drop(1); | 1936 __ Drop(1); |
| 1932 } | 1937 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1950 } | 1955 } |
| 1951 | 1956 |
| 1952 __ pop(rcx); | 1957 __ pop(rcx); |
| 1953 if (expr->ends_initialization_block()) { | 1958 if (expr->ends_initialization_block()) { |
| 1954 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. | 1959 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. |
| 1955 } else { | 1960 } else { |
| 1956 __ pop(rdx); | 1961 __ pop(rdx); |
| 1957 } | 1962 } |
| 1958 // Record source code position before IC call. | 1963 // Record source code position before IC call. |
| 1959 SetSourcePosition(expr->position()); | 1964 SetSourcePosition(expr->position()); |
| 1960 Handle<Code> ic(isolate()->builtins()->builtin( | 1965 Builtins::Name builtin = is_strict_mode() |
| 1961 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 1966 ? Builtins::KeyedStoreIC_Initialize_Strict |
| 1962 : Builtins::KeyedStoreIC_Initialize)); | 1967 : Builtins::KeyedStoreIC_Initialize; |
| 1968 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 1963 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1969 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1964 | 1970 |
| 1965 // If the assignment ends an initialization block, revert to fast case. | 1971 // If the assignment ends an initialization block, revert to fast case. |
| 1966 if (expr->ends_initialization_block()) { | 1972 if (expr->ends_initialization_block()) { |
| 1967 __ pop(rdx); | 1973 __ pop(rdx); |
| 1968 __ push(rax); // Result of assignment, saved even if not needed. | 1974 __ push(rax); // Result of assignment, saved even if not needed. |
| 1969 __ push(rdx); | 1975 __ push(rdx); |
| 1970 __ CallRuntime(Runtime::kToFastProperties, 1); | 1976 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1971 __ pop(rax); | 1977 __ pop(rax); |
| 1972 } | 1978 } |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2231 MemOperand operand = EmitSlotSearch(slot, rdx); | 2237 MemOperand operand = EmitSlotSearch(slot, rdx); |
| 2232 __ movq(rdx, operand); | 2238 __ movq(rdx, operand); |
| 2233 | 2239 |
| 2234 ASSERT(prop->key()->AsLiteral() != NULL); | 2240 ASSERT(prop->key()->AsLiteral() != NULL); |
| 2235 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2241 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
| 2236 __ Move(rax, prop->key()->AsLiteral()->handle()); | 2242 __ Move(rax, prop->key()->AsLiteral()->handle()); |
| 2237 | 2243 |
| 2238 // Record source code position for IC call. | 2244 // Record source code position for IC call. |
| 2239 SetSourcePosition(prop->position()); | 2245 SetSourcePosition(prop->position()); |
| 2240 | 2246 |
| 2241 Handle<Code> ic(isolate()->builtins()->builtin( | 2247 Handle<Code> ic = |
| 2242 Builtins::KeyedLoadIC_Initialize)); | 2248 Builtins::builtin(Builtins::KeyedLoadIC_Initialize, isolate()); |
| 2243 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2249 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 2244 // Push result (function). | 2250 // Push result (function). |
| 2245 __ push(rax); | 2251 __ push(rax); |
| 2246 // Push Global receiver. | 2252 // Push Global receiver. |
| 2247 __ movq(rcx, GlobalObjectOperand()); | 2253 __ movq(rcx, GlobalObjectOperand()); |
| 2248 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); | 2254 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); |
| 2249 EmitCallWithStub(expr); | 2255 EmitCallWithStub(expr); |
| 2250 } else { | 2256 } else { |
| 2251 { PreservePositionScope scope(masm()->positions_recorder()); | 2257 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2252 VisitForStackValue(prop->obj()); | 2258 VisitForStackValue(prop->obj()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2300 } | 2306 } |
| 2301 | 2307 |
| 2302 // Call the construct call builtin that handles allocation and | 2308 // Call the construct call builtin that handles allocation and |
| 2303 // constructor invocation. | 2309 // constructor invocation. |
| 2304 SetSourcePosition(expr->position()); | 2310 SetSourcePosition(expr->position()); |
| 2305 | 2311 |
| 2306 // Load function and argument count into rdi and rax. | 2312 // Load function and argument count into rdi and rax. |
| 2307 __ Set(rax, arg_count); | 2313 __ Set(rax, arg_count); |
| 2308 __ movq(rdi, Operand(rsp, arg_count * kPointerSize)); | 2314 __ movq(rdi, Operand(rsp, arg_count * kPointerSize)); |
| 2309 | 2315 |
| 2310 Handle<Code> construct_builtin(isolate()->builtins()->builtin( | 2316 Handle<Code> construct_builtin = |
| 2311 Builtins::JSConstructCall)); | 2317 Builtins::builtin(Builtins::JSConstructCall, isolate()); |
| 2312 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); | 2318 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
| 2313 context()->Plug(rax); | 2319 context()->Plug(rax); |
| 2314 } | 2320 } |
| 2315 | 2321 |
| 2316 | 2322 |
| 2317 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { | 2323 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { |
| 2318 ASSERT(args->length() == 1); | 2324 ASSERT(args->length() == 1); |
| 2319 | 2325 |
| 2320 VisitForAccumulatorValue(args->at(0)); | 2326 VisitForAccumulatorValue(args->at(0)); |
| 2321 | 2327 |
| (...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3568 // Perform the assignment as if via '='. | 3574 // Perform the assignment as if via '='. |
| 3569 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3575 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 3570 Token::ASSIGN); | 3576 Token::ASSIGN); |
| 3571 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3577 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3572 context()->Plug(rax); | 3578 context()->Plug(rax); |
| 3573 } | 3579 } |
| 3574 break; | 3580 break; |
| 3575 case NAMED_PROPERTY: { | 3581 case NAMED_PROPERTY: { |
| 3576 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 3582 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 3577 __ pop(rdx); | 3583 __ pop(rdx); |
| 3578 Handle<Code> ic(isolate()->builtins()->builtin( | 3584 Builtins::Name builtin = is_strict_mode() |
| 3579 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 3585 ? Builtins::StoreIC_Initialize_Strict |
| 3580 : Builtins::StoreIC_Initialize)); | 3586 : Builtins::StoreIC_Initialize; |
| 3587 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 3581 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3588 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3582 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3589 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3583 if (expr->is_postfix()) { | 3590 if (expr->is_postfix()) { |
| 3584 if (!context()->IsEffect()) { | 3591 if (!context()->IsEffect()) { |
| 3585 context()->PlugTOS(); | 3592 context()->PlugTOS(); |
| 3586 } | 3593 } |
| 3587 } else { | 3594 } else { |
| 3588 context()->Plug(rax); | 3595 context()->Plug(rax); |
| 3589 } | 3596 } |
| 3590 break; | 3597 break; |
| 3591 } | 3598 } |
| 3592 case KEYED_PROPERTY: { | 3599 case KEYED_PROPERTY: { |
| 3593 __ pop(rcx); | 3600 __ pop(rcx); |
| 3594 __ pop(rdx); | 3601 __ pop(rdx); |
| 3595 Handle<Code> ic(isolate()->builtins()->builtin( | 3602 Builtins::Name builtin = is_strict_mode() |
| 3596 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 3603 ? Builtins::KeyedStoreIC_Initialize_Strict |
| 3597 : Builtins::KeyedStoreIC_Initialize)); | 3604 : Builtins::KeyedStoreIC_Initialize; |
| 3605 Handle<Code> ic = Builtins::builtin(builtin, isolate()); |
| 3598 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3606 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3599 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3607 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3600 if (expr->is_postfix()) { | 3608 if (expr->is_postfix()) { |
| 3601 if (!context()->IsEffect()) { | 3609 if (!context()->IsEffect()) { |
| 3602 context()->PlugTOS(); | 3610 context()->PlugTOS(); |
| 3603 } | 3611 } |
| 3604 } else { | 3612 } else { |
| 3605 context()->Plug(rax); | 3613 context()->Plug(rax); |
| 3606 } | 3614 } |
| 3607 break; | 3615 break; |
| 3608 } | 3616 } |
| 3609 } | 3617 } |
| 3610 } | 3618 } |
| 3611 | 3619 |
| 3612 | 3620 |
| 3613 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3621 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 3614 VariableProxy* proxy = expr->AsVariableProxy(); | 3622 VariableProxy* proxy = expr->AsVariableProxy(); |
| 3615 ASSERT(!context()->IsEffect()); | 3623 ASSERT(!context()->IsEffect()); |
| 3616 ASSERT(!context()->IsTest()); | 3624 ASSERT(!context()->IsTest()); |
| 3617 | 3625 |
| 3618 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3626 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
| 3619 Comment cmnt(masm_, "Global variable"); | 3627 Comment cmnt(masm_, "Global variable"); |
| 3620 __ Move(rcx, proxy->name()); | 3628 __ Move(rcx, proxy->name()); |
| 3621 __ movq(rax, GlobalObjectOperand()); | 3629 __ movq(rax, GlobalObjectOperand()); |
| 3622 Handle<Code> ic(isolate()->builtins()->builtin( | 3630 Handle<Code> ic = Builtins::builtin(Builtins::LoadIC_Initialize, isolate()); |
| 3623 Builtins::LoadIC_Initialize)); | |
| 3624 // Use a regular load, not a contextual load, to avoid a reference | 3631 // Use a regular load, not a contextual load, to avoid a reference |
| 3625 // error. | 3632 // error. |
| 3626 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3633 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3627 PrepareForBailout(expr, TOS_REG); | 3634 PrepareForBailout(expr, TOS_REG); |
| 3628 context()->Plug(rax); | 3635 context()->Plug(rax); |
| 3629 } else if (proxy != NULL && | 3636 } else if (proxy != NULL && |
| 3630 proxy->var()->AsSlot() != NULL && | 3637 proxy->var()->AsSlot() != NULL && |
| 3631 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3638 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
| 3632 Label done, slow; | 3639 Label done, slow; |
| 3633 | 3640 |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3996 __ ret(0); | 4003 __ ret(0); |
| 3997 } | 4004 } |
| 3998 | 4005 |
| 3999 | 4006 |
| 4000 #undef __ | 4007 #undef __ |
| 4001 | 4008 |
| 4002 | 4009 |
| 4003 } } // namespace v8::internal | 4010 } } // namespace v8::internal |
| 4004 | 4011 |
| 4005 #endif // V8_TARGET_ARCH_X64 | 4012 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |