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

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

Issue 6880036: Merge revision 7664 (revert of 7644 and 7632) to trunk. (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 8 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/arm/assembler-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 __ mov(r2, r0); 776 __ mov(r2, r0);
777 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); 777 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
778 } 778 }
779 ASSERT(prop->key()->AsLiteral() != NULL && 779 ASSERT(prop->key()->AsLiteral() != NULL &&
780 prop->key()->AsLiteral()->handle()->IsSmi()); 780 prop->key()->AsLiteral()->handle()->IsSmi());
781 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); 781 __ mov(r1, Operand(prop->key()->AsLiteral()->handle()));
782 782
783 Handle<Code> ic = is_strict_mode() 783 Handle<Code> ic = is_strict_mode()
784 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 784 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
785 : isolate()->builtins()->KeyedStoreIC_Initialize(); 785 : isolate()->builtins()->KeyedStoreIC_Initialize();
786 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 786 EmitCallIC(ic, RelocInfo::CODE_TARGET);
787 // Value in r0 is ignored (declarations are statements). 787 // Value in r0 is ignored (declarations are statements).
788 } 788 }
789 } 789 }
790 } 790 }
791 791
792 792
793 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 793 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
794 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 794 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
795 } 795 }
796 796
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 __ cmp(r1, r0); 850 __ cmp(r1, r0);
851 __ b(ne, &next_test); 851 __ b(ne, &next_test);
852 __ Drop(1); // Switch value is no longer needed. 852 __ Drop(1); // Switch value is no longer needed.
853 __ b(clause->body_target()); 853 __ b(clause->body_target());
854 __ bind(&slow_case); 854 __ bind(&slow_case);
855 } 855 }
856 856
857 // Record position before stub call for type feedback. 857 // Record position before stub call for type feedback.
858 SetSourcePosition(clause->position()); 858 SetSourcePosition(clause->position());
859 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); 859 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
860 EmitCallIC(ic, &patch_site, clause->label()->id()); 860 EmitCallIC(ic, &patch_site);
861 __ cmp(r0, Operand(0)); 861 __ cmp(r0, Operand(0));
862 __ b(ne, &next_test); 862 __ b(ne, &next_test);
863 __ Drop(1); // Switch value is no longer needed. 863 __ Drop(1); // Switch value is no longer needed.
864 __ b(clause->body_target()); 864 __ b(clause->body_target());
865 } 865 }
866 866
867 // Discard the test value and jump to the default if present, otherwise to 867 // Discard the test value and jump to the default if present, otherwise to
868 // the end of the statement. 868 // the end of the statement.
869 __ bind(&next_test); 869 __ bind(&next_test);
870 __ Drop(1); // Switch value is no longer needed. 870 __ Drop(1); // Switch value is no longer needed.
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 context()->Plug(r0); 1102 context()->Plug(r0);
1103 } 1103 }
1104 1104
1105 1105
1106 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 1106 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
1107 Comment cmnt(masm_, "[ VariableProxy"); 1107 Comment cmnt(masm_, "[ VariableProxy");
1108 EmitVariableLoad(expr->var()); 1108 EmitVariableLoad(expr->var());
1109 } 1109 }
1110 1110
1111 1111
1112 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
1113 Slot* slot,
1114 TypeofState typeof_state,
1115 Label* slow) {
1116 Register current = cp;
1117 Register next = r1;
1118 Register temp = r2;
1119
1120 Scope* s = scope();
1121 while (s != NULL) {
1122 if (s->num_heap_slots() > 0) {
1123 if (s->calls_eval()) {
1124 // Check that extension is NULL.
1125 __ ldr(temp, ContextOperand(current, Context::EXTENSION_INDEX));
1126 __ tst(temp, temp);
1127 __ b(ne, slow);
1128 }
1129 // Load next context in chain.
1130 __ ldr(next, ContextOperand(current, Context::CLOSURE_INDEX));
1131 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset));
1132 // Walk the rest of the chain without clobbering cp.
1133 current = next;
1134 }
1135 // If no outer scope calls eval, we do not need to check more
1136 // context extensions.
1137 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break;
1138 s = s->outer_scope();
1139 }
1140
1141 if (s->is_eval_scope()) {
1142 Label loop, fast;
1143 if (!current.is(next)) {
1144 __ Move(next, current);
1145 }
1146 __ bind(&loop);
1147 // Terminate at global context.
1148 __ ldr(temp, FieldMemOperand(next, HeapObject::kMapOffset));
1149 __ LoadRoot(ip, Heap::kGlobalContextMapRootIndex);
1150 __ cmp(temp, ip);
1151 __ b(eq, &fast);
1152 // Check that extension is NULL.
1153 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX));
1154 __ tst(temp, temp);
1155 __ b(ne, slow);
1156 // Load next context in chain.
1157 __ ldr(next, ContextOperand(next, Context::CLOSURE_INDEX));
1158 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset));
1159 __ b(&loop);
1160 __ bind(&fast);
1161 }
1162
1163 __ ldr(r0, GlobalObjectOperand());
1164 __ mov(r2, Operand(slot->var()->name()));
1165 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
1166 ? RelocInfo::CODE_TARGET
1167 : RelocInfo::CODE_TARGET_CONTEXT;
1168 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1169 EmitCallIC(ic, mode, AstNode::kNoNumber);
1170 }
1171
1172
1173 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( 1112 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(
1174 Slot* slot, 1113 Slot* slot,
1175 Label* slow) { 1114 Label* slow) {
1176 ASSERT(slot->type() == Slot::CONTEXT); 1115 ASSERT(slot->type() == Slot::CONTEXT);
1177 Register context = cp; 1116 Register context = cp;
1178 Register next = r3; 1117 Register next = r3;
1179 Register temp = r4; 1118 Register temp = r4;
1180 1119
1181 for (Scope* s = scope(); s != slot->var()->scope(); s = s->outer_scope()) { 1120 for (Scope* s = scope(); s != slot->var()->scope(); s = s->outer_scope()) {
1182 if (s->num_heap_slots() > 0) { 1121 if (s->num_heap_slots() > 0) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 key_literal->handle()->IsSmi()) { 1180 key_literal->handle()->IsSmi()) {
1242 // Load arguments object if there are no eval-introduced 1181 // Load arguments object if there are no eval-introduced
1243 // variables. Then load the argument from the arguments 1182 // variables. Then load the argument from the arguments
1244 // object using keyed load. 1183 // object using keyed load.
1245 __ ldr(r1, 1184 __ ldr(r1,
1246 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), 1185 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
1247 slow)); 1186 slow));
1248 __ mov(r0, Operand(key_literal->handle())); 1187 __ mov(r0, Operand(key_literal->handle()));
1249 Handle<Code> ic = 1188 Handle<Code> ic =
1250 isolate()->builtins()->KeyedLoadIC_Initialize(); 1189 isolate()->builtins()->KeyedLoadIC_Initialize();
1251 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1190 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1252 __ jmp(done); 1191 __ jmp(done);
1253 } 1192 }
1254 } 1193 }
1255 } 1194 }
1256 } 1195 }
1257 } 1196 }
1258 1197
1259 1198
1199 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
1200 Slot* slot,
1201 TypeofState typeof_state,
1202 Label* slow) {
1203 Register current = cp;
1204 Register next = r1;
1205 Register temp = r2;
1206
1207 Scope* s = scope();
1208 while (s != NULL) {
1209 if (s->num_heap_slots() > 0) {
1210 if (s->calls_eval()) {
1211 // Check that extension is NULL.
1212 __ ldr(temp, ContextOperand(current, Context::EXTENSION_INDEX));
1213 __ tst(temp, temp);
1214 __ b(ne, slow);
1215 }
1216 // Load next context in chain.
1217 __ ldr(next, ContextOperand(current, Context::CLOSURE_INDEX));
1218 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset));
1219 // Walk the rest of the chain without clobbering cp.
1220 current = next;
1221 }
1222 // If no outer scope calls eval, we do not need to check more
1223 // context extensions.
1224 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break;
1225 s = s->outer_scope();
1226 }
1227
1228 if (s->is_eval_scope()) {
1229 Label loop, fast;
1230 if (!current.is(next)) {
1231 __ Move(next, current);
1232 }
1233 __ bind(&loop);
1234 // Terminate at global context.
1235 __ ldr(temp, FieldMemOperand(next, HeapObject::kMapOffset));
1236 __ LoadRoot(ip, Heap::kGlobalContextMapRootIndex);
1237 __ cmp(temp, ip);
1238 __ b(eq, &fast);
1239 // Check that extension is NULL.
1240 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX));
1241 __ tst(temp, temp);
1242 __ b(ne, slow);
1243 // Load next context in chain.
1244 __ ldr(next, ContextOperand(next, Context::CLOSURE_INDEX));
1245 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset));
1246 __ b(&loop);
1247 __ bind(&fast);
1248 }
1249
1250 __ ldr(r0, GlobalObjectOperand());
1251 __ mov(r2, Operand(slot->var()->name()));
1252 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
1253 ? RelocInfo::CODE_TARGET
1254 : RelocInfo::CODE_TARGET_CONTEXT;
1255 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1256 EmitCallIC(ic, mode);
1257 }
1258
1259
1260 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1260 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1261 // Four cases: non-this global variables, lookup slots, all other 1261 // Four cases: non-this global variables, lookup slots, all other
1262 // types of slots, and parameters that rewrite to explicit property 1262 // types of slots, and parameters that rewrite to explicit property
1263 // accesses on the arguments object. 1263 // accesses on the arguments object.
1264 Slot* slot = var->AsSlot(); 1264 Slot* slot = var->AsSlot();
1265 Property* property = var->AsProperty(); 1265 Property* property = var->AsProperty();
1266 1266
1267 if (var->is_global() && !var->is_this()) { 1267 if (var->is_global() && !var->is_this()) {
1268 Comment cmnt(masm_, "Global variable"); 1268 Comment cmnt(masm_, "Global variable");
1269 // Use inline caching. Variable name is passed in r2 and the global 1269 // Use inline caching. Variable name is passed in r2 and the global
1270 // object (receiver) in r0. 1270 // object (receiver) in r0.
1271 __ ldr(r0, GlobalObjectOperand()); 1271 __ ldr(r0, GlobalObjectOperand());
1272 __ mov(r2, Operand(var->name())); 1272 __ mov(r2, Operand(var->name()));
1273 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1273 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1274 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); 1274 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1275 context()->Plug(r0); 1275 context()->Plug(r0);
1276 1276
1277 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 1277 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
1278 Label done, slow; 1278 Label done, slow;
1279 1279
1280 // Generate code for loading from variables potentially shadowed 1280 // Generate code for loading from variables potentially shadowed
1281 // by eval-introduced variables. 1281 // by eval-introduced variables.
1282 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1282 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
1283 1283
1284 __ bind(&slow); 1284 __ bind(&slow);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 // Assert that the key is a smi. 1323 // Assert that the key is a smi.
1324 Literal* key_literal = property->key()->AsLiteral(); 1324 Literal* key_literal = property->key()->AsLiteral();
1325 ASSERT_NOT_NULL(key_literal); 1325 ASSERT_NOT_NULL(key_literal);
1326 ASSERT(key_literal->handle()->IsSmi()); 1326 ASSERT(key_literal->handle()->IsSmi());
1327 1327
1328 // Load the key. 1328 // Load the key.
1329 __ mov(r0, Operand(key_literal->handle())); 1329 __ mov(r0, Operand(key_literal->handle()));
1330 1330
1331 // Call keyed load IC. It has arguments key and receiver in r0 and r1. 1331 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
1332 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1332 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1333 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1333 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1334 context()->Plug(r0); 1334 context()->Plug(r0);
1335 } 1335 }
1336 } 1336 }
1337 1337
1338 1338
1339 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1339 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1340 Comment cmnt(masm_, "[ RegExpLiteral"); 1340 Comment cmnt(masm_, "[ RegExpLiteral");
1341 Label materialized; 1341 Label materialized;
1342 // Registers will be used as follows: 1342 // Registers will be used as follows:
1343 // r5 = materialized value (RegExp literal) 1343 // r5 = materialized value (RegExp literal)
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 UNREACHABLE(); 1431 UNREACHABLE();
1432 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1432 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1433 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); 1433 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value()));
1434 // Fall through. 1434 // Fall through.
1435 case ObjectLiteral::Property::COMPUTED: 1435 case ObjectLiteral::Property::COMPUTED:
1436 if (key->handle()->IsSymbol()) { 1436 if (key->handle()->IsSymbol()) {
1437 if (property->emit_store()) { 1437 if (property->emit_store()) {
1438 VisitForAccumulatorValue(value); 1438 VisitForAccumulatorValue(value);
1439 __ mov(r2, Operand(key->handle())); 1439 __ mov(r2, Operand(key->handle()));
1440 __ ldr(r1, MemOperand(sp)); 1440 __ ldr(r1, MemOperand(sp));
1441 Handle<Code> ic = is_strict_mode() 1441 Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize();
1442 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1442 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1443 : isolate()->builtins()->StoreIC_Initialize();
1444 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, key->id());
1445 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1443 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1446 } else { 1444 } else {
1447 VisitForEffect(value); 1445 VisitForEffect(value);
1448 } 1446 }
1449 break; 1447 break;
1450 } 1448 }
1451 // Fall through. 1449 // Fall through.
1452 case ObjectLiteral::Property::PROTOTYPE: 1450 case ObjectLiteral::Property::PROTOTYPE:
1453 // Duplicate receiver on stack. 1451 // Duplicate receiver on stack.
1454 __ ldr(r0, MemOperand(sp)); 1452 __ ldr(r0, MemOperand(sp));
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1646 Token::Value op = expr->binary_op(); 1644 Token::Value op = expr->binary_op();
1647 __ push(r0); // Left operand goes on the stack. 1645 __ push(r0); // Left operand goes on the stack.
1648 VisitForAccumulatorValue(expr->value()); 1646 VisitForAccumulatorValue(expr->value());
1649 1647
1650 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1648 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1651 ? OVERWRITE_RIGHT 1649 ? OVERWRITE_RIGHT
1652 : NO_OVERWRITE; 1650 : NO_OVERWRITE;
1653 SetSourcePosition(expr->position() + 1); 1651 SetSourcePosition(expr->position() + 1);
1654 AccumulatorValueContext context(this); 1652 AccumulatorValueContext context(this);
1655 if (ShouldInlineSmiCase(op)) { 1653 if (ShouldInlineSmiCase(op)) {
1656 EmitInlineSmiBinaryOp(expr->binary_operation(), 1654 EmitInlineSmiBinaryOp(expr,
1657 op, 1655 op,
1658 mode, 1656 mode,
1659 expr->target(), 1657 expr->target(),
1660 expr->value()); 1658 expr->value());
1661 } else { 1659 } else {
1662 EmitBinaryOp(expr->binary_operation(), op, mode); 1660 EmitBinaryOp(op, mode);
1663 } 1661 }
1664 1662
1665 // Deoptimization point in case the binary operation may have side effects. 1663 // Deoptimization point in case the binary operation may have side effects.
1666 PrepareForBailout(expr->binary_operation(), TOS_REG); 1664 PrepareForBailout(expr->binary_operation(), TOS_REG);
1667 } else { 1665 } else {
1668 VisitForAccumulatorValue(expr->value()); 1666 VisitForAccumulatorValue(expr->value());
1669 } 1667 }
1670 1668
1671 // Record source position before possible IC call. 1669 // Record source position before possible IC call.
1672 SetSourcePosition(expr->position()); 1670 SetSourcePosition(expr->position());
(...skipping 15 matching lines...) Expand all
1688 } 1686 }
1689 } 1687 }
1690 1688
1691 1689
1692 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1690 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1693 SetSourcePosition(prop->position()); 1691 SetSourcePosition(prop->position());
1694 Literal* key = prop->key()->AsLiteral(); 1692 Literal* key = prop->key()->AsLiteral();
1695 __ mov(r2, Operand(key->handle())); 1693 __ mov(r2, Operand(key->handle()));
1696 // Call load IC. It has arguments receiver and property name r0 and r2. 1694 // Call load IC. It has arguments receiver and property name r0 and r2.
1697 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1695 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1698 if (prop->is_synthetic()) { 1696 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1699 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
1700 } else {
1701 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, prop->id());
1702 }
1703 } 1697 }
1704 1698
1705 1699
1706 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1700 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1707 SetSourcePosition(prop->position()); 1701 SetSourcePosition(prop->position());
1708 // Call keyed load IC. It has arguments key and receiver in r0 and r1. 1702 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
1709 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1703 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1710 if (prop->is_synthetic()) { 1704 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1711 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
1712 } else {
1713 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, prop->id());
1714 }
1715 } 1705 }
1716 1706
1717 1707
1718 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 1708 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr,
1719 Token::Value op, 1709 Token::Value op,
1720 OverwriteMode mode, 1710 OverwriteMode mode,
1721 Expression* left_expr, 1711 Expression* left_expr,
1722 Expression* right_expr) { 1712 Expression* right_expr) {
1723 Label done, smi_case, stub_call; 1713 Label done, smi_case, stub_call;
1724 1714
1725 Register scratch1 = r2; 1715 Register scratch1 = r2;
1726 Register scratch2 = r3; 1716 Register scratch2 = r3;
1727 1717
1728 // Get the arguments. 1718 // Get the arguments.
1729 Register left = r1; 1719 Register left = r1;
1730 Register right = r0; 1720 Register right = r0;
1731 __ pop(left); 1721 __ pop(left);
1732 1722
1733 // Perform combined smi check on both operands. 1723 // Perform combined smi check on both operands.
1734 __ orr(scratch1, left, Operand(right)); 1724 __ orr(scratch1, left, Operand(right));
1735 STATIC_ASSERT(kSmiTag == 0); 1725 STATIC_ASSERT(kSmiTag == 0);
1736 JumpPatchSite patch_site(masm_); 1726 JumpPatchSite patch_site(masm_);
1737 patch_site.EmitJumpIfSmi(scratch1, &smi_case); 1727 patch_site.EmitJumpIfSmi(scratch1, &smi_case);
1738 1728
1739 __ bind(&stub_call); 1729 __ bind(&stub_call);
1740 TypeRecordingBinaryOpStub stub(op, mode); 1730 TypeRecordingBinaryOpStub stub(op, mode);
1741 EmitCallIC(stub.GetCode(), &patch_site, expr->id()); 1731 EmitCallIC(stub.GetCode(), &patch_site);
1742 __ jmp(&done); 1732 __ jmp(&done);
1743 1733
1744 __ bind(&smi_case); 1734 __ bind(&smi_case);
1745 // Smi case. This code works the same way as the smi-smi case in the type 1735 // Smi case. This code works the same way as the smi-smi case in the type
1746 // recording binary operation stub, see 1736 // recording binary operation stub, see
1747 // TypeRecordingBinaryOpStub::GenerateSmiSmiOperation for comments. 1737 // TypeRecordingBinaryOpStub::GenerateSmiSmiOperation for comments.
1748 switch (op) { 1738 switch (op) {
1749 case Token::SAR: 1739 case Token::SAR:
1750 __ b(&stub_call); 1740 __ b(&stub_call);
1751 __ GetLeastBitsFromSmi(scratch1, right, 5); 1741 __ GetLeastBitsFromSmi(scratch1, right, 5);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1807 break; 1797 break;
1808 default: 1798 default:
1809 UNREACHABLE(); 1799 UNREACHABLE();
1810 } 1800 }
1811 1801
1812 __ bind(&done); 1802 __ bind(&done);
1813 context()->Plug(r0); 1803 context()->Plug(r0);
1814 } 1804 }
1815 1805
1816 1806
1817 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 1807 void FullCodeGenerator::EmitBinaryOp(Token::Value op,
1818 Token::Value op,
1819 OverwriteMode mode) { 1808 OverwriteMode mode) {
1820 __ pop(r1); 1809 __ pop(r1);
1821 TypeRecordingBinaryOpStub stub(op, mode); 1810 TypeRecordingBinaryOpStub stub(op, mode);
1822 EmitCallIC(stub.GetCode(), NULL, expr->id()); 1811 EmitCallIC(stub.GetCode(), NULL);
1823 context()->Plug(r0); 1812 context()->Plug(r0);
1824 } 1813 }
1825 1814
1826 1815
1827 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1816 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1828 // Invalid left-hand sides are rewritten to have a 'throw 1817 // Invalid left-hand sides are rewritten to have a 'throw
1829 // ReferenceError' on the left-hand side. 1818 // ReferenceError' on the left-hand side.
1830 if (!expr->IsValidLeftHandSide()) { 1819 if (!expr->IsValidLeftHandSide()) {
1831 VisitForEffect(expr); 1820 VisitForEffect(expr);
1832 return; 1821 return;
(...skipping 19 matching lines...) Expand all
1852 } 1841 }
1853 case NAMED_PROPERTY: { 1842 case NAMED_PROPERTY: {
1854 __ push(r0); // Preserve value. 1843 __ push(r0); // Preserve value.
1855 VisitForAccumulatorValue(prop->obj()); 1844 VisitForAccumulatorValue(prop->obj());
1856 __ mov(r1, r0); 1845 __ mov(r1, r0);
1857 __ pop(r0); // Restore value. 1846 __ pop(r0); // Restore value.
1858 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); 1847 __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
1859 Handle<Code> ic = is_strict_mode() 1848 Handle<Code> ic = is_strict_mode()
1860 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1849 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1861 : isolate()->builtins()->StoreIC_Initialize(); 1850 : isolate()->builtins()->StoreIC_Initialize();
1862 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1851 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1863 break; 1852 break;
1864 } 1853 }
1865 case KEYED_PROPERTY: { 1854 case KEYED_PROPERTY: {
1866 __ push(r0); // Preserve value. 1855 __ push(r0); // Preserve value.
1867 if (prop->is_synthetic()) { 1856 if (prop->is_synthetic()) {
1868 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1857 ASSERT(prop->obj()->AsVariableProxy() != NULL);
1869 ASSERT(prop->key()->AsLiteral() != NULL); 1858 ASSERT(prop->key()->AsLiteral() != NULL);
1870 { AccumulatorValueContext for_object(this); 1859 { AccumulatorValueContext for_object(this);
1871 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); 1860 EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
1872 } 1861 }
1873 __ mov(r2, r0); 1862 __ mov(r2, r0);
1874 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); 1863 __ mov(r1, Operand(prop->key()->AsLiteral()->handle()));
1875 } else { 1864 } else {
1876 VisitForStackValue(prop->obj()); 1865 VisitForStackValue(prop->obj());
1877 VisitForAccumulatorValue(prop->key()); 1866 VisitForAccumulatorValue(prop->key());
1878 __ mov(r1, r0); 1867 __ mov(r1, r0);
1879 __ pop(r2); 1868 __ pop(r2);
1880 } 1869 }
1881 __ pop(r0); // Restore value. 1870 __ pop(r0); // Restore value.
1882 Handle<Code> ic = is_strict_mode() 1871 Handle<Code> ic = is_strict_mode()
1883 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1872 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1884 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1873 : isolate()->builtins()->KeyedStoreIC_Initialize();
1885 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1874 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1886 break; 1875 break;
1887 } 1876 }
1888 } 1877 }
1889 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1878 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1890 context()->Plug(r0); 1879 context()->Plug(r0);
1891 } 1880 }
1892 1881
1893 1882
1894 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1883 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1895 Token::Value op) { 1884 Token::Value op) {
1896 // Left-hand sides that rewrite to explicit property accesses do not reach 1885 // Left-hand sides that rewrite to explicit property accesses do not reach
1897 // here. 1886 // here.
1898 ASSERT(var != NULL); 1887 ASSERT(var != NULL);
1899 ASSERT(var->is_global() || var->AsSlot() != NULL); 1888 ASSERT(var->is_global() || var->AsSlot() != NULL);
1900 1889
1901 if (var->is_global()) { 1890 if (var->is_global()) {
1902 ASSERT(!var->is_this()); 1891 ASSERT(!var->is_this());
1903 // Assignment to a global variable. Use inline caching for the 1892 // Assignment to a global variable. Use inline caching for the
1904 // assignment. Right-hand-side value is passed in r0, variable name in 1893 // assignment. Right-hand-side value is passed in r0, variable name in
1905 // r2, and the global object in r1. 1894 // r2, and the global object in r1.
1906 __ mov(r2, Operand(var->name())); 1895 __ mov(r2, Operand(var->name()));
1907 __ ldr(r1, GlobalObjectOperand()); 1896 __ ldr(r1, GlobalObjectOperand());
1908 Handle<Code> ic = is_strict_mode() 1897 Handle<Code> ic = is_strict_mode()
1909 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1898 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1910 : isolate()->builtins()->StoreIC_Initialize(); 1899 : isolate()->builtins()->StoreIC_Initialize();
1911 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); 1900 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1912 1901
1913 } else if (op == Token::INIT_CONST) { 1902 } else if (op == Token::INIT_CONST) {
1914 // Like var declarations, const declarations are hoisted to function 1903 // Like var declarations, const declarations are hoisted to function
1915 // scope. However, unlike var initializers, const initializers are able 1904 // scope. However, unlike var initializers, const initializers are able
1916 // to drill a hole to that function context, even from inside a 'with' 1905 // to drill a hole to that function context, even from inside a 'with'
1917 // context. We thus bypass the normal static scope lookup. 1906 // context. We thus bypass the normal static scope lookup.
1918 Slot* slot = var->AsSlot(); 1907 Slot* slot = var->AsSlot();
1919 Label skip; 1908 Label skip;
1920 switch (slot->type()) { 1909 switch (slot->type()) {
1921 case Slot::PARAMETER: 1910 case Slot::PARAMETER:
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2010 // receiver into fast case. 1999 // receiver into fast case.
2011 if (expr->ends_initialization_block()) { 2000 if (expr->ends_initialization_block()) {
2012 __ ldr(r1, MemOperand(sp)); 2001 __ ldr(r1, MemOperand(sp));
2013 } else { 2002 } else {
2014 __ pop(r1); 2003 __ pop(r1);
2015 } 2004 }
2016 2005
2017 Handle<Code> ic = is_strict_mode() 2006 Handle<Code> ic = is_strict_mode()
2018 ? isolate()->builtins()->StoreIC_Initialize_Strict() 2007 ? isolate()->builtins()->StoreIC_Initialize_Strict()
2019 : isolate()->builtins()->StoreIC_Initialize(); 2008 : isolate()->builtins()->StoreIC_Initialize();
2020 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); 2009 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2021 2010
2022 // If the assignment ends an initialization block, revert to fast case. 2011 // If the assignment ends an initialization block, revert to fast case.
2023 if (expr->ends_initialization_block()) { 2012 if (expr->ends_initialization_block()) {
2024 __ push(r0); // Result of assignment, saved even if not needed. 2013 __ push(r0); // Result of assignment, saved even if not needed.
2025 // Receiver is under the result value. 2014 // Receiver is under the result value.
2026 __ ldr(ip, MemOperand(sp, kPointerSize)); 2015 __ ldr(ip, MemOperand(sp, kPointerSize));
2027 __ push(ip); 2016 __ push(ip);
2028 __ CallRuntime(Runtime::kToFastProperties, 1); 2017 __ CallRuntime(Runtime::kToFastProperties, 1);
2029 __ pop(r0); 2018 __ pop(r0);
2030 __ Drop(1); 2019 __ Drop(1);
(...skipping 25 matching lines...) Expand all
2056 // receiver into fast case. 2045 // receiver into fast case.
2057 if (expr->ends_initialization_block()) { 2046 if (expr->ends_initialization_block()) {
2058 __ ldr(r2, MemOperand(sp)); 2047 __ ldr(r2, MemOperand(sp));
2059 } else { 2048 } else {
2060 __ pop(r2); 2049 __ pop(r2);
2061 } 2050 }
2062 2051
2063 Handle<Code> ic = is_strict_mode() 2052 Handle<Code> ic = is_strict_mode()
2064 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 2053 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
2065 : isolate()->builtins()->KeyedStoreIC_Initialize(); 2054 : isolate()->builtins()->KeyedStoreIC_Initialize();
2066 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); 2055 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2067 2056
2068 // If the assignment ends an initialization block, revert to fast case. 2057 // If the assignment ends an initialization block, revert to fast case.
2069 if (expr->ends_initialization_block()) { 2058 if (expr->ends_initialization_block()) {
2070 __ push(r0); // Result of assignment, saved even if not needed. 2059 __ push(r0); // Result of assignment, saved even if not needed.
2071 // Receiver is under the result value. 2060 // Receiver is under the result value.
2072 __ ldr(ip, MemOperand(sp, kPointerSize)); 2061 __ ldr(ip, MemOperand(sp, kPointerSize));
2073 __ push(ip); 2062 __ push(ip);
2074 __ CallRuntime(Runtime::kToFastProperties, 1); 2063 __ CallRuntime(Runtime::kToFastProperties, 1);
2075 __ pop(r0); 2064 __ pop(r0);
2076 __ Drop(1); 2065 __ Drop(1);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2108 VisitForStackValue(args->at(i)); 2097 VisitForStackValue(args->at(i));
2109 } 2098 }
2110 __ mov(r2, Operand(name)); 2099 __ mov(r2, Operand(name));
2111 } 2100 }
2112 // Record source position for debugger. 2101 // Record source position for debugger.
2113 SetSourcePosition(expr->position()); 2102 SetSourcePosition(expr->position());
2114 // Call the IC initialization code. 2103 // Call the IC initialization code.
2115 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2104 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2116 Handle<Code> ic = 2105 Handle<Code> ic =
2117 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop); 2106 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop);
2118 unsigned ast_id = 2107 EmitCallIC(ic, mode);
2119 (mode == RelocInfo::CODE_TARGET_WITH_ID) ? expr->id() : kNoASTId;
2120 EmitCallIC(ic, mode, ast_id);
2121 RecordJSReturnSite(expr); 2108 RecordJSReturnSite(expr);
2122 // Restore context register. 2109 // Restore context register.
2123 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2110 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2124 context()->Plug(r0); 2111 context()->Plug(r0);
2125 } 2112 }
2126 2113
2127 2114
2128 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2115 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2129 Expression* key, 2116 Expression* key,
2130 RelocInfo::Mode mode) { 2117 RelocInfo::Mode mode) {
(...skipping 14 matching lines...) Expand all
2145 VisitForStackValue(args->at(i)); 2132 VisitForStackValue(args->at(i));
2146 } 2133 }
2147 } 2134 }
2148 // Record source position for debugger. 2135 // Record source position for debugger.
2149 SetSourcePosition(expr->position()); 2136 SetSourcePosition(expr->position());
2150 // Call the IC initialization code. 2137 // Call the IC initialization code.
2151 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2138 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2152 Handle<Code> ic = 2139 Handle<Code> ic =
2153 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); 2140 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop);
2154 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. 2141 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key.
2155 EmitCallIC(ic, mode, expr->id()); 2142 EmitCallIC(ic, mode);
2156 RecordJSReturnSite(expr); 2143 RecordJSReturnSite(expr);
2157 // Restore context register. 2144 // Restore context register.
2158 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2145 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2159 context()->DropAndPlug(1, r0); // Drop the key still on the stack. 2146 context()->DropAndPlug(1, r0); // Drop the key still on the stack.
2160 } 2147 }
2161 2148
2162 2149
2163 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2150 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
2164 // Code common for calls using the call stub. 2151 // Code common for calls using the call stub.
2165 ZoneList<Expression*>* args = expr->arguments(); 2152 ZoneList<Expression*>* args = expr->arguments();
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
2321 EmitCallWithStub(expr); 2308 EmitCallWithStub(expr);
2322 } else if (fun->AsProperty() != NULL) { 2309 } else if (fun->AsProperty() != NULL) {
2323 // Call to an object property. 2310 // Call to an object property.
2324 Property* prop = fun->AsProperty(); 2311 Property* prop = fun->AsProperty();
2325 Literal* key = prop->key()->AsLiteral(); 2312 Literal* key = prop->key()->AsLiteral();
2326 if (key != NULL && key->handle()->IsSymbol()) { 2313 if (key != NULL && key->handle()->IsSymbol()) {
2327 // Call to a named property, use call IC. 2314 // Call to a named property, use call IC.
2328 { PreservePositionScope scope(masm()->positions_recorder()); 2315 { PreservePositionScope scope(masm()->positions_recorder());
2329 VisitForStackValue(prop->obj()); 2316 VisitForStackValue(prop->obj());
2330 } 2317 }
2331 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET_WITH_ID); 2318 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
2332 } else { 2319 } else {
2333 // Call to a keyed property. 2320 // Call to a keyed property.
2334 // For a synthetic property use keyed load IC followed by function call, 2321 // For a synthetic property use keyed load IC followed by function call,
2335 // for a regular property use keyed EmitCallIC. 2322 // for a regular property use keyed CallIC.
2336 if (prop->is_synthetic()) { 2323 if (prop->is_synthetic()) {
2337 // Do not visit the object and key subexpressions (they are shared 2324 // Do not visit the object and key subexpressions (they are shared
2338 // by all occurrences of the same rewritten parameter). 2325 // by all occurrences of the same rewritten parameter).
2339 ASSERT(prop->obj()->AsVariableProxy() != NULL); 2326 ASSERT(prop->obj()->AsVariableProxy() != NULL);
2340 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); 2327 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL);
2341 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); 2328 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot();
2342 MemOperand operand = EmitSlotSearch(slot, r1); 2329 MemOperand operand = EmitSlotSearch(slot, r1);
2343 __ ldr(r1, operand); 2330 __ ldr(r1, operand);
2344 2331
2345 ASSERT(prop->key()->AsLiteral() != NULL); 2332 ASSERT(prop->key()->AsLiteral() != NULL);
2346 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); 2333 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2347 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); 2334 __ mov(r0, Operand(prop->key()->AsLiteral()->handle()));
2348 2335
2349 // Record source code position for IC call. 2336 // Record source code position for IC call.
2350 SetSourcePosition(prop->position()); 2337 SetSourcePosition(prop->position());
2351 2338
2352 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2339 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2353 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 2340 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2354 __ ldr(r1, GlobalObjectOperand()); 2341 __ ldr(r1, GlobalObjectOperand());
2355 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); 2342 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
2356 __ Push(r0, r1); // Function, receiver. 2343 __ Push(r0, r1); // Function, receiver.
2357 EmitCallWithStub(expr); 2344 EmitCallWithStub(expr);
2358 } else { 2345 } else {
2359 { PreservePositionScope scope(masm()->positions_recorder()); 2346 { PreservePositionScope scope(masm()->positions_recorder());
2360 VisitForStackValue(prop->obj()); 2347 VisitForStackValue(prop->obj());
2361 } 2348 }
2362 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET_WITH_ID); 2349 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2363 } 2350 }
2364 } 2351 }
2365 } else { 2352 } else {
2366 { PreservePositionScope scope(masm()->positions_recorder()); 2353 { PreservePositionScope scope(masm()->positions_recorder());
2367 VisitForStackValue(fun); 2354 VisitForStackValue(fun);
2368 } 2355 }
2369 // Load global receiver object. 2356 // Load global receiver object.
2370 __ ldr(r1, GlobalObjectOperand()); 2357 __ ldr(r1, GlobalObjectOperand());
2371 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); 2358 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
2372 __ push(r1); 2359 __ push(r1);
(...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after
3663 int arg_count = args->length(); 3650 int arg_count = args->length();
3664 for (int i = 0; i < arg_count; i++) { 3651 for (int i = 0; i < arg_count; i++) {
3665 VisitForStackValue(args->at(i)); 3652 VisitForStackValue(args->at(i));
3666 } 3653 }
3667 3654
3668 if (expr->is_jsruntime()) { 3655 if (expr->is_jsruntime()) {
3669 // Call the JS runtime function. 3656 // Call the JS runtime function.
3670 __ mov(r2, Operand(expr->name())); 3657 __ mov(r2, Operand(expr->name()));
3671 Handle<Code> ic = 3658 Handle<Code> ic =
3672 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); 3659 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP);
3673 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); 3660 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3674 // Restore context register. 3661 // Restore context register.
3675 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3662 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3676 } else { 3663 } else {
3677 // Call the C runtime function. 3664 // Call the C runtime function.
3678 __ CallRuntime(expr->function(), arg_count); 3665 __ CallRuntime(expr->function(), arg_count);
3679 } 3666 }
3680 context()->Plug(r0); 3667 context()->Plug(r0);
3681 } 3668 }
3682 3669
3683 3670
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
3942 __ bind(&stub_call); 3929 __ bind(&stub_call);
3943 // Call stub. Undo operation first. 3930 // Call stub. Undo operation first.
3944 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); 3931 __ sub(r0, r0, Operand(Smi::FromInt(count_value)));
3945 } 3932 }
3946 __ mov(r1, Operand(Smi::FromInt(count_value))); 3933 __ mov(r1, Operand(Smi::FromInt(count_value)));
3947 3934
3948 // Record position before stub call. 3935 // Record position before stub call.
3949 SetSourcePosition(expr->position()); 3936 SetSourcePosition(expr->position());
3950 3937
3951 TypeRecordingBinaryOpStub stub(Token::ADD, NO_OVERWRITE); 3938 TypeRecordingBinaryOpStub stub(Token::ADD, NO_OVERWRITE);
3952 EmitCallIC(stub.GetCode(), &patch_site, expr->CountId()); 3939 EmitCallIC(stub.GetCode(), &patch_site);
3953 __ bind(&done); 3940 __ bind(&done);
3954 3941
3955 // Store the value returned in r0. 3942 // Store the value returned in r0.
3956 switch (assign_type) { 3943 switch (assign_type) {
3957 case VARIABLE: 3944 case VARIABLE:
3958 if (expr->is_postfix()) { 3945 if (expr->is_postfix()) {
3959 { EffectContext context(this); 3946 { EffectContext context(this);
3960 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3947 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3961 Token::ASSIGN); 3948 Token::ASSIGN);
3962 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3949 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
(...skipping 10 matching lines...) Expand all
3973 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3960 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3974 context()->Plug(r0); 3961 context()->Plug(r0);
3975 } 3962 }
3976 break; 3963 break;
3977 case NAMED_PROPERTY: { 3964 case NAMED_PROPERTY: {
3978 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); 3965 __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
3979 __ pop(r1); 3966 __ pop(r1);
3980 Handle<Code> ic = is_strict_mode() 3967 Handle<Code> ic = is_strict_mode()
3981 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3968 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3982 : isolate()->builtins()->StoreIC_Initialize(); 3969 : isolate()->builtins()->StoreIC_Initialize();
3983 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); 3970 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3984 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3971 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3985 if (expr->is_postfix()) { 3972 if (expr->is_postfix()) {
3986 if (!context()->IsEffect()) { 3973 if (!context()->IsEffect()) {
3987 context()->PlugTOS(); 3974 context()->PlugTOS();
3988 } 3975 }
3989 } else { 3976 } else {
3990 context()->Plug(r0); 3977 context()->Plug(r0);
3991 } 3978 }
3992 break; 3979 break;
3993 } 3980 }
3994 case KEYED_PROPERTY: { 3981 case KEYED_PROPERTY: {
3995 __ pop(r1); // Key. 3982 __ pop(r1); // Key.
3996 __ pop(r2); // Receiver. 3983 __ pop(r2); // Receiver.
3997 Handle<Code> ic = is_strict_mode() 3984 Handle<Code> ic = is_strict_mode()
3998 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3985 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3999 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3986 : isolate()->builtins()->KeyedStoreIC_Initialize();
4000 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); 3987 EmitCallIC(ic, RelocInfo::CODE_TARGET);
4001 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3988 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4002 if (expr->is_postfix()) { 3989 if (expr->is_postfix()) {
4003 if (!context()->IsEffect()) { 3990 if (!context()->IsEffect()) {
4004 context()->PlugTOS(); 3991 context()->PlugTOS();
4005 } 3992 }
4006 } else { 3993 } else {
4007 context()->Plug(r0); 3994 context()->Plug(r0);
4008 } 3995 }
4009 break; 3996 break;
4010 } 3997 }
4011 } 3998 }
4012 } 3999 }
4013 4000
4014 4001
4015 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 4002 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
4016 ASSERT(!context()->IsEffect()); 4003 ASSERT(!context()->IsEffect());
4017 ASSERT(!context()->IsTest()); 4004 ASSERT(!context()->IsTest());
4018 VariableProxy* proxy = expr->AsVariableProxy(); 4005 VariableProxy* proxy = expr->AsVariableProxy();
4019 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 4006 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
4020 Comment cmnt(masm_, "Global variable"); 4007 Comment cmnt(masm_, "Global variable");
4021 __ ldr(r0, GlobalObjectOperand()); 4008 __ ldr(r0, GlobalObjectOperand());
4022 __ mov(r2, Operand(proxy->name())); 4009 __ mov(r2, Operand(proxy->name()));
4023 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 4010 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
4024 // Use a regular load, not a contextual load, to avoid a reference 4011 // Use a regular load, not a contextual load, to avoid a reference
4025 // error. 4012 // error.
4026 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 4013 EmitCallIC(ic, RelocInfo::CODE_TARGET);
4027 PrepareForBailout(expr, TOS_REG); 4014 PrepareForBailout(expr, TOS_REG);
4028 context()->Plug(r0); 4015 context()->Plug(r0);
4029 } else if (proxy != NULL && 4016 } else if (proxy != NULL &&
4030 proxy->var()->AsSlot() != NULL && 4017 proxy->var()->AsSlot() != NULL &&
4031 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { 4018 proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
4032 Label done, slow; 4019 Label done, slow;
4033 4020
4034 // Generate code for loading from variables potentially shadowed 4021 // Generate code for loading from variables potentially shadowed
4035 // by eval-introduced variables. 4022 // by eval-introduced variables.
4036 Slot* slot = proxy->var()->AsSlot(); 4023 Slot* slot = proxy->var()->AsSlot();
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
4219 __ orr(r2, r0, Operand(r1)); 4206 __ orr(r2, r0, Operand(r1));
4220 patch_site.EmitJumpIfNotSmi(r2, &slow_case); 4207 patch_site.EmitJumpIfNotSmi(r2, &slow_case);
4221 __ cmp(r1, r0); 4208 __ cmp(r1, r0);
4222 Split(cond, if_true, if_false, NULL); 4209 Split(cond, if_true, if_false, NULL);
4223 __ bind(&slow_case); 4210 __ bind(&slow_case);
4224 } 4211 }
4225 4212
4226 // Record position and call the compare IC. 4213 // Record position and call the compare IC.
4227 SetSourcePosition(expr->position()); 4214 SetSourcePosition(expr->position());
4228 Handle<Code> ic = CompareIC::GetUninitialized(op); 4215 Handle<Code> ic = CompareIC::GetUninitialized(op);
4229 EmitCallIC(ic, &patch_site, expr->id()); 4216 EmitCallIC(ic, &patch_site);
4230 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4217 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4231 __ cmp(r0, Operand(0)); 4218 __ cmp(r0, Operand(0));
4232 Split(cond, if_true, if_false, fall_through); 4219 Split(cond, if_true, if_false, fall_through);
4233 } 4220 }
4234 } 4221 }
4235 4222
4236 // Convert the result of the comparison into one expected for this 4223 // Convert the result of the comparison into one expected for this
4237 // expression's context. 4224 // expression's context.
4238 context()->Plug(if_true, if_false); 4225 context()->Plug(if_true, if_false);
4239 } 4226 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4281 Register FullCodeGenerator::result_register() { 4268 Register FullCodeGenerator::result_register() {
4282 return r0; 4269 return r0;
4283 } 4270 }
4284 4271
4285 4272
4286 Register FullCodeGenerator::context_register() { 4273 Register FullCodeGenerator::context_register() {
4287 return cp; 4274 return cp;
4288 } 4275 }
4289 4276
4290 4277
4291 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, 4278 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
4292 RelocInfo::Mode mode,
4293 unsigned ast_id) {
4294 ASSERT(mode == RelocInfo::CODE_TARGET || 4279 ASSERT(mode == RelocInfo::CODE_TARGET ||
4295 mode == RelocInfo::CODE_TARGET_CONTEXT || 4280 mode == RelocInfo::CODE_TARGET_CONTEXT);
4296 mode == RelocInfo::CODE_TARGET_WITH_ID);
4297 Counters* counters = isolate()->counters(); 4281 Counters* counters = isolate()->counters();
4298 switch (ic->kind()) { 4282 switch (ic->kind()) {
4299 case Code::LOAD_IC: 4283 case Code::LOAD_IC:
4300 __ IncrementCounter(counters->named_load_full(), 1, r1, r2); 4284 __ IncrementCounter(counters->named_load_full(), 1, r1, r2);
4301 break; 4285 break;
4302 case Code::KEYED_LOAD_IC: 4286 case Code::KEYED_LOAD_IC:
4303 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2); 4287 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
4304 break; 4288 break;
4305 case Code::STORE_IC: 4289 case Code::STORE_IC:
4306 __ IncrementCounter(counters->named_store_full(), 1, r1, r2); 4290 __ IncrementCounter(counters->named_store_full(), 1, r1, r2);
4307 break; 4291 break;
4308 case Code::KEYED_STORE_IC: 4292 case Code::KEYED_STORE_IC:
4309 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2); 4293 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
4310 default: 4294 default:
4311 break; 4295 break;
4312 } 4296 }
4313 if (mode == RelocInfo::CODE_TARGET_WITH_ID) { 4297 __ Call(ic, mode);
4314 ASSERT(ast_id != kNoASTId);
4315 __ CallWithAstId(ic, mode, ast_id);
4316 } else {
4317 ASSERT(ast_id == kNoASTId);
4318 __ Call(ic, mode);
4319 }
4320 } 4298 }
4321 4299
4322 4300
4323 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, 4301 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
4324 JumpPatchSite* patch_site,
4325 unsigned ast_id) {
4326 Counters* counters = isolate()->counters(); 4302 Counters* counters = isolate()->counters();
4327 switch (ic->kind()) { 4303 switch (ic->kind()) {
4328 case Code::LOAD_IC: 4304 case Code::LOAD_IC:
4329 __ IncrementCounter(counters->named_load_full(), 1, r1, r2); 4305 __ IncrementCounter(counters->named_load_full(), 1, r1, r2);
4330 break; 4306 break;
4331 case Code::KEYED_LOAD_IC: 4307 case Code::KEYED_LOAD_IC:
4332 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2); 4308 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
4333 break; 4309 break;
4334 case Code::STORE_IC: 4310 case Code::STORE_IC:
4335 __ IncrementCounter(counters->named_store_full(), 1, r1, r2); 4311 __ IncrementCounter(counters->named_store_full(), 1, r1, r2);
4336 break; 4312 break;
4337 case Code::KEYED_STORE_IC: 4313 case Code::KEYED_STORE_IC:
4338 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2); 4314 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
4339 default: 4315 default:
4340 break; 4316 break;
4341 } 4317 }
4342 4318 __ Call(ic, RelocInfo::CODE_TARGET);
4343 if (ast_id != kNoASTId) {
4344 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id);
4345 } else {
4346 __ Call(ic, RelocInfo::CODE_TARGET);
4347 }
4348 if (patch_site != NULL && patch_site->is_bound()) { 4319 if (patch_site != NULL && patch_site->is_bound()) {
4349 patch_site->EmitPatchInfo(); 4320 patch_site->EmitPatchInfo();
4350 } else { 4321 } else {
4351 __ nop(); // Signals no inlined code. 4322 __ nop(); // Signals no inlined code.
4352 } 4323 }
4353 } 4324 }
4354 4325
4355 4326
4356 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4327 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
4357 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 4328 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
4390 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 4361 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
4391 __ add(pc, r1, Operand(masm_->CodeObject())); 4362 __ add(pc, r1, Operand(masm_->CodeObject()));
4392 } 4363 }
4393 4364
4394 4365
4395 #undef __ 4366 #undef __
4396 4367
4397 } } // namespace v8::internal 4368 } } // namespace v8::internal
4398 4369
4399 #endif // V8_TARGET_ARCH_ARM 4370 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698