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

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

Issue 3431010: Clean up the insertion of nops (signalling non-inlined loads and... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 3 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/full-codegen.h ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 VisitForValue(function, kAccumulator); 624 VisitForValue(function, kAccumulator);
625 __ pop(ecx); 625 __ pop(ecx);
626 } else { 626 } else {
627 VisitForValue(prop->key(), kAccumulator); 627 VisitForValue(prop->key(), kAccumulator);
628 __ mov(ecx, result_register()); 628 __ mov(ecx, result_register());
629 __ mov(result_register(), Factory::the_hole_value()); 629 __ mov(result_register(), Factory::the_hole_value());
630 } 630 }
631 __ pop(edx); 631 __ pop(edx);
632 632
633 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 633 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
634 __ call(ic, RelocInfo::CODE_TARGET); 634 EmitCallIC(ic, RelocInfo::CODE_TARGET);
635 // Absence of a test eax instruction following the call
636 // indicates that none of the load was inlined.
637 __ nop();
638 } 635 }
639 } 636 }
640 } 637 }
641 638
642 639
643 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 640 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
644 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 641 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
645 } 642 }
646 643
647 644
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 } 982 }
986 983
987 // All extension objects were empty and it is safe to use a global 984 // All extension objects were empty and it is safe to use a global
988 // load IC call. 985 // load IC call.
989 __ mov(eax, CodeGenerator::GlobalObject()); 986 __ mov(eax, CodeGenerator::GlobalObject());
990 __ mov(ecx, slot->var()->name()); 987 __ mov(ecx, slot->var()->name());
991 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 988 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
992 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 989 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
993 ? RelocInfo::CODE_TARGET 990 ? RelocInfo::CODE_TARGET
994 : RelocInfo::CODE_TARGET_CONTEXT; 991 : RelocInfo::CODE_TARGET_CONTEXT;
995 __ call(ic, mode); 992 EmitCallIC(ic, mode);
996 __ nop(); // Signal no inlined code.
997 } 993 }
998 994
999 995
1000 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( 996 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(
1001 Slot* slot, 997 Slot* slot,
1002 Label* slow) { 998 Label* slow) {
1003 ASSERT(slot->type() == Slot::CONTEXT); 999 ASSERT(slot->type() == Slot::CONTEXT);
1004 Register context = esi; 1000 Register context = esi;
1005 Register temp = ebx; 1001 Register temp = ebx;
1006 1002
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 obj_proxy->IsArguments() && 1059 obj_proxy->IsArguments() &&
1064 key_literal->handle()->IsSmi()) { 1060 key_literal->handle()->IsSmi()) {
1065 // Load arguments object if there are no eval-introduced 1061 // Load arguments object if there are no eval-introduced
1066 // variables. Then load the argument from the arguments 1062 // variables. Then load the argument from the arguments
1067 // object using keyed load. 1063 // object using keyed load.
1068 __ mov(edx, 1064 __ mov(edx,
1069 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(), 1065 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(),
1070 slow)); 1066 slow));
1071 __ mov(eax, Immediate(key_literal->handle())); 1067 __ mov(eax, Immediate(key_literal->handle()));
1072 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1068 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1073 __ call(ic, RelocInfo::CODE_TARGET); 1069 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1074 __ jmp(done); 1070 __ jmp(done);
1075 } 1071 }
1076 } 1072 }
1077 } 1073 }
1078 } 1074 }
1079 } 1075 }
1080 1076
1081 1077
1082 void FullCodeGenerator::EmitVariableLoad(Variable* var, 1078 void FullCodeGenerator::EmitVariableLoad(Variable* var,
1083 Expression::Context context) { 1079 Expression::Context context) {
1084 // Four cases: non-this global variables, lookup slots, all other 1080 // Four cases: non-this global variables, lookup slots, all other
1085 // types of slots, and parameters that rewrite to explicit property 1081 // types of slots, and parameters that rewrite to explicit property
1086 // accesses on the arguments object. 1082 // accesses on the arguments object.
1087 Slot* slot = var->slot(); 1083 Slot* slot = var->slot();
1088 Property* property = var->AsProperty(); 1084 Property* property = var->AsProperty();
1089 1085
1090 if (var->is_global() && !var->is_this()) { 1086 if (var->is_global() && !var->is_this()) {
1091 Comment cmnt(masm_, "Global variable"); 1087 Comment cmnt(masm_, "Global variable");
1092 // Use inline caching. Variable name is passed in ecx and the global 1088 // Use inline caching. Variable name is passed in ecx and the global
1093 // object on the stack. 1089 // object on the stack.
1094 __ mov(eax, CodeGenerator::GlobalObject()); 1090 __ mov(eax, CodeGenerator::GlobalObject());
1095 __ mov(ecx, var->name()); 1091 __ mov(ecx, var->name());
1096 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1092 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1097 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 1093 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1098 // By emitting a nop we make sure that we do not have a test eax
1099 // instruction after the call it is treated specially by the LoadIC code
1100 // Remember that the assembler may choose to do peephole optimization
1101 // (eg, push/pop elimination).
1102 __ nop();
1103 Apply(context, eax); 1094 Apply(context, eax);
1104 1095
1105 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 1096 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
1106 Label done, slow; 1097 Label done, slow;
1107 1098
1108 // Generate code for loading from variables potentially shadowed 1099 // Generate code for loading from variables potentially shadowed
1109 // by eval-introduced variables. 1100 // by eval-introduced variables.
1110 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1101 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
1111 1102
1112 __ bind(&slow); 1103 __ bind(&slow);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 // Assert that the key is a smi. 1146 // Assert that the key is a smi.
1156 Literal* key_literal = property->key()->AsLiteral(); 1147 Literal* key_literal = property->key()->AsLiteral();
1157 ASSERT_NOT_NULL(key_literal); 1148 ASSERT_NOT_NULL(key_literal);
1158 ASSERT(key_literal->handle()->IsSmi()); 1149 ASSERT(key_literal->handle()->IsSmi());
1159 1150
1160 // Load the key. 1151 // Load the key.
1161 __ mov(eax, Immediate(key_literal->handle())); 1152 __ mov(eax, Immediate(key_literal->handle()));
1162 1153
1163 // Do a keyed property load. 1154 // Do a keyed property load.
1164 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1155 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1165 __ call(ic, RelocInfo::CODE_TARGET); 1156 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1166 // Notice: We must not have a "test eax, ..." instruction after the 1157
1167 // call. It is treated specially by the LoadIC code.
1168 __ nop();
1169 // Drop key and object left on the stack by IC. 1158 // Drop key and object left on the stack by IC.
1170 Apply(context, eax); 1159 Apply(context, eax);
1171 } 1160 }
1172 } 1161 }
1173 1162
1174 1163
1175 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1164 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1176 Comment cmnt(masm_, "[ RegExpLiteral"); 1165 Comment cmnt(masm_, "[ RegExpLiteral");
1177 NearLabel materialized; 1166 NearLabel materialized;
1178 // Registers will be used as follows: 1167 // Registers will be used as follows:
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 switch (property->kind()) { 1245 switch (property->kind()) {
1257 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1246 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1258 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1247 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1259 // Fall through. 1248 // Fall through.
1260 case ObjectLiteral::Property::COMPUTED: 1249 case ObjectLiteral::Property::COMPUTED:
1261 if (key->handle()->IsSymbol()) { 1250 if (key->handle()->IsSymbol()) {
1262 VisitForValue(value, kAccumulator); 1251 VisitForValue(value, kAccumulator);
1263 __ mov(ecx, Immediate(key->handle())); 1252 __ mov(ecx, Immediate(key->handle()));
1264 __ mov(edx, Operand(esp, 0)); 1253 __ mov(edx, Operand(esp, 0));
1265 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1254 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1266 __ call(ic, RelocInfo::CODE_TARGET); 1255 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1267 __ nop();
1268 break; 1256 break;
1269 } 1257 }
1270 // Fall through. 1258 // Fall through.
1271 case ObjectLiteral::Property::PROTOTYPE: 1259 case ObjectLiteral::Property::PROTOTYPE:
1272 __ push(Operand(esp, 0)); // Duplicate receiver. 1260 __ push(Operand(esp, 0)); // Duplicate receiver.
1273 VisitForValue(key, kStack); 1261 VisitForValue(key, kStack);
1274 VisitForValue(value, kStack); 1262 VisitForValue(value, kStack);
1275 __ CallRuntime(Runtime::kSetProperty, 3); 1263 __ CallRuntime(Runtime::kSetProperty, 3);
1276 break; 1264 break;
1277 case ObjectLiteral::Property::SETTER: 1265 case ObjectLiteral::Property::SETTER:
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 break; 1458 break;
1471 } 1459 }
1472 } 1460 }
1473 1461
1474 1462
1475 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1463 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1476 SetSourcePosition(prop->position()); 1464 SetSourcePosition(prop->position());
1477 Literal* key = prop->key()->AsLiteral(); 1465 Literal* key = prop->key()->AsLiteral();
1478 __ mov(ecx, Immediate(key->handle())); 1466 __ mov(ecx, Immediate(key->handle()));
1479 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1467 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1480 __ call(ic, RelocInfo::CODE_TARGET); 1468 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1481 __ nop();
1482 } 1469 }
1483 1470
1484 1471
1485 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1472 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1486 SetSourcePosition(prop->position()); 1473 SetSourcePosition(prop->position());
1487 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1474 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1488 __ call(ic, RelocInfo::CODE_TARGET); 1475 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1489 __ nop();
1490 } 1476 }
1491 1477
1492 1478
1493 void FullCodeGenerator::EmitConstantSmiAdd(Expression* expr, 1479 void FullCodeGenerator::EmitConstantSmiAdd(Expression* expr,
1494 Expression::Context context, 1480 Expression::Context context,
1495 OverwriteMode mode, 1481 OverwriteMode mode,
1496 bool left_is_constant_smi, 1482 bool left_is_constant_smi,
1497 Smi* value) { 1483 Smi* value) {
1498 NearLabel call_stub; 1484 NearLabel call_stub;
1499 Label done; 1485 Label done;
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 EmitVariableAssignment(var, Token::ASSIGN, Expression::kEffect); 1825 EmitVariableAssignment(var, Token::ASSIGN, Expression::kEffect);
1840 break; 1826 break;
1841 } 1827 }
1842 case NAMED_PROPERTY: { 1828 case NAMED_PROPERTY: {
1843 __ push(eax); // Preserve value. 1829 __ push(eax); // Preserve value.
1844 VisitForValue(prop->obj(), kAccumulator); 1830 VisitForValue(prop->obj(), kAccumulator);
1845 __ mov(edx, eax); 1831 __ mov(edx, eax);
1846 __ pop(eax); // Restore value. 1832 __ pop(eax); // Restore value.
1847 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1833 __ mov(ecx, prop->key()->AsLiteral()->handle());
1848 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1834 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1849 __ call(ic, RelocInfo::CODE_TARGET); 1835 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1850 __ nop(); // Signal no inlined code.
1851 break; 1836 break;
1852 } 1837 }
1853 case KEYED_PROPERTY: { 1838 case KEYED_PROPERTY: {
1854 __ push(eax); // Preserve value. 1839 __ push(eax); // Preserve value.
1855 VisitForValue(prop->obj(), kStack); 1840 VisitForValue(prop->obj(), kStack);
1856 VisitForValue(prop->key(), kAccumulator); 1841 VisitForValue(prop->key(), kAccumulator);
1857 __ mov(ecx, eax); 1842 __ mov(ecx, eax);
1858 __ pop(edx); 1843 __ pop(edx);
1859 __ pop(eax); // Restore value. 1844 __ pop(eax); // Restore value.
1860 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 1845 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
1861 __ call(ic, RelocInfo::CODE_TARGET); 1846 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1862 __ nop(); // Signal no inlined code.
1863 break; 1847 break;
1864 } 1848 }
1865 } 1849 }
1866 } 1850 }
1867 1851
1868 1852
1869 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1853 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1870 Token::Value op, 1854 Token::Value op,
1871 Expression::Context context) { 1855 Expression::Context context) {
1872 // Left-hand sides that rewrite to explicit property accesses do not reach 1856 // Left-hand sides that rewrite to explicit property accesses do not reach
1873 // here. 1857 // here.
1874 ASSERT(var != NULL); 1858 ASSERT(var != NULL);
1875 ASSERT(var->is_global() || var->slot() != NULL); 1859 ASSERT(var->is_global() || var->slot() != NULL);
1876 1860
1877 if (var->is_global()) { 1861 if (var->is_global()) {
1878 ASSERT(!var->is_this()); 1862 ASSERT(!var->is_this());
1879 // Assignment to a global variable. Use inline caching for the 1863 // Assignment to a global variable. Use inline caching for the
1880 // assignment. Right-hand-side value is passed in eax, variable name in 1864 // assignment. Right-hand-side value is passed in eax, variable name in
1881 // ecx, and the global object on the stack. 1865 // ecx, and the global object on the stack.
1882 __ mov(ecx, var->name()); 1866 __ mov(ecx, var->name());
1883 __ mov(edx, CodeGenerator::GlobalObject()); 1867 __ mov(edx, CodeGenerator::GlobalObject());
1884 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1868 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1885 __ call(ic, RelocInfo::CODE_TARGET); 1869 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1886 __ nop();
1887 1870
1888 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { 1871 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
1889 // Perform the assignment for non-const variables and for initialization 1872 // Perform the assignment for non-const variables and for initialization
1890 // of const variables. Const assignments are simply skipped. 1873 // of const variables. Const assignments are simply skipped.
1891 Label done; 1874 Label done;
1892 Slot* slot = var->slot(); 1875 Slot* slot = var->slot();
1893 switch (slot->type()) { 1876 switch (slot->type()) {
1894 case Slot::PARAMETER: 1877 case Slot::PARAMETER:
1895 case Slot::LOCAL: 1878 case Slot::LOCAL:
1896 if (op == Token::INIT_CONST) { 1879 if (op == Token::INIT_CONST) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1960 1943
1961 // Record source code position before IC call. 1944 // Record source code position before IC call.
1962 SetSourcePosition(expr->position()); 1945 SetSourcePosition(expr->position());
1963 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1946 __ mov(ecx, prop->key()->AsLiteral()->handle());
1964 if (expr->ends_initialization_block()) { 1947 if (expr->ends_initialization_block()) {
1965 __ mov(edx, Operand(esp, 0)); 1948 __ mov(edx, Operand(esp, 0));
1966 } else { 1949 } else {
1967 __ pop(edx); 1950 __ pop(edx);
1968 } 1951 }
1969 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1952 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1970 __ call(ic, RelocInfo::CODE_TARGET); 1953 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1971 __ nop();
1972 1954
1973 // If the assignment ends an initialization block, revert to fast case. 1955 // If the assignment ends an initialization block, revert to fast case.
1974 if (expr->ends_initialization_block()) { 1956 if (expr->ends_initialization_block()) {
1975 __ push(eax); // Result of assignment, saved even if not needed. 1957 __ push(eax); // Result of assignment, saved even if not needed.
1976 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 1958 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
1977 __ CallRuntime(Runtime::kToFastProperties, 1); 1959 __ CallRuntime(Runtime::kToFastProperties, 1);
1978 __ pop(eax); 1960 __ pop(eax);
1979 DropAndApply(1, context_, eax); 1961 DropAndApply(1, context_, eax);
1980 } else { 1962 } else {
1981 Apply(context_, eax); 1963 Apply(context_, eax);
(...skipping 17 matching lines...) Expand all
1999 1981
2000 __ pop(ecx); 1982 __ pop(ecx);
2001 if (expr->ends_initialization_block()) { 1983 if (expr->ends_initialization_block()) {
2002 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. 1984 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later.
2003 } else { 1985 } else {
2004 __ pop(edx); 1986 __ pop(edx);
2005 } 1987 }
2006 // Record source code position before IC call. 1988 // Record source code position before IC call.
2007 SetSourcePosition(expr->position()); 1989 SetSourcePosition(expr->position());
2008 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 1990 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
2009 __ call(ic, RelocInfo::CODE_TARGET); 1991 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2010 // This nop signals to the IC that there is no inlined code at the call
2011 // site for it to patch.
2012 __ nop();
2013 1992
2014 // If the assignment ends an initialization block, revert to fast case. 1993 // If the assignment ends an initialization block, revert to fast case.
2015 if (expr->ends_initialization_block()) { 1994 if (expr->ends_initialization_block()) {
2016 __ pop(edx); 1995 __ pop(edx);
2017 __ push(eax); // Result of assignment, saved even if not needed. 1996 __ push(eax); // Result of assignment, saved even if not needed.
2018 __ push(edx); 1997 __ push(edx);
2019 __ CallRuntime(Runtime::kToFastProperties, 1); 1998 __ CallRuntime(Runtime::kToFastProperties, 1);
2020 __ pop(eax); 1999 __ pop(eax);
2021 } 2000 }
2022 2001
(...skipping 26 matching lines...) Expand all
2049 ZoneList<Expression*>* args = expr->arguments(); 2028 ZoneList<Expression*>* args = expr->arguments();
2050 int arg_count = args->length(); 2029 int arg_count = args->length();
2051 for (int i = 0; i < arg_count; i++) { 2030 for (int i = 0; i < arg_count; i++) {
2052 VisitForValue(args->at(i), kStack); 2031 VisitForValue(args->at(i), kStack);
2053 } 2032 }
2054 __ Set(ecx, Immediate(name)); 2033 __ Set(ecx, Immediate(name));
2055 // Record source position of the IC call. 2034 // Record source position of the IC call.
2056 SetSourcePosition(expr->position()); 2035 SetSourcePosition(expr->position());
2057 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2036 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2058 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); 2037 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
2059 __ call(ic, mode); 2038 EmitCallIC(ic, mode);
2060 // Restore context register. 2039 // Restore context register.
2061 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2040 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2062 Apply(context_, eax); 2041 Apply(context_, eax);
2063 } 2042 }
2064 2043
2065 2044
2066 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2045 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2067 Expression* key, 2046 Expression* key,
2068 RelocInfo::Mode mode) { 2047 RelocInfo::Mode mode) {
2069 // Code common for calls using the IC. 2048 // Code common for calls using the IC.
2070 ZoneList<Expression*>* args = expr->arguments(); 2049 ZoneList<Expression*>* args = expr->arguments();
2071 int arg_count = args->length(); 2050 int arg_count = args->length();
2072 for (int i = 0; i < arg_count; i++) { 2051 for (int i = 0; i < arg_count; i++) {
2073 VisitForValue(args->at(i), kStack); 2052 VisitForValue(args->at(i), kStack);
2074 } 2053 }
2075 VisitForValue(key, kAccumulator); 2054 VisitForValue(key, kAccumulator);
2076 __ mov(ecx, eax); 2055 __ mov(ecx, eax);
2077 // Record source position of the IC call. 2056 // Record source position of the IC call.
2078 SetSourcePosition(expr->position()); 2057 SetSourcePosition(expr->position());
2079 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2058 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2080 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize( 2059 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(
2081 arg_count, in_loop); 2060 arg_count, in_loop);
2082 __ call(ic, mode); 2061 EmitCallIC(ic, mode);
2083 // Restore context register. 2062 // Restore context register.
2084 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2063 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2085 Apply(context_, eax); 2064 Apply(context_, eax);
2086 } 2065 }
2087 2066
2088 2067
2089 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2068 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
2090 // Code common for calls using the call stub. 2069 // Code common for calls using the call stub.
2091 ZoneList<Expression*>* args = expr->arguments(); 2070 ZoneList<Expression*>* args = expr->arguments();
2092 int arg_count = args->length(); 2071 int arg_count = args->length();
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
2196 // Call to an object property. 2175 // Call to an object property.
2197 Property* prop = fun->AsProperty(); 2176 Property* prop = fun->AsProperty();
2198 Literal* key = prop->key()->AsLiteral(); 2177 Literal* key = prop->key()->AsLiteral();
2199 if (key != NULL && key->handle()->IsSymbol()) { 2178 if (key != NULL && key->handle()->IsSymbol()) {
2200 // Call to a named property, use call IC. 2179 // Call to a named property, use call IC.
2201 VisitForValue(prop->obj(), kStack); 2180 VisitForValue(prop->obj(), kStack);
2202 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 2181 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
2203 } else { 2182 } else {
2204 // Call to a keyed property. 2183 // Call to a keyed property.
2205 // For a synthetic property use keyed load IC followed by function call, 2184 // For a synthetic property use keyed load IC followed by function call,
2206 // for a regular property use keyed CallIC. 2185 // for a regular property use keyed EmitCallIC.
2207 VisitForValue(prop->obj(), kStack); 2186 VisitForValue(prop->obj(), kStack);
2208 if (prop->is_synthetic()) { 2187 if (prop->is_synthetic()) {
2209 VisitForValue(prop->key(), kAccumulator); 2188 VisitForValue(prop->key(), kAccumulator);
2210 // Record source code position for IC call. 2189 // Record source code position for IC call.
2211 SetSourcePosition(prop->position()); 2190 SetSourcePosition(prop->position());
2212 __ pop(edx); // We do not need to keep the receiver. 2191 __ pop(edx); // We do not need to keep the receiver.
2213 2192
2214 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 2193 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
2215 __ call(ic, RelocInfo::CODE_TARGET); 2194 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2216 // By emitting a nop we make sure that we do not have a "test eax,..."
2217 // instruction after the call as it is treated specially
2218 // by the LoadIC code.
2219 __ nop();
2220 // Push result (function). 2195 // Push result (function).
2221 __ push(eax); 2196 __ push(eax);
2222 // Push Global receiver. 2197 // Push Global receiver.
2223 __ mov(ecx, CodeGenerator::GlobalObject()); 2198 __ mov(ecx, CodeGenerator::GlobalObject());
2224 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); 2199 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
2225 EmitCallWithStub(expr); 2200 EmitCallWithStub(expr);
2226 } else { 2201 } else {
2227 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 2202 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2228 } 2203 }
2229 } 2204 }
(...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after
3137 int arg_count = args->length(); 3112 int arg_count = args->length();
3138 for (int i = 0; i < arg_count; i++) { 3113 for (int i = 0; i < arg_count; i++) {
3139 VisitForValue(args->at(i), kStack); 3114 VisitForValue(args->at(i), kStack);
3140 } 3115 }
3141 3116
3142 if (expr->is_jsruntime()) { 3117 if (expr->is_jsruntime()) {
3143 // Call the JS runtime function via a call IC. 3118 // Call the JS runtime function via a call IC.
3144 __ Set(ecx, Immediate(expr->name())); 3119 __ Set(ecx, Immediate(expr->name()));
3145 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 3120 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
3146 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); 3121 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
3147 __ call(ic, RelocInfo::CODE_TARGET); 3122 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3148 // Restore context register. 3123 // Restore context register.
3149 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3124 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3150 } else { 3125 } else {
3151 // Call the C runtime function. 3126 // Call the C runtime function.
3152 __ CallRuntime(expr->function(), arg_count); 3127 __ CallRuntime(expr->function(), arg_count);
3153 } 3128 }
3154 Apply(context_, eax); 3129 Apply(context_, eax);
3155 } 3130 }
3156 3131
3157 3132
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
3443 // Perform the assignment as if via '='. 3418 // Perform the assignment as if via '='.
3444 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3419 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3445 Token::ASSIGN, 3420 Token::ASSIGN,
3446 context_); 3421 context_);
3447 } 3422 }
3448 break; 3423 break;
3449 case NAMED_PROPERTY: { 3424 case NAMED_PROPERTY: {
3450 __ mov(ecx, prop->key()->AsLiteral()->handle()); 3425 __ mov(ecx, prop->key()->AsLiteral()->handle());
3451 __ pop(edx); 3426 __ pop(edx);
3452 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 3427 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
3453 __ call(ic, RelocInfo::CODE_TARGET); 3428 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3454 // This nop signals to the IC that there is no inlined code at the call
3455 // site for it to patch.
3456 __ nop();
3457 if (expr->is_postfix()) { 3429 if (expr->is_postfix()) {
3458 if (context_ != Expression::kEffect) { 3430 if (context_ != Expression::kEffect) {
3459 ApplyTOS(context_); 3431 ApplyTOS(context_);
3460 } 3432 }
3461 } else { 3433 } else {
3462 Apply(context_, eax); 3434 Apply(context_, eax);
3463 } 3435 }
3464 break; 3436 break;
3465 } 3437 }
3466 case KEYED_PROPERTY: { 3438 case KEYED_PROPERTY: {
3467 __ pop(ecx); 3439 __ pop(ecx);
3468 __ pop(edx); 3440 __ pop(edx);
3469 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 3441 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
3470 __ call(ic, RelocInfo::CODE_TARGET); 3442 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3471 // This nop signals to the IC that there is no inlined code at the call
3472 // site for it to patch.
3473 __ nop();
3474 if (expr->is_postfix()) { 3443 if (expr->is_postfix()) {
3475 // Result is on the stack 3444 // Result is on the stack
3476 if (context_ != Expression::kEffect) { 3445 if (context_ != Expression::kEffect) {
3477 ApplyTOS(context_); 3446 ApplyTOS(context_);
3478 } 3447 }
3479 } else { 3448 } else {
3480 Apply(context_, eax); 3449 Apply(context_, eax);
3481 } 3450 }
3482 break; 3451 break;
3483 } 3452 }
3484 } 3453 }
3485 } 3454 }
3486 3455
3487 3456
3488 void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) { 3457 void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) {
3489 VariableProxy* proxy = expr->AsVariableProxy(); 3458 VariableProxy* proxy = expr->AsVariableProxy();
3490 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3459 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3491 Comment cmnt(masm_, "Global variable"); 3460 Comment cmnt(masm_, "Global variable");
3492 __ mov(eax, CodeGenerator::GlobalObject()); 3461 __ mov(eax, CodeGenerator::GlobalObject());
3493 __ mov(ecx, Immediate(proxy->name())); 3462 __ mov(ecx, Immediate(proxy->name()));
3494 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 3463 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
3495 // Use a regular load, not a contextual load, to avoid a reference 3464 // Use a regular load, not a contextual load, to avoid a reference
3496 // error. 3465 // error.
3497 __ call(ic, RelocInfo::CODE_TARGET); 3466 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3498 __ nop(); // Signal no inlined code.
3499 if (where == kStack) __ push(eax); 3467 if (where == kStack) __ push(eax);
3500 } else if (proxy != NULL && 3468 } else if (proxy != NULL &&
3501 proxy->var()->slot() != NULL && 3469 proxy->var()->slot() != NULL &&
3502 proxy->var()->slot()->type() == Slot::LOOKUP) { 3470 proxy->var()->slot()->type() == Slot::LOOKUP) {
3503 Label done, slow; 3471 Label done, slow;
3504 3472
3505 // Generate code for loading from variables potentially shadowed 3473 // Generate code for loading from variables potentially shadowed
3506 // by eval-introduced variables. 3474 // by eval-introduced variables.
3507 Slot* slot = proxy->var()->slot(); 3475 Slot* slot = proxy->var()->slot();
3508 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done); 3476 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done);
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
3740 Apply(context_, if_true, if_false); 3708 Apply(context_, if_true, if_false);
3741 } 3709 }
3742 3710
3743 3711
3744 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 3712 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
3745 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 3713 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
3746 Apply(context_, eax); 3714 Apply(context_, eax);
3747 } 3715 }
3748 3716
3749 3717
3750 Register FullCodeGenerator::result_register() { return eax; } 3718 Register FullCodeGenerator::result_register() {
3719 return eax;
3720 }
3751 3721
3752 3722
3753 Register FullCodeGenerator::context_register() { return esi; } 3723 Register FullCodeGenerator::context_register() {
3724 return esi;
3725 }
3726
3727
3728 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
3729 ASSERT(mode == RelocInfo::CODE_TARGET ||
3730 mode == RelocInfo::CODE_TARGET_CONTEXT);
3731 __ call(ic, mode);
3732
3733 // If we're calling a (keyed) load or store stub, we have to mark
3734 // the call as containing no inlined code so we will not attempt to
3735 // patch it.
3736 switch (ic->kind()) {
3737 case Code::LOAD_IC:
3738 case Code::KEYED_LOAD_IC:
3739 case Code::STORE_IC:
3740 case Code::KEYED_STORE_IC:
3741 __ nop(); // Signals no inlined code.
3742 break;
3743 default:
3744 // Do nothing.
3745 break;
3746 }
3747 }
3754 3748
3755 3749
3756 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 3750 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
3757 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 3751 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
3758 __ mov(Operand(ebp, frame_offset), value); 3752 __ mov(Operand(ebp, frame_offset), value);
3759 } 3753 }
3760 3754
3761 3755
3762 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { 3756 void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
3763 __ mov(dst, ContextOperand(esi, context_index)); 3757 __ mov(dst, ContextOperand(esi, context_index));
(...skipping 29 matching lines...) Expand all
3793 // And return. 3787 // And return.
3794 __ ret(0); 3788 __ ret(0);
3795 } 3789 }
3796 3790
3797 3791
3798 #undef __ 3792 #undef __
3799 3793
3800 } } // namespace v8::internal 3794 } } // namespace v8::internal
3801 3795
3802 #endif // V8_TARGET_ARCH_IA32 3796 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698