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

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

Issue 6793016: Record AST ids in relocation info at spots where we collect dynamic type feedback. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add ARM port 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
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 28 matching lines...) Expand all
39 #include "stub-cache.h" 39 #include "stub-cache.h"
40 40
41 #include "arm/code-stubs-arm.h" 41 #include "arm/code-stubs-arm.h"
42 42
43 namespace v8 { 43 namespace v8 {
44 namespace internal { 44 namespace internal {
45 45
46 #define __ ACCESS_MASM(masm_) 46 #define __ ACCESS_MASM(masm_)
47 47
48 48
49 static unsigned GetPropertyId(Property* property) {
50 if (property->is_synthetic()) return AstNode::kNoNumber;
51 return property->id();
52 }
53
54
49 // A patch site is a location in the code which it is possible to patch. This 55 // A patch site is a location in the code which it is possible to patch. This
50 // class has a number of methods to emit the code which is patchable and the 56 // class has a number of methods to emit the code which is patchable and the
51 // method EmitPatchInfo to record a marker back to the patchable code. This 57 // method EmitPatchInfo to record a marker back to the patchable code. This
52 // marker is a cmp rx, #yyy instruction, and x * 0x00000fff + yyy (raw 12 bit 58 // marker is a cmp rx, #yyy instruction, and x * 0x00000fff + yyy (raw 12 bit
53 // immediate value is used) is the delta from the pc to the first instruction of 59 // immediate value is used) is the delta from the pc to the first instruction of
54 // the patchable code. 60 // the patchable code.
55 class JumpPatchSite BASE_EMBEDDED { 61 class JumpPatchSite BASE_EMBEDDED {
56 public: 62 public:
57 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) { 63 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) {
58 #ifdef DEBUG 64 #ifdef DEBUG
(...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 __ cmp(r1, r0); 856 __ cmp(r1, r0);
851 __ b(ne, &next_test); 857 __ b(ne, &next_test);
852 __ Drop(1); // Switch value is no longer needed. 858 __ Drop(1); // Switch value is no longer needed.
853 __ b(clause->body_target()); 859 __ b(clause->body_target());
854 __ bind(&slow_case); 860 __ bind(&slow_case);
855 } 861 }
856 862
857 // Record position before stub call for type feedback. 863 // Record position before stub call for type feedback.
858 SetSourcePosition(clause->position()); 864 SetSourcePosition(clause->position());
859 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); 865 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
860 EmitCallIC(ic, &patch_site); 866 EmitCallIC(ic, &patch_site, clause->label()->id());
861 __ cmp(r0, Operand(0)); 867 __ cmp(r0, Operand(0));
862 __ b(ne, &next_test); 868 __ b(ne, &next_test);
863 __ Drop(1); // Switch value is no longer needed. 869 __ Drop(1); // Switch value is no longer needed.
864 __ b(clause->body_target()); 870 __ b(clause->body_target());
865 } 871 }
866 872
867 // Discard the test value and jump to the default if present, otherwise to 873 // Discard the test value and jump to the default if present, otherwise to
868 // the end of the statement. 874 // the end of the statement.
869 __ bind(&next_test); 875 __ bind(&next_test);
870 __ Drop(1); // Switch value is no longer needed. 876 __ Drop(1); // Switch value is no longer needed.
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 context()->Plug(r0); 1108 context()->Plug(r0);
1103 } 1109 }
1104 1110
1105 1111
1106 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 1112 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
1107 Comment cmnt(masm_, "[ VariableProxy"); 1113 Comment cmnt(masm_, "[ VariableProxy");
1108 EmitVariableLoad(expr->var()); 1114 EmitVariableLoad(expr->var());
1109 } 1115 }
1110 1116
1111 1117
1118 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
1119 Slot* slot,
1120 TypeofState typeof_state,
1121 Label* slow) {
1122 Register current = cp;
1123 Register next = r1;
1124 Register temp = r2;
1125
1126 Scope* s = scope();
1127 while (s != NULL) {
1128 if (s->num_heap_slots() > 0) {
1129 if (s->calls_eval()) {
1130 // Check that extension is NULL.
1131 __ ldr(temp, ContextOperand(current, Context::EXTENSION_INDEX));
1132 __ tst(temp, temp);
1133 __ b(ne, slow);
1134 }
1135 // Load next context in chain.
1136 __ ldr(next, ContextOperand(current, Context::CLOSURE_INDEX));
1137 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset));
1138 // Walk the rest of the chain without clobbering cp.
1139 current = next;
1140 }
1141 // If no outer scope calls eval, we do not need to check more
1142 // context extensions.
1143 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break;
1144 s = s->outer_scope();
1145 }
1146
1147 if (s->is_eval_scope()) {
1148 Label loop, fast;
1149 if (!current.is(next)) {
1150 __ Move(next, current);
1151 }
1152 __ bind(&loop);
1153 // Terminate at global context.
1154 __ ldr(temp, FieldMemOperand(next, HeapObject::kMapOffset));
1155 __ LoadRoot(ip, Heap::kGlobalContextMapRootIndex);
1156 __ cmp(temp, ip);
1157 __ b(eq, &fast);
1158 // Check that extension is NULL.
1159 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX));
1160 __ tst(temp, temp);
1161 __ b(ne, slow);
1162 // Load next context in chain.
1163 __ ldr(next, ContextOperand(next, Context::CLOSURE_INDEX));
1164 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset));
1165 __ b(&loop);
1166 __ bind(&fast);
1167 }
1168
1169 __ ldr(r0, GlobalObjectOperand());
1170 __ mov(r2, Operand(slot->var()->name()));
1171 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
1172 ? RelocInfo::CODE_TARGET
1173 : RelocInfo::CODE_TARGET_CONTEXT;
1174 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1175 EmitCallIC(ic, mode);
1176 }
1177
1178
1112 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( 1179 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(
1113 Slot* slot, 1180 Slot* slot,
1114 Label* slow) { 1181 Label* slow) {
1115 ASSERT(slot->type() == Slot::CONTEXT); 1182 ASSERT(slot->type() == Slot::CONTEXT);
1116 Register context = cp; 1183 Register context = cp;
1117 Register next = r3; 1184 Register next = r3;
1118 Register temp = r4; 1185 Register temp = r4;
1119 1186
1120 for (Scope* s = scope(); s != slot->var()->scope(); s = s->outer_scope()) { 1187 for (Scope* s = scope(); s != slot->var()->scope(); s = s->outer_scope()) {
1121 if (s->num_heap_slots() > 0) { 1188 if (s->num_heap_slots() > 0) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 key_literal->handle()->IsSmi()) { 1247 key_literal->handle()->IsSmi()) {
1181 // Load arguments object if there are no eval-introduced 1248 // Load arguments object if there are no eval-introduced
1182 // variables. Then load the argument from the arguments 1249 // variables. Then load the argument from the arguments
1183 // object using keyed load. 1250 // object using keyed load.
1184 __ ldr(r1, 1251 __ ldr(r1,
1185 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), 1252 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
1186 slow)); 1253 slow));
1187 __ mov(r0, Operand(key_literal->handle())); 1254 __ mov(r0, Operand(key_literal->handle()));
1188 Handle<Code> ic = 1255 Handle<Code> ic =
1189 isolate()->builtins()->KeyedLoadIC_Initialize(); 1256 isolate()->builtins()->KeyedLoadIC_Initialize();
1190 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1257 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID,
1258 GetPropertyId(property));
1191 __ jmp(done); 1259 __ jmp(done);
1192 } 1260 }
1193 } 1261 }
1194 } 1262 }
1195 } 1263 }
1196 } 1264 }
1197 1265
1198 1266
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) { 1267 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1261 // Four cases: non-this global variables, lookup slots, all other 1268 // Four cases: non-this global variables, lookup slots, all other
1262 // types of slots, and parameters that rewrite to explicit property 1269 // types of slots, and parameters that rewrite to explicit property
1263 // accesses on the arguments object. 1270 // accesses on the arguments object.
1264 Slot* slot = var->AsSlot(); 1271 Slot* slot = var->AsSlot();
1265 Property* property = var->AsProperty(); 1272 Property* property = var->AsProperty();
1266 1273
1267 if (var->is_global() && !var->is_this()) { 1274 if (var->is_global() && !var->is_this()) {
1268 Comment cmnt(masm_, "Global variable"); 1275 Comment cmnt(masm_, "Global variable");
1269 // Use inline caching. Variable name is passed in r2 and the global 1276 // Use inline caching. Variable name is passed in r2 and the global
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 // Assert that the key is a smi. 1330 // Assert that the key is a smi.
1324 Literal* key_literal = property->key()->AsLiteral(); 1331 Literal* key_literal = property->key()->AsLiteral();
1325 ASSERT_NOT_NULL(key_literal); 1332 ASSERT_NOT_NULL(key_literal);
1326 ASSERT(key_literal->handle()->IsSmi()); 1333 ASSERT(key_literal->handle()->IsSmi());
1327 1334
1328 // Load the key. 1335 // Load the key.
1329 __ mov(r0, Operand(key_literal->handle())); 1336 __ mov(r0, Operand(key_literal->handle()));
1330 1337
1331 // Call keyed load IC. It has arguments key and receiver in r0 and r1. 1338 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
1332 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1339 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1333 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1340 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, GetPropertyId(property));
1334 context()->Plug(r0); 1341 context()->Plug(r0);
1335 } 1342 }
1336 } 1343 }
1337 1344
1338 1345
1339 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1346 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1340 Comment cmnt(masm_, "[ RegExpLiteral"); 1347 Comment cmnt(masm_, "[ RegExpLiteral");
1341 Label materialized; 1348 Label materialized;
1342 // Registers will be used as follows: 1349 // Registers will be used as follows:
1343 // r5 = materialized value (RegExp literal) 1350 // r5 = materialized value (RegExp literal)
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 UNREACHABLE(); 1438 UNREACHABLE();
1432 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1439 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1433 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); 1440 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value()));
1434 // Fall through. 1441 // Fall through.
1435 case ObjectLiteral::Property::COMPUTED: 1442 case ObjectLiteral::Property::COMPUTED:
1436 if (key->handle()->IsSymbol()) { 1443 if (key->handle()->IsSymbol()) {
1437 if (property->emit_store()) { 1444 if (property->emit_store()) {
1438 VisitForAccumulatorValue(value); 1445 VisitForAccumulatorValue(value);
1439 __ mov(r2, Operand(key->handle())); 1446 __ mov(r2, Operand(key->handle()));
1440 __ ldr(r1, MemOperand(sp)); 1447 __ ldr(r1, MemOperand(sp));
1441 Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize(); 1448 Handle<Code> ic = is_strict_mode()
1442 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1449 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1450 : isolate()->builtins()->StoreIC_Initialize();
1451 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, key->id());
1443 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1452 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1444 } else { 1453 } else {
1445 VisitForEffect(value); 1454 VisitForEffect(value);
1446 } 1455 }
1447 break; 1456 break;
1448 } 1457 }
1449 // Fall through. 1458 // Fall through.
1450 case ObjectLiteral::Property::PROTOTYPE: 1459 case ObjectLiteral::Property::PROTOTYPE:
1451 // Duplicate receiver on stack. 1460 // Duplicate receiver on stack.
1452 __ ldr(r0, MemOperand(sp)); 1461 __ ldr(r0, MemOperand(sp));
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1644 Token::Value op = expr->binary_op(); 1653 Token::Value op = expr->binary_op();
1645 __ push(r0); // Left operand goes on the stack. 1654 __ push(r0); // Left operand goes on the stack.
1646 VisitForAccumulatorValue(expr->value()); 1655 VisitForAccumulatorValue(expr->value());
1647 1656
1648 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1657 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1649 ? OVERWRITE_RIGHT 1658 ? OVERWRITE_RIGHT
1650 : NO_OVERWRITE; 1659 : NO_OVERWRITE;
1651 SetSourcePosition(expr->position() + 1); 1660 SetSourcePosition(expr->position() + 1);
1652 AccumulatorValueContext context(this); 1661 AccumulatorValueContext context(this);
1653 if (ShouldInlineSmiCase(op)) { 1662 if (ShouldInlineSmiCase(op)) {
1654 EmitInlineSmiBinaryOp(expr, 1663 EmitInlineSmiBinaryOp(expr->binary_operation(),
1655 op, 1664 op,
1656 mode, 1665 mode,
1657 expr->target(), 1666 expr->target(),
1658 expr->value()); 1667 expr->value());
1659 } else { 1668 } else {
1660 EmitBinaryOp(op, mode); 1669 EmitBinaryOp(expr->binary_operation(), op, mode);
1661 } 1670 }
1662 1671
1663 // Deoptimization point in case the binary operation may have side effects. 1672 // Deoptimization point in case the binary operation may have side effects.
1664 PrepareForBailout(expr->binary_operation(), TOS_REG); 1673 PrepareForBailout(expr->binary_operation(), TOS_REG);
1665 } else { 1674 } else {
1666 VisitForAccumulatorValue(expr->value()); 1675 VisitForAccumulatorValue(expr->value());
1667 } 1676 }
1668 1677
1669 // Record source position before possible IC call. 1678 // Record source position before possible IC call.
1670 SetSourcePosition(expr->position()); 1679 SetSourcePosition(expr->position());
(...skipping 15 matching lines...) Expand all
1686 } 1695 }
1687 } 1696 }
1688 1697
1689 1698
1690 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1699 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1691 SetSourcePosition(prop->position()); 1700 SetSourcePosition(prop->position());
1692 Literal* key = prop->key()->AsLiteral(); 1701 Literal* key = prop->key()->AsLiteral();
1693 __ mov(r2, Operand(key->handle())); 1702 __ mov(r2, Operand(key->handle()));
1694 // Call load IC. It has arguments receiver and property name r0 and r2. 1703 // Call load IC. It has arguments receiver and property name r0 and r2.
1695 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1704 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1696 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1705 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, GetPropertyId(prop));
1697 } 1706 }
1698 1707
1699 1708
1700 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1709 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1701 SetSourcePosition(prop->position()); 1710 SetSourcePosition(prop->position());
1702 // Call keyed load IC. It has arguments key and receiver in r0 and r1. 1711 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
1703 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1712 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1704 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1713 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, GetPropertyId(prop));
1705 } 1714 }
1706 1715
1707 1716
1708 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, 1717 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
1709 Token::Value op, 1718 Token::Value op,
1710 OverwriteMode mode, 1719 OverwriteMode mode,
1711 Expression* left_expr, 1720 Expression* left_expr,
1712 Expression* right_expr) { 1721 Expression* right_expr) {
1713 Label done, smi_case, stub_call; 1722 Label done, smi_case, stub_call;
1714 1723
1715 Register scratch1 = r2; 1724 Register scratch1 = r2;
1716 Register scratch2 = r3; 1725 Register scratch2 = r3;
1717 1726
1718 // Get the arguments. 1727 // Get the arguments.
1719 Register left = r1; 1728 Register left = r1;
1720 Register right = r0; 1729 Register right = r0;
1721 __ pop(left); 1730 __ pop(left);
1722 1731
1723 // Perform combined smi check on both operands. 1732 // Perform combined smi check on both operands.
1724 __ orr(scratch1, left, Operand(right)); 1733 __ orr(scratch1, left, Operand(right));
1725 STATIC_ASSERT(kSmiTag == 0); 1734 STATIC_ASSERT(kSmiTag == 0);
1726 JumpPatchSite patch_site(masm_); 1735 JumpPatchSite patch_site(masm_);
1727 patch_site.EmitJumpIfSmi(scratch1, &smi_case); 1736 patch_site.EmitJumpIfSmi(scratch1, &smi_case);
1728 1737
1729 __ bind(&stub_call); 1738 __ bind(&stub_call);
1730 TypeRecordingBinaryOpStub stub(op, mode); 1739 TypeRecordingBinaryOpStub stub(op, mode);
1731 EmitCallIC(stub.GetCode(), &patch_site); 1740 EmitCallIC(stub.GetCode(), &patch_site, expr->id());
1732 __ jmp(&done); 1741 __ jmp(&done);
1733 1742
1734 __ bind(&smi_case); 1743 __ bind(&smi_case);
1735 // Smi case. This code works the same way as the smi-smi case in the type 1744 // Smi case. This code works the same way as the smi-smi case in the type
1736 // recording binary operation stub, see 1745 // recording binary operation stub, see
1737 // TypeRecordingBinaryOpStub::GenerateSmiSmiOperation for comments. 1746 // TypeRecordingBinaryOpStub::GenerateSmiSmiOperation for comments.
1738 switch (op) { 1747 switch (op) {
1739 case Token::SAR: 1748 case Token::SAR:
1740 __ b(&stub_call); 1749 __ b(&stub_call);
1741 __ GetLeastBitsFromSmi(scratch1, right, 5); 1750 __ GetLeastBitsFromSmi(scratch1, right, 5);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1797 break; 1806 break;
1798 default: 1807 default:
1799 UNREACHABLE(); 1808 UNREACHABLE();
1800 } 1809 }
1801 1810
1802 __ bind(&done); 1811 __ bind(&done);
1803 context()->Plug(r0); 1812 context()->Plug(r0);
1804 } 1813 }
1805 1814
1806 1815
1807 void FullCodeGenerator::EmitBinaryOp(Token::Value op, 1816 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
1817 Token::Value op,
1808 OverwriteMode mode) { 1818 OverwriteMode mode) {
1809 __ pop(r1); 1819 __ pop(r1);
1810 TypeRecordingBinaryOpStub stub(op, mode); 1820 TypeRecordingBinaryOpStub stub(op, mode);
1811 EmitCallIC(stub.GetCode(), NULL); 1821 EmitCallIC(stub.GetCode(), NULL, expr->id());
1812 context()->Plug(r0); 1822 context()->Plug(r0);
1813 } 1823 }
1814 1824
1815 1825
1816 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1826 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1817 // Invalid left-hand sides are rewritten to have a 'throw 1827 // Invalid left-hand sides are rewritten to have a 'throw
1818 // ReferenceError' on the left-hand side. 1828 // ReferenceError' on the left-hand side.
1819 if (!expr->IsValidLeftHandSide()) { 1829 if (!expr->IsValidLeftHandSide()) {
1820 VisitForEffect(expr); 1830 VisitForEffect(expr);
1821 return; 1831 return;
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1999 // receiver into fast case. 2009 // receiver into fast case.
2000 if (expr->ends_initialization_block()) { 2010 if (expr->ends_initialization_block()) {
2001 __ ldr(r1, MemOperand(sp)); 2011 __ ldr(r1, MemOperand(sp));
2002 } else { 2012 } else {
2003 __ pop(r1); 2013 __ pop(r1);
2004 } 2014 }
2005 2015
2006 Handle<Code> ic = is_strict_mode() 2016 Handle<Code> ic = is_strict_mode()
2007 ? isolate()->builtins()->StoreIC_Initialize_Strict() 2017 ? isolate()->builtins()->StoreIC_Initialize_Strict()
2008 : isolate()->builtins()->StoreIC_Initialize(); 2018 : isolate()->builtins()->StoreIC_Initialize();
2009 EmitCallIC(ic, RelocInfo::CODE_TARGET); 2019 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id());
2010 2020
2011 // If the assignment ends an initialization block, revert to fast case. 2021 // If the assignment ends an initialization block, revert to fast case.
2012 if (expr->ends_initialization_block()) { 2022 if (expr->ends_initialization_block()) {
2013 __ push(r0); // Result of assignment, saved even if not needed. 2023 __ push(r0); // Result of assignment, saved even if not needed.
2014 // Receiver is under the result value. 2024 // Receiver is under the result value.
2015 __ ldr(ip, MemOperand(sp, kPointerSize)); 2025 __ ldr(ip, MemOperand(sp, kPointerSize));
2016 __ push(ip); 2026 __ push(ip);
2017 __ CallRuntime(Runtime::kToFastProperties, 1); 2027 __ CallRuntime(Runtime::kToFastProperties, 1);
2018 __ pop(r0); 2028 __ pop(r0);
2019 __ Drop(1); 2029 __ Drop(1);
(...skipping 25 matching lines...) Expand all
2045 // receiver into fast case. 2055 // receiver into fast case.
2046 if (expr->ends_initialization_block()) { 2056 if (expr->ends_initialization_block()) {
2047 __ ldr(r2, MemOperand(sp)); 2057 __ ldr(r2, MemOperand(sp));
2048 } else { 2058 } else {
2049 __ pop(r2); 2059 __ pop(r2);
2050 } 2060 }
2051 2061
2052 Handle<Code> ic = is_strict_mode() 2062 Handle<Code> ic = is_strict_mode()
2053 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 2063 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
2054 : isolate()->builtins()->KeyedStoreIC_Initialize(); 2064 : isolate()->builtins()->KeyedStoreIC_Initialize();
2055 EmitCallIC(ic, RelocInfo::CODE_TARGET); 2065 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id());
2056 2066
2057 // If the assignment ends an initialization block, revert to fast case. 2067 // If the assignment ends an initialization block, revert to fast case.
2058 if (expr->ends_initialization_block()) { 2068 if (expr->ends_initialization_block()) {
2059 __ push(r0); // Result of assignment, saved even if not needed. 2069 __ push(r0); // Result of assignment, saved even if not needed.
2060 // Receiver is under the result value. 2070 // Receiver is under the result value.
2061 __ ldr(ip, MemOperand(sp, kPointerSize)); 2071 __ ldr(ip, MemOperand(sp, kPointerSize));
2062 __ push(ip); 2072 __ push(ip);
2063 __ CallRuntime(Runtime::kToFastProperties, 1); 2073 __ CallRuntime(Runtime::kToFastProperties, 1);
2064 __ pop(r0); 2074 __ pop(r0);
2065 __ Drop(1); 2075 __ Drop(1);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2097 VisitForStackValue(args->at(i)); 2107 VisitForStackValue(args->at(i));
2098 } 2108 }
2099 __ mov(r2, Operand(name)); 2109 __ mov(r2, Operand(name));
2100 } 2110 }
2101 // Record source position for debugger. 2111 // Record source position for debugger.
2102 SetSourcePosition(expr->position()); 2112 SetSourcePosition(expr->position());
2103 // Call the IC initialization code. 2113 // Call the IC initialization code.
2104 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2114 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2105 Handle<Code> ic = 2115 Handle<Code> ic =
2106 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop); 2116 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop);
2107 EmitCallIC(ic, mode); 2117 EmitCallIC(ic, mode, expr->id());
2108 RecordJSReturnSite(expr); 2118 RecordJSReturnSite(expr);
2109 // Restore context register. 2119 // Restore context register.
2110 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2120 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2111 context()->Plug(r0); 2121 context()->Plug(r0);
2112 } 2122 }
2113 2123
2114 2124
2115 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2125 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2116 Expression* key, 2126 Expression* key,
2117 RelocInfo::Mode mode) { 2127 RelocInfo::Mode mode) {
(...skipping 14 matching lines...) Expand all
2132 VisitForStackValue(args->at(i)); 2142 VisitForStackValue(args->at(i));
2133 } 2143 }
2134 } 2144 }
2135 // Record source position for debugger. 2145 // Record source position for debugger.
2136 SetSourcePosition(expr->position()); 2146 SetSourcePosition(expr->position());
2137 // Call the IC initialization code. 2147 // Call the IC initialization code.
2138 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2148 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2139 Handle<Code> ic = 2149 Handle<Code> ic =
2140 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); 2150 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop);
2141 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. 2151 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key.
2142 EmitCallIC(ic, mode); 2152 EmitCallIC(ic, mode, expr->id());
2143 RecordJSReturnSite(expr); 2153 RecordJSReturnSite(expr);
2144 // Restore context register. 2154 // Restore context register.
2145 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2155 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2146 context()->DropAndPlug(1, r0); // Drop the key still on the stack. 2156 context()->DropAndPlug(1, r0); // Drop the key still on the stack.
2147 } 2157 }
2148 2158
2149 2159
2150 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2160 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
2151 // Code common for calls using the call stub. 2161 // Code common for calls using the call stub.
2152 ZoneList<Expression*>* args = expr->arguments(); 2162 ZoneList<Expression*>* args = expr->arguments();
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 EmitCallWithStub(expr); 2318 EmitCallWithStub(expr);
2309 } else if (fun->AsProperty() != NULL) { 2319 } else if (fun->AsProperty() != NULL) {
2310 // Call to an object property. 2320 // Call to an object property.
2311 Property* prop = fun->AsProperty(); 2321 Property* prop = fun->AsProperty();
2312 Literal* key = prop->key()->AsLiteral(); 2322 Literal* key = prop->key()->AsLiteral();
2313 if (key != NULL && key->handle()->IsSymbol()) { 2323 if (key != NULL && key->handle()->IsSymbol()) {
2314 // Call to a named property, use call IC. 2324 // Call to a named property, use call IC.
2315 { PreservePositionScope scope(masm()->positions_recorder()); 2325 { PreservePositionScope scope(masm()->positions_recorder());
2316 VisitForStackValue(prop->obj()); 2326 VisitForStackValue(prop->obj());
2317 } 2327 }
2318 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 2328 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET_WITH_ID);
2319 } else { 2329 } else {
2320 // Call to a keyed property. 2330 // Call to a keyed property.
2321 // For a synthetic property use keyed load IC followed by function call, 2331 // For a synthetic property use keyed load IC followed by function call,
2322 // for a regular property use keyed CallIC. 2332 // for a regular property use keyed EmitCallIC.
2323 if (prop->is_synthetic()) { 2333 if (prop->is_synthetic()) {
2324 // Do not visit the object and key subexpressions (they are shared 2334 // Do not visit the object and key subexpressions (they are shared
2325 // by all occurrences of the same rewritten parameter). 2335 // by all occurrences of the same rewritten parameter).
2326 ASSERT(prop->obj()->AsVariableProxy() != NULL); 2336 ASSERT(prop->obj()->AsVariableProxy() != NULL);
2327 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); 2337 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL);
2328 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); 2338 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot();
2329 MemOperand operand = EmitSlotSearch(slot, r1); 2339 MemOperand operand = EmitSlotSearch(slot, r1);
2330 __ ldr(r1, operand); 2340 __ ldr(r1, operand);
2331 2341
2332 ASSERT(prop->key()->AsLiteral() != NULL); 2342 ASSERT(prop->key()->AsLiteral() != NULL);
2333 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); 2343 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2334 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); 2344 __ mov(r0, Operand(prop->key()->AsLiteral()->handle()));
2335 2345
2336 // Record source code position for IC call. 2346 // Record source code position for IC call.
2337 SetSourcePosition(prop->position()); 2347 SetSourcePosition(prop->position());
2338 2348
2339 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2349 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2340 EmitCallIC(ic, RelocInfo::CODE_TARGET); 2350 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, GetPropertyId(prop));
2341 __ ldr(r1, GlobalObjectOperand()); 2351 __ ldr(r1, GlobalObjectOperand());
2342 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); 2352 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
2343 __ Push(r0, r1); // Function, receiver. 2353 __ Push(r0, r1); // Function, receiver.
2344 EmitCallWithStub(expr); 2354 EmitCallWithStub(expr);
2345 } else { 2355 } else {
2346 { PreservePositionScope scope(masm()->positions_recorder()); 2356 { PreservePositionScope scope(masm()->positions_recorder());
2347 VisitForStackValue(prop->obj()); 2357 VisitForStackValue(prop->obj());
2348 } 2358 }
2349 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 2359 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET_WITH_ID);
2350 } 2360 }
2351 } 2361 }
2352 } else { 2362 } else {
2353 { PreservePositionScope scope(masm()->positions_recorder()); 2363 { PreservePositionScope scope(masm()->positions_recorder());
2354 VisitForStackValue(fun); 2364 VisitForStackValue(fun);
2355 } 2365 }
2356 // Load global receiver object. 2366 // Load global receiver object.
2357 __ ldr(r1, GlobalObjectOperand()); 2367 __ ldr(r1, GlobalObjectOperand());
2358 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); 2368 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
2359 __ push(r1); 2369 __ push(r1);
(...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after
3651 int arg_count = args->length(); 3661 int arg_count = args->length();
3652 for (int i = 0; i < arg_count; i++) { 3662 for (int i = 0; i < arg_count; i++) {
3653 VisitForStackValue(args->at(i)); 3663 VisitForStackValue(args->at(i));
3654 } 3664 }
3655 3665
3656 if (expr->is_jsruntime()) { 3666 if (expr->is_jsruntime()) {
3657 // Call the JS runtime function. 3667 // Call the JS runtime function.
3658 __ mov(r2, Operand(expr->name())); 3668 __ mov(r2, Operand(expr->name()));
3659 Handle<Code> ic = 3669 Handle<Code> ic =
3660 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); 3670 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP);
3661 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3671 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id());
3662 // Restore context register. 3672 // Restore context register.
3663 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3673 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3664 } else { 3674 } else {
3665 // Call the C runtime function. 3675 // Call the C runtime function.
3666 __ CallRuntime(expr->function(), arg_count); 3676 __ CallRuntime(expr->function(), arg_count);
3667 } 3677 }
3668 context()->Plug(r0); 3678 context()->Plug(r0);
3669 } 3679 }
3670 3680
3671 3681
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
3930 __ bind(&stub_call); 3940 __ bind(&stub_call);
3931 // Call stub. Undo operation first. 3941 // Call stub. Undo operation first.
3932 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); 3942 __ sub(r0, r0, Operand(Smi::FromInt(count_value)));
3933 } 3943 }
3934 __ mov(r1, Operand(Smi::FromInt(count_value))); 3944 __ mov(r1, Operand(Smi::FromInt(count_value)));
3935 3945
3936 // Record position before stub call. 3946 // Record position before stub call.
3937 SetSourcePosition(expr->position()); 3947 SetSourcePosition(expr->position());
3938 3948
3939 TypeRecordingBinaryOpStub stub(Token::ADD, NO_OVERWRITE); 3949 TypeRecordingBinaryOpStub stub(Token::ADD, NO_OVERWRITE);
3940 EmitCallIC(stub.GetCode(), &patch_site); 3950 EmitCallIC(stub.GetCode(), &patch_site, expr->CountId());
3941 __ bind(&done); 3951 __ bind(&done);
3942 3952
3943 // Store the value returned in r0. 3953 // Store the value returned in r0.
3944 switch (assign_type) { 3954 switch (assign_type) {
3945 case VARIABLE: 3955 case VARIABLE:
3946 if (expr->is_postfix()) { 3956 if (expr->is_postfix()) {
3947 { EffectContext context(this); 3957 { EffectContext context(this);
3948 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3958 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3949 Token::ASSIGN); 3959 Token::ASSIGN);
3950 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3960 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
(...skipping 10 matching lines...) Expand all
3961 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3971 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3962 context()->Plug(r0); 3972 context()->Plug(r0);
3963 } 3973 }
3964 break; 3974 break;
3965 case NAMED_PROPERTY: { 3975 case NAMED_PROPERTY: {
3966 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); 3976 __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
3967 __ pop(r1); 3977 __ pop(r1);
3968 Handle<Code> ic = is_strict_mode() 3978 Handle<Code> ic = is_strict_mode()
3969 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3979 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3970 : isolate()->builtins()->StoreIC_Initialize(); 3980 : isolate()->builtins()->StoreIC_Initialize();
3971 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3981 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id());
3972 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3982 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3973 if (expr->is_postfix()) { 3983 if (expr->is_postfix()) {
3974 if (!context()->IsEffect()) { 3984 if (!context()->IsEffect()) {
3975 context()->PlugTOS(); 3985 context()->PlugTOS();
3976 } 3986 }
3977 } else { 3987 } else {
3978 context()->Plug(r0); 3988 context()->Plug(r0);
3979 } 3989 }
3980 break; 3990 break;
3981 } 3991 }
3982 case KEYED_PROPERTY: { 3992 case KEYED_PROPERTY: {
3983 __ pop(r1); // Key. 3993 __ pop(r1); // Key.
3984 __ pop(r2); // Receiver. 3994 __ pop(r2); // Receiver.
3985 Handle<Code> ic = is_strict_mode() 3995 Handle<Code> ic = is_strict_mode()
3986 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3996 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3987 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3997 : isolate()->builtins()->KeyedStoreIC_Initialize();
3988 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3998 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id());
3989 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3999 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3990 if (expr->is_postfix()) { 4000 if (expr->is_postfix()) {
3991 if (!context()->IsEffect()) { 4001 if (!context()->IsEffect()) {
3992 context()->PlugTOS(); 4002 context()->PlugTOS();
3993 } 4003 }
3994 } else { 4004 } else {
3995 context()->Plug(r0); 4005 context()->Plug(r0);
3996 } 4006 }
3997 break; 4007 break;
3998 } 4008 }
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
4207 __ orr(r2, r0, Operand(r1)); 4217 __ orr(r2, r0, Operand(r1));
4208 patch_site.EmitJumpIfNotSmi(r2, &slow_case); 4218 patch_site.EmitJumpIfNotSmi(r2, &slow_case);
4209 __ cmp(r1, r0); 4219 __ cmp(r1, r0);
4210 Split(cond, if_true, if_false, NULL); 4220 Split(cond, if_true, if_false, NULL);
4211 __ bind(&slow_case); 4221 __ bind(&slow_case);
4212 } 4222 }
4213 4223
4214 // Record position and call the compare IC. 4224 // Record position and call the compare IC.
4215 SetSourcePosition(expr->position()); 4225 SetSourcePosition(expr->position());
4216 Handle<Code> ic = CompareIC::GetUninitialized(op); 4226 Handle<Code> ic = CompareIC::GetUninitialized(op);
4217 EmitCallIC(ic, &patch_site); 4227 EmitCallIC(ic, &patch_site, expr->id());
4218 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4228 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4219 __ cmp(r0, Operand(0)); 4229 __ cmp(r0, Operand(0));
4220 Split(cond, if_true, if_false, fall_through); 4230 Split(cond, if_true, if_false, fall_through);
4221 } 4231 }
4222 } 4232 }
4223 4233
4224 // Convert the result of the comparison into one expected for this 4234 // Convert the result of the comparison into one expected for this
4225 // expression's context. 4235 // expression's context.
4226 context()->Plug(if_true, if_false); 4236 context()->Plug(if_true, if_false);
4227 } 4237 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4269 Register FullCodeGenerator::result_register() { 4279 Register FullCodeGenerator::result_register() {
4270 return r0; 4280 return r0;
4271 } 4281 }
4272 4282
4273 4283
4274 Register FullCodeGenerator::context_register() { 4284 Register FullCodeGenerator::context_register() {
4275 return cp; 4285 return cp;
4276 } 4286 }
4277 4287
4278 4288
4279 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { 4289 void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
4290 RelocInfo::Mode mode,
4291 unsigned ast_id) {
4280 ASSERT(mode == RelocInfo::CODE_TARGET || 4292 ASSERT(mode == RelocInfo::CODE_TARGET ||
4281 mode == RelocInfo::CODE_TARGET_CONTEXT); 4293 mode == RelocInfo::CODE_TARGET_CONTEXT ||
4294 mode == RelocInfo::CODE_TARGET_WITH_ID);
4282 Counters* counters = isolate()->counters(); 4295 Counters* counters = isolate()->counters();
4283 switch (ic->kind()) { 4296 switch (ic->kind()) {
4284 case Code::LOAD_IC: 4297 case Code::LOAD_IC:
4285 __ IncrementCounter(counters->named_load_full(), 1, r1, r2); 4298 __ IncrementCounter(counters->named_load_full(), 1, r1, r2);
4286 break; 4299 break;
4287 case Code::KEYED_LOAD_IC: 4300 case Code::KEYED_LOAD_IC:
4288 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2); 4301 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
4289 break; 4302 break;
4290 case Code::STORE_IC: 4303 case Code::STORE_IC:
4291 __ IncrementCounter(counters->named_store_full(), 1, r1, r2); 4304 __ IncrementCounter(counters->named_store_full(), 1, r1, r2);
4292 break; 4305 break;
4293 case Code::KEYED_STORE_IC: 4306 case Code::KEYED_STORE_IC:
4294 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2); 4307 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
4295 default: 4308 default:
4296 break; 4309 break;
4297 } 4310 }
4298 4311 if (mode == RelocInfo::CODE_TARGET_WITH_ID) {
4299 __ Call(ic, mode); 4312 ASSERT(ast_id != kNoASTId);
4313 __ CallWithAstId(ic, mode, ast_id);
4314 } else {
4315 ASSERT(ast_id == kNoASTId);
4316 __ Call(ic, mode);
4317 }
4300 } 4318 }
4301 4319
4302 4320
4303 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { 4321 void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
4322 JumpPatchSite* patch_site,
4323 unsigned ast_id) {
4304 Counters* counters = isolate()->counters(); 4324 Counters* counters = isolate()->counters();
4305 switch (ic->kind()) { 4325 switch (ic->kind()) {
4306 case Code::LOAD_IC: 4326 case Code::LOAD_IC:
4307 __ IncrementCounter(counters->named_load_full(), 1, r1, r2); 4327 __ IncrementCounter(counters->named_load_full(), 1, r1, r2);
4308 break; 4328 break;
4309 case Code::KEYED_LOAD_IC: 4329 case Code::KEYED_LOAD_IC:
4310 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2); 4330 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
4311 break; 4331 break;
4312 case Code::STORE_IC: 4332 case Code::STORE_IC:
4313 __ IncrementCounter(counters->named_store_full(), 1, r1, r2); 4333 __ IncrementCounter(counters->named_store_full(), 1, r1, r2);
4314 break; 4334 break;
4315 case Code::KEYED_STORE_IC: 4335 case Code::KEYED_STORE_IC:
4316 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2); 4336 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
4317 default: 4337 default:
4318 break; 4338 break;
4319 } 4339 }
4320 4340
4321 __ Call(ic, RelocInfo::CODE_TARGET); 4341 if (ast_id != kNoASTId) {
4342 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id);
4343 } else {
4344 __ Call(ic, RelocInfo::CODE_TARGET);
4345 }
4322 if (patch_site != NULL && patch_site->is_bound()) { 4346 if (patch_site != NULL && patch_site->is_bound()) {
4323 patch_site->EmitPatchInfo(); 4347 patch_site->EmitPatchInfo();
4324 } else { 4348 } else {
4325 __ nop(); // Signals no inlined code. 4349 __ nop(); // Signals no inlined code.
4326 } 4350 }
4327 } 4351 }
4328 4352
4329 4353
4330 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4354 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
4331 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 4355 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
4364 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 4388 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
4365 __ add(pc, r1, Operand(masm_->CodeObject())); 4389 __ add(pc, r1, Operand(masm_->CodeObject()));
4366 } 4390 }
4367 4391
4368 4392
4369 #undef __ 4393 #undef __
4370 4394
4371 } } // namespace v8::internal 4395 } } // namespace v8::internal
4372 4396
4373 #endif // V8_TARGET_ARCH_ARM 4397 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698