Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 869 __ cmp(edx, eax); | 869 __ cmp(edx, eax); |
| 870 __ j(not_equal, &next_test); | 870 __ j(not_equal, &next_test); |
| 871 __ Drop(1); // Switch value is no longer needed. | 871 __ Drop(1); // Switch value is no longer needed. |
| 872 __ jmp(clause->body_target()); | 872 __ jmp(clause->body_target()); |
| 873 __ bind(&slow_case); | 873 __ bind(&slow_case); |
| 874 } | 874 } |
| 875 | 875 |
| 876 // Record position before stub call for type feedback. | 876 // Record position before stub call for type feedback. |
| 877 SetSourcePosition(clause->position()); | 877 SetSourcePosition(clause->position()); |
| 878 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); | 878 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); |
| 879 info_->increment_number_of_ics(); | |
| 879 __ call(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 880 __ call(ic, RelocInfo::CODE_TARGET, clause->CompareId()); |
| 880 patch_site.EmitPatchInfo(); | 881 patch_site.EmitPatchInfo(); |
| 881 __ test(eax, eax); | 882 __ test(eax, eax); |
| 882 __ j(not_equal, &next_test); | 883 __ j(not_equal, &next_test); |
| 883 __ Drop(1); // Switch value is no longer needed. | 884 __ Drop(1); // Switch value is no longer needed. |
| 884 __ jmp(clause->body_target()); | 885 __ jmp(clause->body_target()); |
| 885 } | 886 } |
| 886 | 887 |
| 887 // Discard the test value and jump to the default if present, otherwise to | 888 // Discard the test value and jump to the default if present, otherwise to |
| 888 // the end of the statement. | 889 // the end of the statement. |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1179 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); | 1180 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); |
| 1180 __ jmp(&next); | 1181 __ jmp(&next); |
| 1181 __ bind(&fast); | 1182 __ bind(&fast); |
| 1182 } | 1183 } |
| 1183 | 1184 |
| 1184 // All extension objects were empty and it is safe to use a global | 1185 // All extension objects were empty and it is safe to use a global |
| 1185 // load IC call. | 1186 // load IC call. |
| 1186 __ mov(eax, GlobalObjectOperand()); | 1187 __ mov(eax, GlobalObjectOperand()); |
| 1187 __ mov(ecx, var->name()); | 1188 __ mov(ecx, var->name()); |
| 1188 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1189 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1190 info_->increment_number_of_ics(); | |
| 1189 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1191 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
| 1190 ? RelocInfo::CODE_TARGET | 1192 ? RelocInfo::CODE_TARGET |
| 1191 : RelocInfo::CODE_TARGET_CONTEXT; | 1193 : RelocInfo::CODE_TARGET_CONTEXT; |
| 1192 __ call(ic, mode); | 1194 __ call(ic, mode); |
| 1193 } | 1195 } |
| 1194 | 1196 |
| 1195 | 1197 |
| 1196 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1198 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
| 1197 Label* slow) { | 1199 Label* slow) { |
| 1198 ASSERT(var->IsContextSlot()); | 1200 ASSERT(var->IsContextSlot()); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1263 // Three cases: global variables, lookup variables, and all other types of | 1265 // Three cases: global variables, lookup variables, and all other types of |
| 1264 // variables. | 1266 // variables. |
| 1265 switch (var->location()) { | 1267 switch (var->location()) { |
| 1266 case Variable::UNALLOCATED: { | 1268 case Variable::UNALLOCATED: { |
| 1267 Comment cmnt(masm_, "Global variable"); | 1269 Comment cmnt(masm_, "Global variable"); |
| 1268 // Use inline caching. Variable name is passed in ecx and the global | 1270 // Use inline caching. Variable name is passed in ecx and the global |
| 1269 // object in eax. | 1271 // object in eax. |
| 1270 __ mov(eax, GlobalObjectOperand()); | 1272 __ mov(eax, GlobalObjectOperand()); |
| 1271 __ mov(ecx, var->name()); | 1273 __ mov(ecx, var->name()); |
| 1272 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1274 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1275 info_->increment_number_of_ics(); | |
| 1273 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1276 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1274 context()->Plug(eax); | 1277 context()->Plug(eax); |
| 1275 break; | 1278 break; |
| 1276 } | 1279 } |
| 1277 | 1280 |
| 1278 case Variable::PARAMETER: | 1281 case Variable::PARAMETER: |
| 1279 case Variable::LOCAL: | 1282 case Variable::LOCAL: |
| 1280 case Variable::CONTEXT: { | 1283 case Variable::CONTEXT: { |
| 1281 Comment cmnt(masm_, var->IsContextSlot() | 1284 Comment cmnt(masm_, var->IsContextSlot() |
| 1282 ? "Context variable" | 1285 ? "Context variable" |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1463 // Fall through. | 1466 // Fall through. |
| 1464 case ObjectLiteral::Property::COMPUTED: | 1467 case ObjectLiteral::Property::COMPUTED: |
| 1465 if (key->handle()->IsSymbol()) { | 1468 if (key->handle()->IsSymbol()) { |
| 1466 if (property->emit_store()) { | 1469 if (property->emit_store()) { |
| 1467 VisitForAccumulatorValue(value); | 1470 VisitForAccumulatorValue(value); |
| 1468 __ mov(ecx, Immediate(key->handle())); | 1471 __ mov(ecx, Immediate(key->handle())); |
| 1469 __ mov(edx, Operand(esp, 0)); | 1472 __ mov(edx, Operand(esp, 0)); |
| 1470 Handle<Code> ic = is_classic_mode() | 1473 Handle<Code> ic = is_classic_mode() |
| 1471 ? isolate()->builtins()->StoreIC_Initialize() | 1474 ? isolate()->builtins()->StoreIC_Initialize() |
| 1472 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 1475 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
| 1476 info_->increment_number_of_ics(); | |
| 1473 __ call(ic, RelocInfo::CODE_TARGET, key->id()); | 1477 __ call(ic, RelocInfo::CODE_TARGET, key->id()); |
| 1474 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1478 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1475 } else { | 1479 } else { |
| 1476 VisitForEffect(value); | 1480 VisitForEffect(value); |
| 1477 } | 1481 } |
| 1478 break; | 1482 break; |
| 1479 } | 1483 } |
| 1480 // Fall through. | 1484 // Fall through. |
| 1481 case ObjectLiteral::Property::PROTOTYPE: | 1485 case ObjectLiteral::Property::PROTOTYPE: |
| 1482 __ push(Operand(esp, 0)); // Duplicate receiver. | 1486 __ push(Operand(esp, 0)); // Duplicate receiver. |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1727 } | 1731 } |
| 1728 } | 1732 } |
| 1729 | 1733 |
| 1730 | 1734 |
| 1731 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1735 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1732 SetSourcePosition(prop->position()); | 1736 SetSourcePosition(prop->position()); |
| 1733 Literal* key = prop->key()->AsLiteral(); | 1737 Literal* key = prop->key()->AsLiteral(); |
| 1734 ASSERT(!key->handle()->IsSmi()); | 1738 ASSERT(!key->handle()->IsSmi()); |
| 1735 __ mov(ecx, Immediate(key->handle())); | 1739 __ mov(ecx, Immediate(key->handle())); |
| 1736 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1740 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1741 info_->increment_number_of_ics(); | |
| 1737 __ call(ic, RelocInfo::CODE_TARGET, prop->id()); | 1742 __ call(ic, RelocInfo::CODE_TARGET, prop->id()); |
| 1738 } | 1743 } |
| 1739 | 1744 |
| 1740 | 1745 |
| 1741 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1746 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 1742 SetSourcePosition(prop->position()); | 1747 SetSourcePosition(prop->position()); |
| 1743 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1748 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1749 info_->increment_number_of_ics(); | |
| 1744 __ call(ic, RelocInfo::CODE_TARGET, prop->id()); | 1750 __ call(ic, RelocInfo::CODE_TARGET, prop->id()); |
| 1745 } | 1751 } |
| 1746 | 1752 |
| 1747 | 1753 |
| 1748 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1754 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 1749 Token::Value op, | 1755 Token::Value op, |
| 1750 OverwriteMode mode, | 1756 OverwriteMode mode, |
| 1751 Expression* left, | 1757 Expression* left, |
| 1752 Expression* right) { | 1758 Expression* right) { |
| 1753 // Do combined smi check of the operands. Left operand is on the | 1759 // Do combined smi check of the operands. Left operand is on the |
| 1754 // stack. Right operand is in eax. | 1760 // stack. Right operand is in eax. |
| 1755 Label smi_case, done, stub_call; | 1761 Label smi_case, done, stub_call; |
| 1756 __ pop(edx); | 1762 __ pop(edx); |
| 1757 __ mov(ecx, eax); | 1763 __ mov(ecx, eax); |
| 1758 __ or_(eax, edx); | 1764 __ or_(eax, edx); |
| 1759 JumpPatchSite patch_site(masm_); | 1765 JumpPatchSite patch_site(masm_); |
| 1760 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); | 1766 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); |
| 1761 | 1767 |
| 1762 __ bind(&stub_call); | 1768 __ bind(&stub_call); |
| 1763 __ mov(eax, ecx); | 1769 __ mov(eax, ecx); |
| 1764 BinaryOpStub stub(op, mode); | 1770 BinaryOpStub stub(op, mode); |
| 1771 info_->increment_number_of_ics(); | |
| 1765 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1772 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
| 1766 patch_site.EmitPatchInfo(); | 1773 patch_site.EmitPatchInfo(); |
| 1767 __ jmp(&done, Label::kNear); | 1774 __ jmp(&done, Label::kNear); |
| 1768 | 1775 |
| 1769 // Smi case. | 1776 // Smi case. |
| 1770 __ bind(&smi_case); | 1777 __ bind(&smi_case); |
| 1771 __ mov(eax, edx); // Copy left operand in case of a stub call. | 1778 __ mov(eax, edx); // Copy left operand in case of a stub call. |
| 1772 | 1779 |
| 1773 switch (op) { | 1780 switch (op) { |
| 1774 case Token::SAR: | 1781 case Token::SAR: |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1840 context()->Plug(eax); | 1847 context()->Plug(eax); |
| 1841 } | 1848 } |
| 1842 | 1849 |
| 1843 | 1850 |
| 1844 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 1851 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
| 1845 Token::Value op, | 1852 Token::Value op, |
| 1846 OverwriteMode mode) { | 1853 OverwriteMode mode) { |
| 1847 __ pop(edx); | 1854 __ pop(edx); |
| 1848 BinaryOpStub stub(op, mode); | 1855 BinaryOpStub stub(op, mode); |
| 1849 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 1856 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 1857 info_->increment_number_of_ics(); | |
| 1850 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1858 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
| 1851 patch_site.EmitPatchInfo(); | 1859 patch_site.EmitPatchInfo(); |
| 1852 context()->Plug(eax); | 1860 context()->Plug(eax); |
| 1853 } | 1861 } |
| 1854 | 1862 |
| 1855 | 1863 |
| 1856 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { | 1864 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { |
| 1857 // Invalid left-hand sides are rewritten to have a 'throw | 1865 // Invalid left-hand sides are rewritten to have a 'throw |
| 1858 // ReferenceError' on the left-hand side. | 1866 // ReferenceError' on the left-hand side. |
| 1859 if (!expr->IsValidLeftHandSide()) { | 1867 if (!expr->IsValidLeftHandSide()) { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1881 } | 1889 } |
| 1882 case NAMED_PROPERTY: { | 1890 case NAMED_PROPERTY: { |
| 1883 __ push(eax); // Preserve value. | 1891 __ push(eax); // Preserve value. |
| 1884 VisitForAccumulatorValue(prop->obj()); | 1892 VisitForAccumulatorValue(prop->obj()); |
| 1885 __ mov(edx, eax); | 1893 __ mov(edx, eax); |
| 1886 __ pop(eax); // Restore value. | 1894 __ pop(eax); // Restore value. |
| 1887 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1895 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 1888 Handle<Code> ic = is_classic_mode() | 1896 Handle<Code> ic = is_classic_mode() |
| 1889 ? isolate()->builtins()->StoreIC_Initialize() | 1897 ? isolate()->builtins()->StoreIC_Initialize() |
| 1890 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 1898 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
| 1899 info_->increment_number_of_ics(); | |
| 1891 __ call(ic); | 1900 __ call(ic); |
| 1892 break; | 1901 break; |
| 1893 } | 1902 } |
| 1894 case KEYED_PROPERTY: { | 1903 case KEYED_PROPERTY: { |
| 1895 __ push(eax); // Preserve value. | 1904 __ push(eax); // Preserve value. |
| 1896 VisitForStackValue(prop->obj()); | 1905 VisitForStackValue(prop->obj()); |
| 1897 VisitForAccumulatorValue(prop->key()); | 1906 VisitForAccumulatorValue(prop->key()); |
| 1898 __ mov(ecx, eax); | 1907 __ mov(ecx, eax); |
| 1899 __ pop(edx); | 1908 __ pop(edx); |
| 1900 __ pop(eax); // Restore value. | 1909 __ pop(eax); // Restore value. |
| 1901 Handle<Code> ic = is_classic_mode() | 1910 Handle<Code> ic = is_classic_mode() |
| 1902 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 1911 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 1903 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 1912 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 1913 info_->increment_number_of_ics(); | |
| 1904 __ call(ic); | 1914 __ call(ic); |
| 1905 break; | 1915 break; |
| 1906 } | 1916 } |
| 1907 } | 1917 } |
| 1908 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1918 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
| 1909 context()->Plug(eax); | 1919 context()->Plug(eax); |
| 1910 } | 1920 } |
| 1911 | 1921 |
| 1912 | 1922 |
| 1913 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1923 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 1914 Token::Value op) { | 1924 Token::Value op) { |
| 1915 if (var->IsUnallocated()) { | 1925 if (var->IsUnallocated()) { |
| 1916 // Global var, const, or let. | 1926 // Global var, const, or let. |
| 1917 __ mov(ecx, var->name()); | 1927 __ mov(ecx, var->name()); |
| 1918 __ mov(edx, GlobalObjectOperand()); | 1928 __ mov(edx, GlobalObjectOperand()); |
| 1919 Handle<Code> ic = is_classic_mode() | 1929 Handle<Code> ic = is_classic_mode() |
| 1920 ? isolate()->builtins()->StoreIC_Initialize() | 1930 ? isolate()->builtins()->StoreIC_Initialize() |
| 1921 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 1931 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
| 1932 info_->increment_number_of_ics(); | |
| 1922 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1933 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1923 | 1934 |
| 1924 } else if (op == Token::INIT_CONST) { | 1935 } else if (op == Token::INIT_CONST) { |
| 1925 // Const initializers need a write barrier. | 1936 // Const initializers need a write barrier. |
| 1926 ASSERT(!var->IsParameter()); // No const parameters. | 1937 ASSERT(!var->IsParameter()); // No const parameters. |
| 1927 if (var->IsStackLocal()) { | 1938 if (var->IsStackLocal()) { |
| 1928 Label skip; | 1939 Label skip; |
| 1929 __ mov(edx, StackOperand(var)); | 1940 __ mov(edx, StackOperand(var)); |
| 1930 __ cmp(edx, isolate()->factory()->the_hole_value()); | 1941 __ cmp(edx, isolate()->factory()->the_hole_value()); |
| 1931 __ j(not_equal, &skip); | 1942 __ j(not_equal, &skip); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2021 SetSourcePosition(expr->position()); | 2032 SetSourcePosition(expr->position()); |
| 2022 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 2033 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 2023 if (expr->ends_initialization_block()) { | 2034 if (expr->ends_initialization_block()) { |
| 2024 __ mov(edx, Operand(esp, 0)); | 2035 __ mov(edx, Operand(esp, 0)); |
| 2025 } else { | 2036 } else { |
| 2026 __ pop(edx); | 2037 __ pop(edx); |
| 2027 } | 2038 } |
| 2028 Handle<Code> ic = is_classic_mode() | 2039 Handle<Code> ic = is_classic_mode() |
| 2029 ? isolate()->builtins()->StoreIC_Initialize() | 2040 ? isolate()->builtins()->StoreIC_Initialize() |
| 2030 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 2041 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
| 2042 info_->increment_number_of_ics(); | |
| 2031 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); | 2043 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 2032 | 2044 |
| 2033 // If the assignment ends an initialization block, revert to fast case. | 2045 // If the assignment ends an initialization block, revert to fast case. |
| 2034 if (expr->ends_initialization_block()) { | 2046 if (expr->ends_initialization_block()) { |
| 2035 __ push(eax); // Result of assignment, saved even if not needed. | 2047 __ push(eax); // Result of assignment, saved even if not needed. |
| 2036 __ push(Operand(esp, kPointerSize)); // Receiver is under value. | 2048 __ push(Operand(esp, kPointerSize)); // Receiver is under value. |
| 2037 __ CallRuntime(Runtime::kToFastProperties, 1); | 2049 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2038 __ pop(eax); | 2050 __ pop(eax); |
| 2039 __ Drop(1); | 2051 __ Drop(1); |
| 2040 } | 2052 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 2061 if (expr->ends_initialization_block()) { | 2073 if (expr->ends_initialization_block()) { |
| 2062 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. | 2074 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. |
| 2063 } else { | 2075 } else { |
| 2064 __ pop(edx); | 2076 __ pop(edx); |
| 2065 } | 2077 } |
| 2066 // Record source code position before IC call. | 2078 // Record source code position before IC call. |
| 2067 SetSourcePosition(expr->position()); | 2079 SetSourcePosition(expr->position()); |
| 2068 Handle<Code> ic = is_classic_mode() | 2080 Handle<Code> ic = is_classic_mode() |
| 2069 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2081 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2070 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2082 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2083 info_->increment_number_of_ics(); | |
| 2071 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); | 2084 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 2072 | 2085 |
| 2073 // If the assignment ends an initialization block, revert to fast case. | 2086 // If the assignment ends an initialization block, revert to fast case. |
| 2074 if (expr->ends_initialization_block()) { | 2087 if (expr->ends_initialization_block()) { |
| 2075 __ pop(edx); | 2088 __ pop(edx); |
| 2076 __ push(eax); // Result of assignment, saved even if not needed. | 2089 __ push(eax); // Result of assignment, saved even if not needed. |
| 2077 __ push(edx); | 2090 __ push(edx); |
| 2078 __ CallRuntime(Runtime::kToFastProperties, 1); | 2091 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2079 __ pop(eax); | 2092 __ pop(eax); |
| 2080 } | 2093 } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 2111 { PreservePositionScope scope(masm()->positions_recorder()); | 2124 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2112 for (int i = 0; i < arg_count; i++) { | 2125 for (int i = 0; i < arg_count; i++) { |
| 2113 VisitForStackValue(args->at(i)); | 2126 VisitForStackValue(args->at(i)); |
| 2114 } | 2127 } |
| 2115 __ Set(ecx, Immediate(name)); | 2128 __ Set(ecx, Immediate(name)); |
| 2116 } | 2129 } |
| 2117 // Record source position of the IC call. | 2130 // Record source position of the IC call. |
| 2118 SetSourcePosition(expr->position()); | 2131 SetSourcePosition(expr->position()); |
| 2119 Handle<Code> ic = | 2132 Handle<Code> ic = |
| 2120 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 2133 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 2134 info_->increment_number_of_ics(); | |
| 2121 __ call(ic, mode, expr->id()); | 2135 __ call(ic, mode, expr->id()); |
| 2122 RecordJSReturnSite(expr); | 2136 RecordJSReturnSite(expr); |
| 2123 // Restore context register. | 2137 // Restore context register. |
| 2124 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2138 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 2125 context()->Plug(eax); | 2139 context()->Plug(eax); |
| 2126 } | 2140 } |
| 2127 | 2141 |
| 2128 | 2142 |
| 2129 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2143 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 2130 Expression* key) { | 2144 Expression* key) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 2142 int arg_count = args->length(); | 2156 int arg_count = args->length(); |
| 2143 { PreservePositionScope scope(masm()->positions_recorder()); | 2157 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2144 for (int i = 0; i < arg_count; i++) { | 2158 for (int i = 0; i < arg_count; i++) { |
| 2145 VisitForStackValue(args->at(i)); | 2159 VisitForStackValue(args->at(i)); |
| 2146 } | 2160 } |
| 2147 } | 2161 } |
| 2148 // Record source position of the IC call. | 2162 // Record source position of the IC call. |
| 2149 SetSourcePosition(expr->position()); | 2163 SetSourcePosition(expr->position()); |
| 2150 Handle<Code> ic = | 2164 Handle<Code> ic = |
| 2151 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2165 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
| 2166 info_->increment_number_of_ics(); | |
| 2152 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. | 2167 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. |
| 2153 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); | 2168 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 2154 RecordJSReturnSite(expr); | 2169 RecordJSReturnSite(expr); |
| 2155 // Restore context register. | 2170 // Restore context register. |
| 2156 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2171 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 2157 context()->DropAndPlug(1, eax); // Drop the key still on the stack. | 2172 context()->DropAndPlug(1, eax); // Drop the key still on the stack. |
| 2158 } | 2173 } |
| 2159 | 2174 |
| 2160 | 2175 |
| 2161 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2176 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
| (...skipping 1568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3730 for (int i = 0; i < arg_count; i++) { | 3745 for (int i = 0; i < arg_count; i++) { |
| 3731 VisitForStackValue(args->at(i)); | 3746 VisitForStackValue(args->at(i)); |
| 3732 } | 3747 } |
| 3733 | 3748 |
| 3734 if (expr->is_jsruntime()) { | 3749 if (expr->is_jsruntime()) { |
| 3735 // Call the JS runtime function via a call IC. | 3750 // Call the JS runtime function via a call IC. |
| 3736 __ Set(ecx, Immediate(expr->name())); | 3751 __ Set(ecx, Immediate(expr->name())); |
| 3737 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 3752 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
| 3738 Handle<Code> ic = | 3753 Handle<Code> ic = |
| 3739 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 3754 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 3755 info_->increment_number_of_ics(); | |
| 3740 __ call(ic, mode, expr->id()); | 3756 __ call(ic, mode, expr->id()); |
| 3741 // Restore context register. | 3757 // Restore context register. |
| 3742 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 3758 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 3743 } else { | 3759 } else { |
| 3744 // Call the C runtime function. | 3760 // Call the C runtime function. |
| 3745 __ CallRuntime(expr->function(), arg_count); | 3761 __ CallRuntime(expr->function(), arg_count); |
| 3746 } | 3762 } |
| 3747 context()->Plug(eax); | 3763 context()->Plug(eax); |
| 3748 } | 3764 } |
| 3749 | 3765 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3884 } | 3900 } |
| 3885 | 3901 |
| 3886 | 3902 |
| 3887 void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr, | 3903 void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr, |
| 3888 const char* comment) { | 3904 const char* comment) { |
| 3889 Comment cmt(masm_, comment); | 3905 Comment cmt(masm_, comment); |
| 3890 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 3906 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); |
| 3891 UnaryOverwriteMode overwrite = | 3907 UnaryOverwriteMode overwrite = |
| 3892 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 3908 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
| 3893 UnaryOpStub stub(expr->op(), overwrite); | 3909 UnaryOpStub stub(expr->op(), overwrite); |
| 3910 info_->increment_number_of_ics(); | |
| 3894 // UnaryOpStub expects the argument to be in the | 3911 // UnaryOpStub expects the argument to be in the |
| 3895 // accumulator register eax. | 3912 // accumulator register eax. |
| 3896 VisitForAccumulatorValue(expr->expression()); | 3913 VisitForAccumulatorValue(expr->expression()); |
| 3897 SetSourcePosition(expr->position()); | 3914 SetSourcePosition(expr->position()); |
| 3898 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 3915 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
| 3899 context()->Plug(eax); | 3916 context()->Plug(eax); |
| 3900 } | 3917 } |
| 3901 | 3918 |
| 3902 | 3919 |
| 3903 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 3920 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4008 } | 4025 } |
| 4009 } | 4026 } |
| 4010 | 4027 |
| 4011 // Record position before stub call. | 4028 // Record position before stub call. |
| 4012 SetSourcePosition(expr->position()); | 4029 SetSourcePosition(expr->position()); |
| 4013 | 4030 |
| 4014 // Call stub for +1/-1. | 4031 // Call stub for +1/-1. |
| 4015 __ mov(edx, eax); | 4032 __ mov(edx, eax); |
| 4016 __ mov(eax, Immediate(Smi::FromInt(1))); | 4033 __ mov(eax, Immediate(Smi::FromInt(1))); |
| 4017 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); | 4034 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); |
| 4035 info_->increment_number_of_ics(); | |
| 4018 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); | 4036 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); |
| 4019 patch_site.EmitPatchInfo(); | 4037 patch_site.EmitPatchInfo(); |
| 4020 __ bind(&done); | 4038 __ bind(&done); |
| 4021 | 4039 |
| 4022 // Store the value returned in eax. | 4040 // Store the value returned in eax. |
| 4023 switch (assign_type) { | 4041 switch (assign_type) { |
| 4024 case VARIABLE: | 4042 case VARIABLE: |
| 4025 if (expr->is_postfix()) { | 4043 if (expr->is_postfix()) { |
| 4026 // Perform the assignment as if via '='. | 4044 // Perform the assignment as if via '='. |
| 4027 { EffectContext context(this); | 4045 { EffectContext context(this); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 4042 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4060 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4043 context()->Plug(eax); | 4061 context()->Plug(eax); |
| 4044 } | 4062 } |
| 4045 break; | 4063 break; |
| 4046 case NAMED_PROPERTY: { | 4064 case NAMED_PROPERTY: { |
| 4047 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 4065 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 4048 __ pop(edx); | 4066 __ pop(edx); |
| 4049 Handle<Code> ic = is_classic_mode() | 4067 Handle<Code> ic = is_classic_mode() |
| 4050 ? isolate()->builtins()->StoreIC_Initialize() | 4068 ? isolate()->builtins()->StoreIC_Initialize() |
| 4051 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 4069 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
| 4070 info_->increment_number_of_ics(); | |
| 4052 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); | 4071 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 4053 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4072 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4054 if (expr->is_postfix()) { | 4073 if (expr->is_postfix()) { |
| 4055 if (!context()->IsEffect()) { | 4074 if (!context()->IsEffect()) { |
| 4056 context()->PlugTOS(); | 4075 context()->PlugTOS(); |
| 4057 } | 4076 } |
| 4058 } else { | 4077 } else { |
| 4059 context()->Plug(eax); | 4078 context()->Plug(eax); |
| 4060 } | 4079 } |
| 4061 break; | 4080 break; |
| 4062 } | 4081 } |
| 4063 case KEYED_PROPERTY: { | 4082 case KEYED_PROPERTY: { |
| 4064 __ pop(ecx); | 4083 __ pop(ecx); |
| 4065 __ pop(edx); | 4084 __ pop(edx); |
| 4066 Handle<Code> ic = is_classic_mode() | 4085 Handle<Code> ic = is_classic_mode() |
| 4067 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4086 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 4068 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4087 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 4088 info_->increment_number_of_ics(); | |
| 4069 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); | 4089 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 4070 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4090 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4071 if (expr->is_postfix()) { | 4091 if (expr->is_postfix()) { |
| 4072 // Result is on the stack | 4092 // Result is on the stack |
| 4073 if (!context()->IsEffect()) { | 4093 if (!context()->IsEffect()) { |
| 4074 context()->PlugTOS(); | 4094 context()->PlugTOS(); |
| 4075 } | 4095 } |
| 4076 } else { | 4096 } else { |
| 4077 context()->Plug(eax); | 4097 context()->Plug(eax); |
| 4078 } | 4098 } |
| 4079 break; | 4099 break; |
| 4080 } | 4100 } |
| 4081 } | 4101 } |
| 4082 } | 4102 } |
| 4083 | 4103 |
| 4084 | 4104 |
| 4085 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4105 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 4086 VariableProxy* proxy = expr->AsVariableProxy(); | 4106 VariableProxy* proxy = expr->AsVariableProxy(); |
| 4087 ASSERT(!context()->IsEffect()); | 4107 ASSERT(!context()->IsEffect()); |
| 4088 ASSERT(!context()->IsTest()); | 4108 ASSERT(!context()->IsTest()); |
| 4089 | 4109 |
| 4090 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4110 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 4091 Comment cmnt(masm_, "Global variable"); | 4111 Comment cmnt(masm_, "Global variable"); |
| 4092 __ mov(eax, GlobalObjectOperand()); | 4112 __ mov(eax, GlobalObjectOperand()); |
| 4093 __ mov(ecx, Immediate(proxy->name())); | 4113 __ mov(ecx, Immediate(proxy->name())); |
| 4094 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 4114 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 4115 info_->increment_number_of_ics(); | |
| 4095 // Use a regular load, not a contextual load, to avoid a reference | 4116 // Use a regular load, not a contextual load, to avoid a reference |
| 4096 // error. | 4117 // error. |
| 4097 __ call(ic); | 4118 __ call(ic); |
| 4098 PrepareForBailout(expr, TOS_REG); | 4119 PrepareForBailout(expr, TOS_REG); |
| 4099 context()->Plug(eax); | 4120 context()->Plug(eax); |
| 4100 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4121 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 4101 Label done, slow; | 4122 Label done, slow; |
| 4102 | 4123 |
| 4103 // Generate code for loading from variables potentially shadowed | 4124 // Generate code for loading from variables potentially shadowed |
| 4104 // by eval-introduced variables. | 4125 // by eval-introduced variables. |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4267 __ or_(ecx, eax); | 4288 __ or_(ecx, eax); |
| 4268 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); | 4289 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); |
| 4269 __ cmp(edx, eax); | 4290 __ cmp(edx, eax); |
| 4270 Split(cc, if_true, if_false, NULL); | 4291 Split(cc, if_true, if_false, NULL); |
| 4271 __ bind(&slow_case); | 4292 __ bind(&slow_case); |
| 4272 } | 4293 } |
| 4273 | 4294 |
| 4274 // Record position and call the compare IC. | 4295 // Record position and call the compare IC. |
| 4275 SetSourcePosition(expr->position()); | 4296 SetSourcePosition(expr->position()); |
| 4276 Handle<Code> ic = CompareIC::GetUninitialized(op); | 4297 Handle<Code> ic = CompareIC::GetUninitialized(op); |
| 4298 info_->increment_number_of_ics(); | |
|
Vyacheslav Egorov (Chromium)
2012/02/15 12:07:39
Please wrap increment and __ call together into a
Jakob Kummerow
2012/02/17 16:07:52
Done.
| |
| 4277 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); | 4299 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 4278 patch_site.EmitPatchInfo(); | 4300 patch_site.EmitPatchInfo(); |
| 4279 | 4301 |
| 4280 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4302 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4281 __ test(eax, eax); | 4303 __ test(eax, eax); |
| 4282 Split(cc, if_true, if_false, fall_through); | 4304 Split(cc, if_true, if_false, fall_through); |
| 4283 } | 4305 } |
| 4284 } | 4306 } |
| 4285 | 4307 |
| 4286 // Convert the result of the comparison into one expected for this | 4308 // Convert the result of the comparison into one expected for this |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4426 *context_length = 0; | 4448 *context_length = 0; |
| 4427 return previous_; | 4449 return previous_; |
| 4428 } | 4450 } |
| 4429 | 4451 |
| 4430 | 4452 |
| 4431 #undef __ | 4453 #undef __ |
| 4432 | 4454 |
| 4433 } } // namespace v8::internal | 4455 } } // namespace v8::internal |
| 4434 | 4456 |
| 4435 #endif // V8_TARGET_ARCH_IA32 | 4457 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |