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

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

Issue 9403009: Count ICs that have type information. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/heap.cc ('k') | src/ic.h » ('j') | src/ic.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/heap.cc ('k') | src/ic.h » ('j') | src/ic.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698