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