| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |