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

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: fix confusing --trace-opt output 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/objects-inl.h » ('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 __ call(ic, RelocInfo::CODE_TARGET, clause->CompareId()); 879 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId());
880 patch_site.EmitPatchInfo(); 880 patch_site.EmitPatchInfo();
881 __ test(eax, eax); 881 __ test(eax, eax);
882 __ j(not_equal, &next_test); 882 __ j(not_equal, &next_test);
883 __ Drop(1); // Switch value is no longer needed. 883 __ Drop(1); // Switch value is no longer needed.
884 __ jmp(clause->body_target()); 884 __ jmp(clause->body_target());
885 } 885 }
886 886
887 // Discard the test value and jump to the default if present, otherwise to 887 // Discard the test value and jump to the default if present, otherwise to
888 // the end of the statement. 888 // the end of the statement.
889 __ bind(&next_test); 889 __ bind(&next_test);
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 } 1182 }
1183 1183
1184 // All extension objects were empty and it is safe to use a global 1184 // All extension objects were empty and it is safe to use a global
1185 // load IC call. 1185 // load IC call.
1186 __ mov(eax, GlobalObjectOperand()); 1186 __ mov(eax, GlobalObjectOperand());
1187 __ mov(ecx, var->name()); 1187 __ mov(ecx, var->name());
1188 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1188 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1189 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 1189 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
1190 ? RelocInfo::CODE_TARGET 1190 ? RelocInfo::CODE_TARGET
1191 : RelocInfo::CODE_TARGET_CONTEXT; 1191 : RelocInfo::CODE_TARGET_CONTEXT;
1192 __ call(ic, mode); 1192 CallIC(ic, mode);
1193 } 1193 }
1194 1194
1195 1195
1196 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1196 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1197 Label* slow) { 1197 Label* slow) {
1198 ASSERT(var->IsContextSlot()); 1198 ASSERT(var->IsContextSlot());
1199 Register context = esi; 1199 Register context = esi;
1200 Register temp = ebx; 1200 Register temp = ebx;
1201 1201
1202 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { 1202 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 // Three cases: global variables, lookup variables, and all other types of 1263 // Three cases: global variables, lookup variables, and all other types of
1264 // variables. 1264 // variables.
1265 switch (var->location()) { 1265 switch (var->location()) {
1266 case Variable::UNALLOCATED: { 1266 case Variable::UNALLOCATED: {
1267 Comment cmnt(masm_, "Global variable"); 1267 Comment cmnt(masm_, "Global variable");
1268 // Use inline caching. Variable name is passed in ecx and the global 1268 // Use inline caching. Variable name is passed in ecx and the global
1269 // object in eax. 1269 // object in eax.
1270 __ mov(eax, GlobalObjectOperand()); 1270 __ mov(eax, GlobalObjectOperand());
1271 __ mov(ecx, var->name()); 1271 __ mov(ecx, var->name());
1272 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1272 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1273 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 1273 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1274 context()->Plug(eax); 1274 context()->Plug(eax);
1275 break; 1275 break;
1276 } 1276 }
1277 1277
1278 case Variable::PARAMETER: 1278 case Variable::PARAMETER:
1279 case Variable::LOCAL: 1279 case Variable::LOCAL:
1280 case Variable::CONTEXT: { 1280 case Variable::CONTEXT: {
1281 Comment cmnt(masm_, var->IsContextSlot() 1281 Comment cmnt(masm_, var->IsContextSlot()
1282 ? "Context variable" 1282 ? "Context variable"
1283 : "Stack variable"); 1283 : "Stack variable");
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1463 // Fall through. 1463 // Fall through.
1464 case ObjectLiteral::Property::COMPUTED: 1464 case ObjectLiteral::Property::COMPUTED:
1465 if (key->handle()->IsSymbol()) { 1465 if (key->handle()->IsSymbol()) {
1466 if (property->emit_store()) { 1466 if (property->emit_store()) {
1467 VisitForAccumulatorValue(value); 1467 VisitForAccumulatorValue(value);
1468 __ mov(ecx, Immediate(key->handle())); 1468 __ mov(ecx, Immediate(key->handle()));
1469 __ mov(edx, Operand(esp, 0)); 1469 __ mov(edx, Operand(esp, 0));
1470 Handle<Code> ic = is_classic_mode() 1470 Handle<Code> ic = is_classic_mode()
1471 ? isolate()->builtins()->StoreIC_Initialize() 1471 ? isolate()->builtins()->StoreIC_Initialize()
1472 : isolate()->builtins()->StoreIC_Initialize_Strict(); 1472 : isolate()->builtins()->StoreIC_Initialize_Strict();
1473 __ call(ic, RelocInfo::CODE_TARGET, key->id()); 1473 CallIC(ic, RelocInfo::CODE_TARGET, key->id());
1474 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1474 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1475 } else { 1475 } else {
1476 VisitForEffect(value); 1476 VisitForEffect(value);
1477 } 1477 }
1478 break; 1478 break;
1479 } 1479 }
1480 // Fall through. 1480 // Fall through.
1481 case ObjectLiteral::Property::PROTOTYPE: 1481 case ObjectLiteral::Property::PROTOTYPE:
1482 __ push(Operand(esp, 0)); // Duplicate receiver. 1482 __ push(Operand(esp, 0)); // Duplicate receiver.
1483 VisitForStackValue(key); 1483 VisitForStackValue(key);
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 } 1727 }
1728 } 1728 }
1729 1729
1730 1730
1731 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1731 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1732 SetSourcePosition(prop->position()); 1732 SetSourcePosition(prop->position());
1733 Literal* key = prop->key()->AsLiteral(); 1733 Literal* key = prop->key()->AsLiteral();
1734 ASSERT(!key->handle()->IsSmi()); 1734 ASSERT(!key->handle()->IsSmi());
1735 __ mov(ecx, Immediate(key->handle())); 1735 __ mov(ecx, Immediate(key->handle()));
1736 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1736 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1737 __ call(ic, RelocInfo::CODE_TARGET, prop->id()); 1737 CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
1738 } 1738 }
1739 1739
1740 1740
1741 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1741 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1742 SetSourcePosition(prop->position()); 1742 SetSourcePosition(prop->position());
1743 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1743 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1744 __ call(ic, RelocInfo::CODE_TARGET, prop->id()); 1744 CallIC(ic, RelocInfo::CODE_TARGET, prop->id());
1745 } 1745 }
1746 1746
1747 1747
1748 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 1748 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
1749 Token::Value op, 1749 Token::Value op,
1750 OverwriteMode mode, 1750 OverwriteMode mode,
1751 Expression* left, 1751 Expression* left,
1752 Expression* right) { 1752 Expression* right) {
1753 // Do combined smi check of the operands. Left operand is on the 1753 // Do combined smi check of the operands. Left operand is on the
1754 // stack. Right operand is in eax. 1754 // stack. Right operand is in eax.
1755 Label smi_case, done, stub_call; 1755 Label smi_case, done, stub_call;
1756 __ pop(edx); 1756 __ pop(edx);
1757 __ mov(ecx, eax); 1757 __ mov(ecx, eax);
1758 __ or_(eax, edx); 1758 __ or_(eax, edx);
1759 JumpPatchSite patch_site(masm_); 1759 JumpPatchSite patch_site(masm_);
1760 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); 1760 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear);
1761 1761
1762 __ bind(&stub_call); 1762 __ bind(&stub_call);
1763 __ mov(eax, ecx); 1763 __ mov(eax, ecx);
1764 BinaryOpStub stub(op, mode); 1764 BinaryOpStub stub(op, mode);
1765 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); 1765 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1766 patch_site.EmitPatchInfo(); 1766 patch_site.EmitPatchInfo();
1767 __ jmp(&done, Label::kNear); 1767 __ jmp(&done, Label::kNear);
1768 1768
1769 // Smi case. 1769 // Smi case.
1770 __ bind(&smi_case); 1770 __ bind(&smi_case);
1771 __ mov(eax, edx); // Copy left operand in case of a stub call. 1771 __ mov(eax, edx); // Copy left operand in case of a stub call.
1772 1772
1773 switch (op) { 1773 switch (op) {
1774 case Token::SAR: 1774 case Token::SAR:
1775 __ SmiUntag(eax); 1775 __ SmiUntag(eax);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 context()->Plug(eax); 1840 context()->Plug(eax);
1841 } 1841 }
1842 1842
1843 1843
1844 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 1844 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
1845 Token::Value op, 1845 Token::Value op,
1846 OverwriteMode mode) { 1846 OverwriteMode mode) {
1847 __ pop(edx); 1847 __ pop(edx);
1848 BinaryOpStub stub(op, mode); 1848 BinaryOpStub stub(op, mode);
1849 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 1849 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
1850 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); 1850 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1851 patch_site.EmitPatchInfo(); 1851 patch_site.EmitPatchInfo();
1852 context()->Plug(eax); 1852 context()->Plug(eax);
1853 } 1853 }
1854 1854
1855 1855
1856 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1856 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1857 // Invalid left-hand sides are rewritten to have a 'throw 1857 // Invalid left-hand sides are rewritten to have a 'throw
1858 // ReferenceError' on the left-hand side. 1858 // ReferenceError' on the left-hand side.
1859 if (!expr->IsValidLeftHandSide()) { 1859 if (!expr->IsValidLeftHandSide()) {
1860 VisitForEffect(expr); 1860 VisitForEffect(expr);
(...skipping 20 matching lines...) Expand all
1881 } 1881 }
1882 case NAMED_PROPERTY: { 1882 case NAMED_PROPERTY: {
1883 __ push(eax); // Preserve value. 1883 __ push(eax); // Preserve value.
1884 VisitForAccumulatorValue(prop->obj()); 1884 VisitForAccumulatorValue(prop->obj());
1885 __ mov(edx, eax); 1885 __ mov(edx, eax);
1886 __ pop(eax); // Restore value. 1886 __ pop(eax); // Restore value.
1887 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1887 __ mov(ecx, prop->key()->AsLiteral()->handle());
1888 Handle<Code> ic = is_classic_mode() 1888 Handle<Code> ic = is_classic_mode()
1889 ? isolate()->builtins()->StoreIC_Initialize() 1889 ? isolate()->builtins()->StoreIC_Initialize()
1890 : isolate()->builtins()->StoreIC_Initialize_Strict(); 1890 : isolate()->builtins()->StoreIC_Initialize_Strict();
1891 __ call(ic); 1891 CallIC(ic);
1892 break; 1892 break;
1893 } 1893 }
1894 case KEYED_PROPERTY: { 1894 case KEYED_PROPERTY: {
1895 __ push(eax); // Preserve value. 1895 __ push(eax); // Preserve value.
1896 VisitForStackValue(prop->obj()); 1896 VisitForStackValue(prop->obj());
1897 VisitForAccumulatorValue(prop->key()); 1897 VisitForAccumulatorValue(prop->key());
1898 __ mov(ecx, eax); 1898 __ mov(ecx, eax);
1899 __ pop(edx); 1899 __ pop(edx);
1900 __ pop(eax); // Restore value. 1900 __ pop(eax); // Restore value.
1901 Handle<Code> ic = is_classic_mode() 1901 Handle<Code> ic = is_classic_mode()
1902 ? isolate()->builtins()->KeyedStoreIC_Initialize() 1902 ? isolate()->builtins()->KeyedStoreIC_Initialize()
1903 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 1903 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
1904 __ call(ic); 1904 CallIC(ic);
1905 break; 1905 break;
1906 } 1906 }
1907 } 1907 }
1908 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1908 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1909 context()->Plug(eax); 1909 context()->Plug(eax);
1910 } 1910 }
1911 1911
1912 1912
1913 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1913 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1914 Token::Value op) { 1914 Token::Value op) {
1915 if (var->IsUnallocated()) { 1915 if (var->IsUnallocated()) {
1916 // Global var, const, or let. 1916 // Global var, const, or let.
1917 __ mov(ecx, var->name()); 1917 __ mov(ecx, var->name());
1918 __ mov(edx, GlobalObjectOperand()); 1918 __ mov(edx, GlobalObjectOperand());
1919 Handle<Code> ic = is_classic_mode() 1919 Handle<Code> ic = is_classic_mode()
1920 ? isolate()->builtins()->StoreIC_Initialize() 1920 ? isolate()->builtins()->StoreIC_Initialize()
1921 : isolate()->builtins()->StoreIC_Initialize_Strict(); 1921 : isolate()->builtins()->StoreIC_Initialize_Strict();
1922 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 1922 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1923 1923
1924 } else if (op == Token::INIT_CONST) { 1924 } else if (op == Token::INIT_CONST) {
1925 // Const initializers need a write barrier. 1925 // Const initializers need a write barrier.
1926 ASSERT(!var->IsParameter()); // No const parameters. 1926 ASSERT(!var->IsParameter()); // No const parameters.
1927 if (var->IsStackLocal()) { 1927 if (var->IsStackLocal()) {
1928 Label skip; 1928 Label skip;
1929 __ mov(edx, StackOperand(var)); 1929 __ mov(edx, StackOperand(var));
1930 __ cmp(edx, isolate()->factory()->the_hole_value()); 1930 __ cmp(edx, isolate()->factory()->the_hole_value());
1931 __ j(not_equal, &skip); 1931 __ j(not_equal, &skip);
1932 __ mov(StackOperand(var), eax); 1932 __ mov(StackOperand(var), eax);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2021 SetSourcePosition(expr->position()); 2021 SetSourcePosition(expr->position());
2022 __ mov(ecx, prop->key()->AsLiteral()->handle()); 2022 __ mov(ecx, prop->key()->AsLiteral()->handle());
2023 if (expr->ends_initialization_block()) { 2023 if (expr->ends_initialization_block()) {
2024 __ mov(edx, Operand(esp, 0)); 2024 __ mov(edx, Operand(esp, 0));
2025 } else { 2025 } else {
2026 __ pop(edx); 2026 __ pop(edx);
2027 } 2027 }
2028 Handle<Code> ic = is_classic_mode() 2028 Handle<Code> ic = is_classic_mode()
2029 ? isolate()->builtins()->StoreIC_Initialize() 2029 ? isolate()->builtins()->StoreIC_Initialize()
2030 : isolate()->builtins()->StoreIC_Initialize_Strict(); 2030 : isolate()->builtins()->StoreIC_Initialize_Strict();
2031 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 2031 CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
2032 2032
2033 // If the assignment ends an initialization block, revert to fast case. 2033 // If the assignment ends an initialization block, revert to fast case.
2034 if (expr->ends_initialization_block()) { 2034 if (expr->ends_initialization_block()) {
2035 __ push(eax); // Result of assignment, saved even if not needed. 2035 __ push(eax); // Result of assignment, saved even if not needed.
2036 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 2036 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
2037 __ CallRuntime(Runtime::kToFastProperties, 1); 2037 __ CallRuntime(Runtime::kToFastProperties, 1);
2038 __ pop(eax); 2038 __ pop(eax);
2039 __ Drop(1); 2039 __ Drop(1);
2040 } 2040 }
2041 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2041 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
(...skipping 19 matching lines...) Expand all
2061 if (expr->ends_initialization_block()) { 2061 if (expr->ends_initialization_block()) {
2062 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. 2062 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later.
2063 } else { 2063 } else {
2064 __ pop(edx); 2064 __ pop(edx);
2065 } 2065 }
2066 // Record source code position before IC call. 2066 // Record source code position before IC call.
2067 SetSourcePosition(expr->position()); 2067 SetSourcePosition(expr->position());
2068 Handle<Code> ic = is_classic_mode() 2068 Handle<Code> ic = is_classic_mode()
2069 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2069 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2070 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2070 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2071 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 2071 CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
2072 2072
2073 // If the assignment ends an initialization block, revert to fast case. 2073 // If the assignment ends an initialization block, revert to fast case.
2074 if (expr->ends_initialization_block()) { 2074 if (expr->ends_initialization_block()) {
2075 __ pop(edx); 2075 __ pop(edx);
2076 __ push(eax); // Result of assignment, saved even if not needed. 2076 __ push(eax); // Result of assignment, saved even if not needed.
2077 __ push(edx); 2077 __ push(edx);
2078 __ CallRuntime(Runtime::kToFastProperties, 1); 2078 __ CallRuntime(Runtime::kToFastProperties, 1);
2079 __ pop(eax); 2079 __ pop(eax);
2080 } 2080 }
2081 2081
(...skipping 13 matching lines...) Expand all
2095 } else { 2095 } else {
2096 VisitForStackValue(expr->obj()); 2096 VisitForStackValue(expr->obj());
2097 VisitForAccumulatorValue(expr->key()); 2097 VisitForAccumulatorValue(expr->key());
2098 __ pop(edx); 2098 __ pop(edx);
2099 EmitKeyedPropertyLoad(expr); 2099 EmitKeyedPropertyLoad(expr);
2100 context()->Plug(eax); 2100 context()->Plug(eax);
2101 } 2101 }
2102 } 2102 }
2103 2103
2104 2104
2105 void FullCodeGenerator::CallIC(Handle<Code> code,
2106 RelocInfo::Mode rmode,
2107 unsigned ast_id) {
2108 ic_total_count_++;
2109 __ call(code, rmode, ast_id);
2110 }
2111
2112
2113
2114
2105 void FullCodeGenerator::EmitCallWithIC(Call* expr, 2115 void FullCodeGenerator::EmitCallWithIC(Call* expr,
2106 Handle<Object> name, 2116 Handle<Object> name,
2107 RelocInfo::Mode mode) { 2117 RelocInfo::Mode mode) {
2108 // Code common for calls using the IC. 2118 // Code common for calls using the IC.
2109 ZoneList<Expression*>* args = expr->arguments(); 2119 ZoneList<Expression*>* args = expr->arguments();
2110 int arg_count = args->length(); 2120 int arg_count = args->length();
2111 { PreservePositionScope scope(masm()->positions_recorder()); 2121 { PreservePositionScope scope(masm()->positions_recorder());
2112 for (int i = 0; i < arg_count; i++) { 2122 for (int i = 0; i < arg_count; i++) {
2113 VisitForStackValue(args->at(i)); 2123 VisitForStackValue(args->at(i));
2114 } 2124 }
2115 __ Set(ecx, Immediate(name)); 2125 __ Set(ecx, Immediate(name));
2116 } 2126 }
2117 // Record source position of the IC call. 2127 // Record source position of the IC call.
2118 SetSourcePosition(expr->position()); 2128 SetSourcePosition(expr->position());
2119 Handle<Code> ic = 2129 Handle<Code> ic =
2120 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); 2130 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
2121 __ call(ic, mode, expr->id()); 2131 CallIC(ic, mode, expr->id());
2122 RecordJSReturnSite(expr); 2132 RecordJSReturnSite(expr);
2123 // Restore context register. 2133 // Restore context register.
2124 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2134 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2125 context()->Plug(eax); 2135 context()->Plug(eax);
2126 } 2136 }
2127 2137
2128 2138
2129 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2139 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2130 Expression* key) { 2140 Expression* key) {
2131 // Load the key. 2141 // Load the key.
(...skipping 11 matching lines...) Expand all
2143 { PreservePositionScope scope(masm()->positions_recorder()); 2153 { PreservePositionScope scope(masm()->positions_recorder());
2144 for (int i = 0; i < arg_count; i++) { 2154 for (int i = 0; i < arg_count; i++) {
2145 VisitForStackValue(args->at(i)); 2155 VisitForStackValue(args->at(i));
2146 } 2156 }
2147 } 2157 }
2148 // Record source position of the IC call. 2158 // Record source position of the IC call.
2149 SetSourcePosition(expr->position()); 2159 SetSourcePosition(expr->position());
2150 Handle<Code> ic = 2160 Handle<Code> ic =
2151 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); 2161 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
2152 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. 2162 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
2153 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 2163 CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
2154 RecordJSReturnSite(expr); 2164 RecordJSReturnSite(expr);
2155 // Restore context register. 2165 // Restore context register.
2156 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2166 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2157 context()->DropAndPlug(1, eax); // Drop the key still on the stack. 2167 context()->DropAndPlug(1, eax); // Drop the key still on the stack.
2158 } 2168 }
2159 2169
2160 2170
2161 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { 2171 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
2162 // Code common for calls using the call stub. 2172 // Code common for calls using the call stub.
2163 ZoneList<Expression*>* args = expr->arguments(); 2173 ZoneList<Expression*>* args = expr->arguments();
(...skipping 1566 matching lines...) Expand 10 before | Expand all | Expand 10 after
3730 for (int i = 0; i < arg_count; i++) { 3740 for (int i = 0; i < arg_count; i++) {
3731 VisitForStackValue(args->at(i)); 3741 VisitForStackValue(args->at(i));
3732 } 3742 }
3733 3743
3734 if (expr->is_jsruntime()) { 3744 if (expr->is_jsruntime()) {
3735 // Call the JS runtime function via a call IC. 3745 // Call the JS runtime function via a call IC.
3736 __ Set(ecx, Immediate(expr->name())); 3746 __ Set(ecx, Immediate(expr->name()));
3737 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; 3747 RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
3738 Handle<Code> ic = 3748 Handle<Code> ic =
3739 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); 3749 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
3740 __ call(ic, mode, expr->id()); 3750 CallIC(ic, mode, expr->id());
3741 // Restore context register. 3751 // Restore context register.
3742 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3752 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3743 } else { 3753 } else {
3744 // Call the C runtime function. 3754 // Call the C runtime function.
3745 __ CallRuntime(expr->function(), arg_count); 3755 __ CallRuntime(expr->function(), arg_count);
3746 } 3756 }
3747 context()->Plug(eax); 3757 context()->Plug(eax);
3748 } 3758 }
3749 3759
3750 3760
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
3888 const char* comment) { 3898 const char* comment) {
3889 Comment cmt(masm_, comment); 3899 Comment cmt(masm_, comment);
3890 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); 3900 bool can_overwrite = expr->expression()->ResultOverwriteAllowed();
3891 UnaryOverwriteMode overwrite = 3901 UnaryOverwriteMode overwrite =
3892 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; 3902 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
3893 UnaryOpStub stub(expr->op(), overwrite); 3903 UnaryOpStub stub(expr->op(), overwrite);
3894 // UnaryOpStub expects the argument to be in the 3904 // UnaryOpStub expects the argument to be in the
3895 // accumulator register eax. 3905 // accumulator register eax.
3896 VisitForAccumulatorValue(expr->expression()); 3906 VisitForAccumulatorValue(expr->expression());
3897 SetSourcePosition(expr->position()); 3907 SetSourcePosition(expr->position());
3898 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); 3908 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
3899 context()->Plug(eax); 3909 context()->Plug(eax);
3900 } 3910 }
3901 3911
3902 3912
3903 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 3913 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
3904 Comment cmnt(masm_, "[ CountOperation"); 3914 Comment cmnt(masm_, "[ CountOperation");
3905 SetSourcePosition(expr->position()); 3915 SetSourcePosition(expr->position());
3906 3916
3907 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 3917 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
3908 // as the left-hand side. 3918 // as the left-hand side.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
4008 } 4018 }
4009 } 4019 }
4010 4020
4011 // Record position before stub call. 4021 // Record position before stub call.
4012 SetSourcePosition(expr->position()); 4022 SetSourcePosition(expr->position());
4013 4023
4014 // Call stub for +1/-1. 4024 // Call stub for +1/-1.
4015 __ mov(edx, eax); 4025 __ mov(edx, eax);
4016 __ mov(eax, Immediate(Smi::FromInt(1))); 4026 __ mov(eax, Immediate(Smi::FromInt(1)));
4017 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); 4027 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
4018 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); 4028 CallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
4019 patch_site.EmitPatchInfo(); 4029 patch_site.EmitPatchInfo();
4020 __ bind(&done); 4030 __ bind(&done);
4021 4031
4022 // Store the value returned in eax. 4032 // Store the value returned in eax.
4023 switch (assign_type) { 4033 switch (assign_type) {
4024 case VARIABLE: 4034 case VARIABLE:
4025 if (expr->is_postfix()) { 4035 if (expr->is_postfix()) {
4026 // Perform the assignment as if via '='. 4036 // Perform the assignment as if via '='.
4027 { EffectContext context(this); 4037 { EffectContext context(this);
4028 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4038 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
(...skipping 13 matching lines...) Expand all
4042 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4052 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4043 context()->Plug(eax); 4053 context()->Plug(eax);
4044 } 4054 }
4045 break; 4055 break;
4046 case NAMED_PROPERTY: { 4056 case NAMED_PROPERTY: {
4047 __ mov(ecx, prop->key()->AsLiteral()->handle()); 4057 __ mov(ecx, prop->key()->AsLiteral()->handle());
4048 __ pop(edx); 4058 __ pop(edx);
4049 Handle<Code> ic = is_classic_mode() 4059 Handle<Code> ic = is_classic_mode()
4050 ? isolate()->builtins()->StoreIC_Initialize() 4060 ? isolate()->builtins()->StoreIC_Initialize()
4051 : isolate()->builtins()->StoreIC_Initialize_Strict(); 4061 : isolate()->builtins()->StoreIC_Initialize_Strict();
4052 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 4062 CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
4053 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4063 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4054 if (expr->is_postfix()) { 4064 if (expr->is_postfix()) {
4055 if (!context()->IsEffect()) { 4065 if (!context()->IsEffect()) {
4056 context()->PlugTOS(); 4066 context()->PlugTOS();
4057 } 4067 }
4058 } else { 4068 } else {
4059 context()->Plug(eax); 4069 context()->Plug(eax);
4060 } 4070 }
4061 break; 4071 break;
4062 } 4072 }
4063 case KEYED_PROPERTY: { 4073 case KEYED_PROPERTY: {
4064 __ pop(ecx); 4074 __ pop(ecx);
4065 __ pop(edx); 4075 __ pop(edx);
4066 Handle<Code> ic = is_classic_mode() 4076 Handle<Code> ic = is_classic_mode()
4067 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4077 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4068 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4078 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4069 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 4079 CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
4070 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4080 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4071 if (expr->is_postfix()) { 4081 if (expr->is_postfix()) {
4072 // Result is on the stack 4082 // Result is on the stack
4073 if (!context()->IsEffect()) { 4083 if (!context()->IsEffect()) {
4074 context()->PlugTOS(); 4084 context()->PlugTOS();
4075 } 4085 }
4076 } else { 4086 } else {
4077 context()->Plug(eax); 4087 context()->Plug(eax);
4078 } 4088 }
4079 break; 4089 break;
4080 } 4090 }
4081 } 4091 }
4082 } 4092 }
4083 4093
4084 4094
4085 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 4095 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
4086 VariableProxy* proxy = expr->AsVariableProxy(); 4096 VariableProxy* proxy = expr->AsVariableProxy();
4087 ASSERT(!context()->IsEffect()); 4097 ASSERT(!context()->IsEffect());
4088 ASSERT(!context()->IsTest()); 4098 ASSERT(!context()->IsTest());
4089 4099
4090 if (proxy != NULL && proxy->var()->IsUnallocated()) { 4100 if (proxy != NULL && proxy->var()->IsUnallocated()) {
4091 Comment cmnt(masm_, "Global variable"); 4101 Comment cmnt(masm_, "Global variable");
4092 __ mov(eax, GlobalObjectOperand()); 4102 __ mov(eax, GlobalObjectOperand());
4093 __ mov(ecx, Immediate(proxy->name())); 4103 __ mov(ecx, Immediate(proxy->name()));
4094 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 4104 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
4095 // Use a regular load, not a contextual load, to avoid a reference 4105 // Use a regular load, not a contextual load, to avoid a reference
4096 // error. 4106 // error.
4097 __ call(ic); 4107 CallIC(ic);
4098 PrepareForBailout(expr, TOS_REG); 4108 PrepareForBailout(expr, TOS_REG);
4099 context()->Plug(eax); 4109 context()->Plug(eax);
4100 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 4110 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
4101 Label done, slow; 4111 Label done, slow;
4102 4112
4103 // Generate code for loading from variables potentially shadowed 4113 // Generate code for loading from variables potentially shadowed
4104 // by eval-introduced variables. 4114 // by eval-introduced variables.
4105 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); 4115 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done);
4106 4116
4107 __ bind(&slow); 4117 __ bind(&slow);
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
4267 __ or_(ecx, eax); 4277 __ or_(ecx, eax);
4268 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 4278 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear);
4269 __ cmp(edx, eax); 4279 __ cmp(edx, eax);
4270 Split(cc, if_true, if_false, NULL); 4280 Split(cc, if_true, if_false, NULL);
4271 __ bind(&slow_case); 4281 __ bind(&slow_case);
4272 } 4282 }
4273 4283
4274 // Record position and call the compare IC. 4284 // Record position and call the compare IC.
4275 SetSourcePosition(expr->position()); 4285 SetSourcePosition(expr->position());
4276 Handle<Code> ic = CompareIC::GetUninitialized(op); 4286 Handle<Code> ic = CompareIC::GetUninitialized(op);
4277 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); 4287 CallIC(ic, RelocInfo::CODE_TARGET, expr->id());
4278 patch_site.EmitPatchInfo(); 4288 patch_site.EmitPatchInfo();
4279 4289
4280 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4290 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4281 __ test(eax, eax); 4291 __ test(eax, eax);
4282 Split(cc, if_true, if_false, fall_through); 4292 Split(cc, if_true, if_false, fall_through);
4283 } 4293 }
4284 } 4294 }
4285 4295
4286 // Convert the result of the comparison into one expected for this 4296 // Convert the result of the comparison into one expected for this
4287 // expression's context. 4297 // expression's context.
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
4426 *context_length = 0; 4436 *context_length = 0;
4427 return previous_; 4437 return previous_;
4428 } 4438 }
4429 4439
4430 4440
4431 #undef __ 4441 #undef __
4432 4442
4433 } } // namespace v8::internal 4443 } } // namespace v8::internal
4434 4444
4435 #endif // V8_TARGET_ARCH_IA32 4445 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/heap.cc ('k') | src/ic.h » ('j') | src/objects-inl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698