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 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 if (true_label_ != fall_through_) __ b(true_label_); | 555 if (true_label_ != fall_through_) __ b(true_label_); |
556 } else { | 556 } else { |
557 if (false_label_ != fall_through_) __ b(false_label_); | 557 if (false_label_ != fall_through_) __ b(false_label_); |
558 } | 558 } |
559 } | 559 } |
560 | 560 |
561 | 561 |
562 void FullCodeGenerator::DoTest(Label* if_true, | 562 void FullCodeGenerator::DoTest(Label* if_true, |
563 Label* if_false, | 563 Label* if_false, |
564 Label* fall_through) { | 564 Label* fall_through) { |
565 if (CpuFeatures::IsSupported(VFP3)) { | 565 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { |
566 CpuFeatures::Scope scope(VFP3); | 566 CpuFeatures::Scope scope(VFP3); |
567 // Emit the inlined tests assumed by the stub. | 567 // Emit the inlined tests assumed by the stub. |
568 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 568 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
569 __ cmp(result_register(), ip); | 569 __ cmp(result_register(), ip); |
570 __ b(eq, if_false); | 570 __ b(eq, if_false); |
571 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 571 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
572 __ cmp(result_register(), ip); | 572 __ cmp(result_register(), ip); |
573 __ b(eq, if_true); | 573 __ b(eq, if_true); |
574 __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 574 __ LoadRoot(ip, Heap::kFalseValueRootIndex); |
575 __ cmp(result_register(), ip); | 575 __ cmp(result_register(), ip); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 VisitForAccumulatorValue(function); | 774 VisitForAccumulatorValue(function); |
775 __ pop(r2); | 775 __ pop(r2); |
776 } else { | 776 } else { |
777 __ mov(r2, r0); | 777 __ mov(r2, r0); |
778 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); | 778 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); |
779 } | 779 } |
780 ASSERT(prop->key()->AsLiteral() != NULL && | 780 ASSERT(prop->key()->AsLiteral() != NULL && |
781 prop->key()->AsLiteral()->handle()->IsSmi()); | 781 prop->key()->AsLiteral()->handle()->IsSmi()); |
782 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); | 782 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); |
783 | 783 |
784 Handle<Code> ic(Builtins::builtin( | 784 Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode() |
785 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 785 ? Builtins::KeyedStoreIC_Initialize_Strict |
786 : Builtins::KeyedStoreIC_Initialize)); | 786 : Builtins::KeyedStoreIC_Initialize)); |
787 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 787 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
788 // Value in r0 is ignored (declarations are statements). | 788 // Value in r0 is ignored (declarations are statements). |
789 } | 789 } |
790 } | 790 } |
791 } | 791 } |
792 | 792 |
793 | 793 |
794 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 794 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
795 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 795 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
796 } | 796 } |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 key_literal != NULL && | 1179 key_literal != NULL && |
1180 obj_proxy->IsArguments() && | 1180 obj_proxy->IsArguments() && |
1181 key_literal->handle()->IsSmi()) { | 1181 key_literal->handle()->IsSmi()) { |
1182 // Load arguments object if there are no eval-introduced | 1182 // Load arguments object if there are no eval-introduced |
1183 // variables. Then load the argument from the arguments | 1183 // variables. Then load the argument from the arguments |
1184 // object using keyed load. | 1184 // object using keyed load. |
1185 __ ldr(r1, | 1185 __ ldr(r1, |
1186 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1186 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
1187 slow)); | 1187 slow)); |
1188 __ mov(r0, Operand(key_literal->handle())); | 1188 __ mov(r0, Operand(key_literal->handle())); |
1189 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1189 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1190 Builtins::KeyedLoadIC_Initialize)); |
1190 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1191 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1191 __ jmp(done); | 1192 __ jmp(done); |
1192 } | 1193 } |
1193 } | 1194 } |
1194 } | 1195 } |
1195 } | 1196 } |
1196 } | 1197 } |
1197 | 1198 |
1198 | 1199 |
1199 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( | 1200 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1245 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset)); | 1246 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset)); |
1246 __ b(&loop); | 1247 __ b(&loop); |
1247 __ bind(&fast); | 1248 __ bind(&fast); |
1248 } | 1249 } |
1249 | 1250 |
1250 __ ldr(r0, GlobalObjectOperand()); | 1251 __ ldr(r0, GlobalObjectOperand()); |
1251 __ mov(r2, Operand(slot->var()->name())); | 1252 __ mov(r2, Operand(slot->var()->name())); |
1252 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1253 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
1253 ? RelocInfo::CODE_TARGET | 1254 ? RelocInfo::CODE_TARGET |
1254 : RelocInfo::CODE_TARGET_CONTEXT; | 1255 : RelocInfo::CODE_TARGET_CONTEXT; |
1255 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1256 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1257 Builtins::LoadIC_Initialize)); |
1256 EmitCallIC(ic, mode); | 1258 EmitCallIC(ic, mode); |
1257 } | 1259 } |
1258 | 1260 |
1259 | 1261 |
1260 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1262 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
1261 // Four cases: non-this global variables, lookup slots, all other | 1263 // Four cases: non-this global variables, lookup slots, all other |
1262 // types of slots, and parameters that rewrite to explicit property | 1264 // types of slots, and parameters that rewrite to explicit property |
1263 // accesses on the arguments object. | 1265 // accesses on the arguments object. |
1264 Slot* slot = var->AsSlot(); | 1266 Slot* slot = var->AsSlot(); |
1265 Property* property = var->AsProperty(); | 1267 Property* property = var->AsProperty(); |
1266 | 1268 |
1267 if (var->is_global() && !var->is_this()) { | 1269 if (var->is_global() && !var->is_this()) { |
1268 Comment cmnt(masm_, "Global variable"); | 1270 Comment cmnt(masm_, "Global variable"); |
1269 // Use inline caching. Variable name is passed in r2 and the global | 1271 // Use inline caching. Variable name is passed in r2 and the global |
1270 // object (receiver) in r0. | 1272 // object (receiver) in r0. |
1271 __ ldr(r0, GlobalObjectOperand()); | 1273 __ ldr(r0, GlobalObjectOperand()); |
1272 __ mov(r2, Operand(var->name())); | 1274 __ mov(r2, Operand(var->name())); |
1273 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1275 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1276 Builtins::LoadIC_Initialize)); |
1274 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1277 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1275 context()->Plug(r0); | 1278 context()->Plug(r0); |
1276 | 1279 |
1277 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1280 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
1278 Label done, slow; | 1281 Label done, slow; |
1279 | 1282 |
1280 // Generate code for loading from variables potentially shadowed | 1283 // Generate code for loading from variables potentially shadowed |
1281 // by eval-introduced variables. | 1284 // by eval-introduced variables. |
1282 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1285 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
1283 | 1286 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1322 | 1325 |
1323 // Assert that the key is a smi. | 1326 // Assert that the key is a smi. |
1324 Literal* key_literal = property->key()->AsLiteral(); | 1327 Literal* key_literal = property->key()->AsLiteral(); |
1325 ASSERT_NOT_NULL(key_literal); | 1328 ASSERT_NOT_NULL(key_literal); |
1326 ASSERT(key_literal->handle()->IsSmi()); | 1329 ASSERT(key_literal->handle()->IsSmi()); |
1327 | 1330 |
1328 // Load the key. | 1331 // Load the key. |
1329 __ mov(r0, Operand(key_literal->handle())); | 1332 __ mov(r0, Operand(key_literal->handle())); |
1330 | 1333 |
1331 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1334 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
1332 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1335 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1336 Builtins::KeyedLoadIC_Initialize)); |
1333 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1337 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1334 context()->Plug(r0); | 1338 context()->Plug(r0); |
1335 } | 1339 } |
1336 } | 1340 } |
1337 | 1341 |
1338 | 1342 |
1339 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1343 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
1340 Comment cmnt(masm_, "[ RegExpLiteral"); | 1344 Comment cmnt(masm_, "[ RegExpLiteral"); |
1341 Label materialized; | 1345 Label materialized; |
1342 // Registers will be used as follows: | 1346 // Registers will be used as follows: |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1425 UNREACHABLE(); | 1429 UNREACHABLE(); |
1426 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1430 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1427 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1431 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1428 // Fall through. | 1432 // Fall through. |
1429 case ObjectLiteral::Property::COMPUTED: | 1433 case ObjectLiteral::Property::COMPUTED: |
1430 if (key->handle()->IsSymbol()) { | 1434 if (key->handle()->IsSymbol()) { |
1431 if (property->emit_store()) { | 1435 if (property->emit_store()) { |
1432 VisitForAccumulatorValue(value); | 1436 VisitForAccumulatorValue(value); |
1433 __ mov(r2, Operand(key->handle())); | 1437 __ mov(r2, Operand(key->handle())); |
1434 __ ldr(r1, MemOperand(sp)); | 1438 __ ldr(r1, MemOperand(sp)); |
1435 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1439 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1440 Builtins::StoreIC_Initialize)); |
1436 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1441 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1437 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1442 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1438 } else { | 1443 } else { |
1439 VisitForEffect(value); | 1444 VisitForEffect(value); |
1440 } | 1445 } |
1441 break; | 1446 break; |
1442 } | 1447 } |
1443 // Fall through. | 1448 // Fall through. |
1444 case ObjectLiteral::Property::PROTOTYPE: | 1449 case ObjectLiteral::Property::PROTOTYPE: |
1445 // Duplicate receiver on stack. | 1450 // Duplicate receiver on stack. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 Comment cmnt(masm_, "[ ArrayLiteral"); | 1488 Comment cmnt(masm_, "[ ArrayLiteral"); |
1484 | 1489 |
1485 ZoneList<Expression*>* subexprs = expr->values(); | 1490 ZoneList<Expression*>* subexprs = expr->values(); |
1486 int length = subexprs->length(); | 1491 int length = subexprs->length(); |
1487 | 1492 |
1488 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1493 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
1489 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); | 1494 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); |
1490 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); | 1495 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); |
1491 __ mov(r1, Operand(expr->constant_elements())); | 1496 __ mov(r1, Operand(expr->constant_elements())); |
1492 __ Push(r3, r2, r1); | 1497 __ Push(r3, r2, r1); |
1493 if (expr->constant_elements()->map() == Heap::fixed_cow_array_map()) { | 1498 if (expr->constant_elements()->map() == |
| 1499 isolate()->heap()->fixed_cow_array_map()) { |
1494 FastCloneShallowArrayStub stub( | 1500 FastCloneShallowArrayStub stub( |
1495 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length); | 1501 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length); |
1496 __ CallStub(&stub); | 1502 __ CallStub(&stub); |
1497 __ IncrementCounter(&Counters::cow_arrays_created_stub, 1, r1, r2); | 1503 __ IncrementCounter( |
| 1504 isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2); |
1498 } else if (expr->depth() > 1) { | 1505 } else if (expr->depth() > 1) { |
1499 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); | 1506 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); |
1500 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1507 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
1501 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); | 1508 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); |
1502 } else { | 1509 } else { |
1503 FastCloneShallowArrayStub stub( | 1510 FastCloneShallowArrayStub stub( |
1504 FastCloneShallowArrayStub::CLONE_ELEMENTS, length); | 1511 FastCloneShallowArrayStub::CLONE_ELEMENTS, length); |
1505 __ CallStub(&stub); | 1512 __ CallStub(&stub); |
1506 } | 1513 } |
1507 | 1514 |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1671 break; | 1678 break; |
1672 } | 1679 } |
1673 } | 1680 } |
1674 | 1681 |
1675 | 1682 |
1676 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1683 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
1677 SetSourcePosition(prop->position()); | 1684 SetSourcePosition(prop->position()); |
1678 Literal* key = prop->key()->AsLiteral(); | 1685 Literal* key = prop->key()->AsLiteral(); |
1679 __ mov(r2, Operand(key->handle())); | 1686 __ mov(r2, Operand(key->handle())); |
1680 // Call load IC. It has arguments receiver and property name r0 and r2. | 1687 // Call load IC. It has arguments receiver and property name r0 and r2. |
1681 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1688 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1689 Builtins::LoadIC_Initialize)); |
1682 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1690 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1683 } | 1691 } |
1684 | 1692 |
1685 | 1693 |
1686 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1694 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1687 SetSourcePosition(prop->position()); | 1695 SetSourcePosition(prop->position()); |
1688 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1696 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
1689 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1697 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1698 Builtins::KeyedLoadIC_Initialize)); |
1690 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1699 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1691 } | 1700 } |
1692 | 1701 |
1693 | 1702 |
1694 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, | 1703 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, |
1695 Token::Value op, | 1704 Token::Value op, |
1696 OverwriteMode mode, | 1705 OverwriteMode mode, |
1697 Expression* left_expr, | 1706 Expression* left_expr, |
1698 Expression* right_expr) { | 1707 Expression* right_expr) { |
1699 Label done, smi_case, stub_call; | 1708 Label done, smi_case, stub_call; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1824 EffectContext context(this); | 1833 EffectContext context(this); |
1825 EmitVariableAssignment(var, Token::ASSIGN); | 1834 EmitVariableAssignment(var, Token::ASSIGN); |
1826 break; | 1835 break; |
1827 } | 1836 } |
1828 case NAMED_PROPERTY: { | 1837 case NAMED_PROPERTY: { |
1829 __ push(r0); // Preserve value. | 1838 __ push(r0); // Preserve value. |
1830 VisitForAccumulatorValue(prop->obj()); | 1839 VisitForAccumulatorValue(prop->obj()); |
1831 __ mov(r1, r0); | 1840 __ mov(r1, r0); |
1832 __ pop(r0); // Restore value. | 1841 __ pop(r0); // Restore value. |
1833 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 1842 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
1834 Handle<Code> ic(Builtins::builtin( | 1843 Handle<Code> ic(isolate()->builtins()->builtin( |
1835 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1844 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
1836 : Builtins::StoreIC_Initialize)); | 1845 : Builtins::StoreIC_Initialize)); |
1837 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1846 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1838 break; | 1847 break; |
1839 } | 1848 } |
1840 case KEYED_PROPERTY: { | 1849 case KEYED_PROPERTY: { |
1841 __ push(r0); // Preserve value. | 1850 __ push(r0); // Preserve value. |
1842 if (prop->is_synthetic()) { | 1851 if (prop->is_synthetic()) { |
1843 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 1852 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
1844 ASSERT(prop->key()->AsLiteral() != NULL); | 1853 ASSERT(prop->key()->AsLiteral() != NULL); |
1845 { AccumulatorValueContext for_object(this); | 1854 { AccumulatorValueContext for_object(this); |
1846 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 1855 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
1847 } | 1856 } |
1848 __ mov(r2, r0); | 1857 __ mov(r2, r0); |
1849 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); | 1858 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); |
1850 } else { | 1859 } else { |
1851 VisitForStackValue(prop->obj()); | 1860 VisitForStackValue(prop->obj()); |
1852 VisitForAccumulatorValue(prop->key()); | 1861 VisitForAccumulatorValue(prop->key()); |
1853 __ mov(r1, r0); | 1862 __ mov(r1, r0); |
1854 __ pop(r2); | 1863 __ pop(r2); |
1855 } | 1864 } |
1856 __ pop(r0); // Restore value. | 1865 __ pop(r0); // Restore value. |
1857 Handle<Code> ic(Builtins::builtin( | 1866 Handle<Code> ic(isolate()->builtins()->builtin( |
1858 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 1867 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
1859 : Builtins::KeyedStoreIC_Initialize)); | 1868 : Builtins::KeyedStoreIC_Initialize)); |
1860 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1869 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1861 break; | 1870 break; |
1862 } | 1871 } |
1863 } | 1872 } |
1864 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1873 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
1865 context()->Plug(r0); | 1874 context()->Plug(r0); |
1866 } | 1875 } |
1867 | 1876 |
1868 | 1877 |
1869 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1878 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
1870 Token::Value op) { | 1879 Token::Value op) { |
1871 // Left-hand sides that rewrite to explicit property accesses do not reach | 1880 // Left-hand sides that rewrite to explicit property accesses do not reach |
1872 // here. | 1881 // here. |
1873 ASSERT(var != NULL); | 1882 ASSERT(var != NULL); |
1874 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1883 ASSERT(var->is_global() || var->AsSlot() != NULL); |
1875 | 1884 |
1876 if (var->is_global()) { | 1885 if (var->is_global()) { |
1877 ASSERT(!var->is_this()); | 1886 ASSERT(!var->is_this()); |
1878 // Assignment to a global variable. Use inline caching for the | 1887 // Assignment to a global variable. Use inline caching for the |
1879 // assignment. Right-hand-side value is passed in r0, variable name in | 1888 // assignment. Right-hand-side value is passed in r0, variable name in |
1880 // r2, and the global object in r1. | 1889 // r2, and the global object in r1. |
1881 __ mov(r2, Operand(var->name())); | 1890 __ mov(r2, Operand(var->name())); |
1882 __ ldr(r1, GlobalObjectOperand()); | 1891 __ ldr(r1, GlobalObjectOperand()); |
1883 Handle<Code> ic(Builtins::builtin( | 1892 Handle<Code> ic(isolate()->builtins()->builtin( |
1884 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1893 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
1885 : Builtins::StoreIC_Initialize)); | 1894 : Builtins::StoreIC_Initialize)); |
1886 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1895 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1887 | 1896 |
1888 } else if (op == Token::INIT_CONST) { | 1897 } else if (op == Token::INIT_CONST) { |
1889 // Like var declarations, const declarations are hoisted to function | 1898 // Like var declarations, const declarations are hoisted to function |
1890 // scope. However, unlike var initializers, const initializers are able | 1899 // scope. However, unlike var initializers, const initializers are able |
1891 // to drill a hole to that function context, even from inside a 'with' | 1900 // to drill a hole to that function context, even from inside a 'with' |
1892 // context. We thus bypass the normal static scope lookup. | 1901 // context. We thus bypass the normal static scope lookup. |
1893 Slot* slot = var->AsSlot(); | 1902 Slot* slot = var->AsSlot(); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1982 SetSourcePosition(expr->position()); | 1991 SetSourcePosition(expr->position()); |
1983 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 1992 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
1984 // Load receiver to r1. Leave a copy in the stack if needed for turning the | 1993 // Load receiver to r1. Leave a copy in the stack if needed for turning the |
1985 // receiver into fast case. | 1994 // receiver into fast case. |
1986 if (expr->ends_initialization_block()) { | 1995 if (expr->ends_initialization_block()) { |
1987 __ ldr(r1, MemOperand(sp)); | 1996 __ ldr(r1, MemOperand(sp)); |
1988 } else { | 1997 } else { |
1989 __ pop(r1); | 1998 __ pop(r1); |
1990 } | 1999 } |
1991 | 2000 |
1992 Handle<Code> ic(Builtins::builtin( | 2001 Handle<Code> ic(isolate()->builtins()->builtin( |
1993 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 2002 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
1994 : Builtins::StoreIC_Initialize)); | 2003 : Builtins::StoreIC_Initialize)); |
1995 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2004 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1996 | 2005 |
1997 // If the assignment ends an initialization block, revert to fast case. | 2006 // If the assignment ends an initialization block, revert to fast case. |
1998 if (expr->ends_initialization_block()) { | 2007 if (expr->ends_initialization_block()) { |
1999 __ push(r0); // Result of assignment, saved even if not needed. | 2008 __ push(r0); // Result of assignment, saved even if not needed. |
2000 // Receiver is under the result value. | 2009 // Receiver is under the result value. |
2001 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2010 __ ldr(ip, MemOperand(sp, kPointerSize)); |
2002 __ push(ip); | 2011 __ push(ip); |
(...skipping 25 matching lines...) Expand all Loading... |
2028 SetSourcePosition(expr->position()); | 2037 SetSourcePosition(expr->position()); |
2029 __ pop(r1); // Key. | 2038 __ pop(r1); // Key. |
2030 // Load receiver to r2. Leave a copy in the stack if needed for turning the | 2039 // Load receiver to r2. Leave a copy in the stack if needed for turning the |
2031 // receiver into fast case. | 2040 // receiver into fast case. |
2032 if (expr->ends_initialization_block()) { | 2041 if (expr->ends_initialization_block()) { |
2033 __ ldr(r2, MemOperand(sp)); | 2042 __ ldr(r2, MemOperand(sp)); |
2034 } else { | 2043 } else { |
2035 __ pop(r2); | 2044 __ pop(r2); |
2036 } | 2045 } |
2037 | 2046 |
2038 Handle<Code> ic(Builtins::builtin( | 2047 Handle<Code> ic(isolate()->builtins()->builtin( |
2039 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 2048 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
2040 : Builtins::KeyedStoreIC_Initialize)); | 2049 : Builtins::KeyedStoreIC_Initialize)); |
2041 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2050 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
2042 | 2051 |
2043 // If the assignment ends an initialization block, revert to fast case. | 2052 // If the assignment ends an initialization block, revert to fast case. |
2044 if (expr->ends_initialization_block()) { | 2053 if (expr->ends_initialization_block()) { |
2045 __ push(r0); // Result of assignment, saved even if not needed. | 2054 __ push(r0); // Result of assignment, saved even if not needed. |
2046 // Receiver is under the result value. | 2055 // Receiver is under the result value. |
2047 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2056 __ ldr(ip, MemOperand(sp, kPointerSize)); |
2048 __ push(ip); | 2057 __ push(ip); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2081 { PreservePositionScope scope(masm()->positions_recorder()); | 2090 { PreservePositionScope scope(masm()->positions_recorder()); |
2082 for (int i = 0; i < arg_count; i++) { | 2091 for (int i = 0; i < arg_count; i++) { |
2083 VisitForStackValue(args->at(i)); | 2092 VisitForStackValue(args->at(i)); |
2084 } | 2093 } |
2085 __ mov(r2, Operand(name)); | 2094 __ mov(r2, Operand(name)); |
2086 } | 2095 } |
2087 // Record source position for debugger. | 2096 // Record source position for debugger. |
2088 SetSourcePosition(expr->position()); | 2097 SetSourcePosition(expr->position()); |
2089 // Call the IC initialization code. | 2098 // Call the IC initialization code. |
2090 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2099 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2091 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop); | 2100 Handle<Code> ic = |
| 2101 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop); |
2092 EmitCallIC(ic, mode); | 2102 EmitCallIC(ic, mode); |
2093 RecordJSReturnSite(expr); | 2103 RecordJSReturnSite(expr); |
2094 // Restore context register. | 2104 // Restore context register. |
2095 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2105 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2096 context()->Plug(r0); | 2106 context()->Plug(r0); |
2097 } | 2107 } |
2098 | 2108 |
2099 | 2109 |
2100 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2110 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2101 Expression* key, | 2111 Expression* key, |
(...skipping 12 matching lines...) Expand all Loading... |
2114 int arg_count = args->length(); | 2124 int arg_count = args->length(); |
2115 { PreservePositionScope scope(masm()->positions_recorder()); | 2125 { PreservePositionScope scope(masm()->positions_recorder()); |
2116 for (int i = 0; i < arg_count; i++) { | 2126 for (int i = 0; i < arg_count; i++) { |
2117 VisitForStackValue(args->at(i)); | 2127 VisitForStackValue(args->at(i)); |
2118 } | 2128 } |
2119 } | 2129 } |
2120 // Record source position for debugger. | 2130 // Record source position for debugger. |
2121 SetSourcePosition(expr->position()); | 2131 SetSourcePosition(expr->position()); |
2122 // Call the IC initialization code. | 2132 // Call the IC initialization code. |
2123 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2133 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2124 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arg_count, in_loop); | 2134 Handle<Code> ic = |
| 2135 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); |
2125 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2136 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
2126 EmitCallIC(ic, mode); | 2137 EmitCallIC(ic, mode); |
2127 RecordJSReturnSite(expr); | 2138 RecordJSReturnSite(expr); |
2128 // Restore context register. | 2139 // Restore context register. |
2129 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2140 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2130 context()->DropAndPlug(1, r0); // Drop the key still on the stack. | 2141 context()->DropAndPlug(1, r0); // Drop the key still on the stack. |
2131 } | 2142 } |
2132 | 2143 |
2133 | 2144 |
2134 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 2145 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2313 MemOperand operand = EmitSlotSearch(slot, r1); | 2324 MemOperand operand = EmitSlotSearch(slot, r1); |
2314 __ ldr(r1, operand); | 2325 __ ldr(r1, operand); |
2315 | 2326 |
2316 ASSERT(prop->key()->AsLiteral() != NULL); | 2327 ASSERT(prop->key()->AsLiteral() != NULL); |
2317 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2328 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
2318 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); | 2329 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); |
2319 | 2330 |
2320 // Record source code position for IC call. | 2331 // Record source code position for IC call. |
2321 SetSourcePosition(prop->position()); | 2332 SetSourcePosition(prop->position()); |
2322 | 2333 |
2323 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 2334 Handle<Code> ic(isolate()->builtins()->builtin( |
| 2335 Builtins::KeyedLoadIC_Initialize)); |
2324 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2336 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
2325 __ ldr(r1, GlobalObjectOperand()); | 2337 __ ldr(r1, GlobalObjectOperand()); |
2326 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2338 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
2327 __ Push(r0, r1); // Function, receiver. | 2339 __ Push(r0, r1); // Function, receiver. |
2328 EmitCallWithStub(expr); | 2340 EmitCallWithStub(expr); |
2329 } else { | 2341 } else { |
2330 { PreservePositionScope scope(masm()->positions_recorder()); | 2342 { PreservePositionScope scope(masm()->positions_recorder()); |
2331 VisitForStackValue(prop->obj()); | 2343 VisitForStackValue(prop->obj()); |
2332 } | 2344 } |
2333 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 2345 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
2334 } | 2346 } |
2335 } | 2347 } |
2336 } else { | 2348 } else { |
2337 // Call to some other expression. If the expression is an anonymous | 2349 // Call to some other expression. If the expression is an anonymous |
2338 // function literal not called in a loop, mark it as one that should | 2350 // function literal not called in a loop, mark it as one that should |
2339 // also use the fast code generator. | 2351 // also use the fast code generator. |
2340 FunctionLiteral* lit = fun->AsFunctionLiteral(); | 2352 FunctionLiteral* lit = fun->AsFunctionLiteral(); |
2341 if (lit != NULL && | 2353 if (lit != NULL && |
2342 lit->name()->Equals(Heap::empty_string()) && | 2354 lit->name()->Equals(isolate()->heap()->empty_string()) && |
2343 loop_depth() == 0) { | 2355 loop_depth() == 0) { |
2344 lit->set_try_full_codegen(true); | 2356 lit->set_try_full_codegen(true); |
2345 } | 2357 } |
2346 | 2358 |
2347 { PreservePositionScope scope(masm()->positions_recorder()); | 2359 { PreservePositionScope scope(masm()->positions_recorder()); |
2348 VisitForStackValue(fun); | 2360 VisitForStackValue(fun); |
2349 } | 2361 } |
2350 // Load global receiver object. | 2362 // Load global receiver object. |
2351 __ ldr(r1, GlobalObjectOperand()); | 2363 __ ldr(r1, GlobalObjectOperand()); |
2352 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2364 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
(...skipping 28 matching lines...) Expand all Loading... |
2381 } | 2393 } |
2382 | 2394 |
2383 // Call the construct call builtin that handles allocation and | 2395 // Call the construct call builtin that handles allocation and |
2384 // constructor invocation. | 2396 // constructor invocation. |
2385 SetSourcePosition(expr->position()); | 2397 SetSourcePosition(expr->position()); |
2386 | 2398 |
2387 // Load function and argument count into r1 and r0. | 2399 // Load function and argument count into r1 and r0. |
2388 __ mov(r0, Operand(arg_count)); | 2400 __ mov(r0, Operand(arg_count)); |
2389 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); | 2401 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
2390 | 2402 |
2391 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); | 2403 Handle<Code> construct_builtin(isolate()->builtins()->builtin( |
| 2404 Builtins::JSConstructCall)); |
2392 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); | 2405 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
2393 context()->Plug(r0); | 2406 context()->Plug(r0); |
2394 } | 2407 } |
2395 | 2408 |
2396 | 2409 |
2397 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { | 2410 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { |
2398 ASSERT(args->length() == 1); | 2411 ASSERT(args->length() == 1); |
2399 | 2412 |
2400 VisitForAccumulatorValue(args->at(0)); | 2413 VisitForAccumulatorValue(args->at(0)); |
2401 | 2414 |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2776 __ bind(&slow_allocate_heapnumber); | 2789 __ bind(&slow_allocate_heapnumber); |
2777 // Allocate a heap number. | 2790 // Allocate a heap number. |
2778 __ CallRuntime(Runtime::kNumberAlloc, 0); | 2791 __ CallRuntime(Runtime::kNumberAlloc, 0); |
2779 __ mov(r4, Operand(r0)); | 2792 __ mov(r4, Operand(r0)); |
2780 | 2793 |
2781 __ bind(&heapnumber_allocated); | 2794 __ bind(&heapnumber_allocated); |
2782 | 2795 |
2783 // Convert 32 random bits in r0 to 0.(32 random bits) in a double | 2796 // Convert 32 random bits in r0 to 0.(32 random bits) in a double |
2784 // by computing: | 2797 // by computing: |
2785 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). | 2798 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). |
2786 if (CpuFeatures::IsSupported(VFP3)) { | 2799 if (isolate()->cpu_features()->IsSupported(VFP3)) { |
2787 __ PrepareCallCFunction(0, r1); | 2800 __ PrepareCallCFunction(0, r1); |
2788 __ CallCFunction(ExternalReference::random_uint32_function(), 0); | 2801 __ CallCFunction(ExternalReference::random_uint32_function(), 0); |
2789 | 2802 |
2790 CpuFeatures::Scope scope(VFP3); | 2803 CpuFeatures::Scope scope(VFP3); |
2791 // 0x41300000 is the top half of 1.0 x 2^20 as a double. | 2804 // 0x41300000 is the top half of 1.0 x 2^20 as a double. |
2792 // Create this constant using mov/orr to avoid PC relative load. | 2805 // Create this constant using mov/orr to avoid PC relative load. |
2793 __ mov(r1, Operand(0x41000000)); | 2806 __ mov(r1, Operand(0x41000000)); |
2794 __ orr(r1, r1, Operand(0x300000)); | 2807 __ orr(r1, r1, Operand(0x300000)); |
2795 // Move 0x41300000xxxxxxxx (x = random bits) to VFP. | 2808 // Move 0x41300000xxxxxxxx (x = random bits) to VFP. |
2796 __ vmov(d7, r0, r1); | 2809 __ vmov(d7, r0, r1); |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3197 } | 3210 } |
3198 | 3211 |
3199 | 3212 |
3200 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { | 3213 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { |
3201 ASSERT_EQ(2, args->length()); | 3214 ASSERT_EQ(2, args->length()); |
3202 | 3215 |
3203 ASSERT_NE(NULL, args->at(0)->AsLiteral()); | 3216 ASSERT_NE(NULL, args->at(0)->AsLiteral()); |
3204 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); | 3217 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); |
3205 | 3218 |
3206 Handle<FixedArray> jsfunction_result_caches( | 3219 Handle<FixedArray> jsfunction_result_caches( |
3207 Top::global_context()->jsfunction_result_caches()); | 3220 isolate()->global_context()->jsfunction_result_caches()); |
3208 if (jsfunction_result_caches->length() <= cache_id) { | 3221 if (jsfunction_result_caches->length() <= cache_id) { |
3209 __ Abort("Attempt to use undefined cache."); | 3222 __ Abort("Attempt to use undefined cache."); |
3210 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 3223 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
3211 context()->Plug(r0); | 3224 context()->Plug(r0); |
3212 return; | 3225 return; |
3213 } | 3226 } |
3214 | 3227 |
3215 VisitForAccumulatorValue(args->at(1)); | 3228 VisitForAccumulatorValue(args->at(1)); |
3216 | 3229 |
3217 Register key = r0; | 3230 Register key = r0; |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3576 | 3589 |
3577 // Push the arguments ("left-to-right"). | 3590 // Push the arguments ("left-to-right"). |
3578 int arg_count = args->length(); | 3591 int arg_count = args->length(); |
3579 for (int i = 0; i < arg_count; i++) { | 3592 for (int i = 0; i < arg_count; i++) { |
3580 VisitForStackValue(args->at(i)); | 3593 VisitForStackValue(args->at(i)); |
3581 } | 3594 } |
3582 | 3595 |
3583 if (expr->is_jsruntime()) { | 3596 if (expr->is_jsruntime()) { |
3584 // Call the JS runtime function. | 3597 // Call the JS runtime function. |
3585 __ mov(r2, Operand(expr->name())); | 3598 __ mov(r2, Operand(expr->name())); |
3586 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, NOT_IN_LOOP); | 3599 Handle<Code> ic = |
| 3600 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); |
3587 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3601 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3588 // Restore context register. | 3602 // Restore context register. |
3589 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3603 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3590 } else { | 3604 } else { |
3591 // Call the C runtime function. | 3605 // Call the C runtime function. |
3592 __ CallRuntime(expr->function(), arg_count); | 3606 __ CallRuntime(expr->function(), arg_count); |
3593 } | 3607 } |
3594 context()->Plug(r0); | 3608 context()->Plug(r0); |
3595 } | 3609 } |
3596 | 3610 |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3880 } else { | 3894 } else { |
3881 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3895 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
3882 Token::ASSIGN); | 3896 Token::ASSIGN); |
3883 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3897 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3884 context()->Plug(r0); | 3898 context()->Plug(r0); |
3885 } | 3899 } |
3886 break; | 3900 break; |
3887 case NAMED_PROPERTY: { | 3901 case NAMED_PROPERTY: { |
3888 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 3902 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
3889 __ pop(r1); | 3903 __ pop(r1); |
3890 Handle<Code> ic(Builtins::builtin( | 3904 Handle<Code> ic(isolate()->builtins()->builtin( |
3891 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 3905 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
3892 : Builtins::StoreIC_Initialize)); | 3906 : Builtins::StoreIC_Initialize)); |
3893 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3907 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3894 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3908 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3895 if (expr->is_postfix()) { | 3909 if (expr->is_postfix()) { |
3896 if (!context()->IsEffect()) { | 3910 if (!context()->IsEffect()) { |
3897 context()->PlugTOS(); | 3911 context()->PlugTOS(); |
3898 } | 3912 } |
3899 } else { | 3913 } else { |
3900 context()->Plug(r0); | 3914 context()->Plug(r0); |
3901 } | 3915 } |
3902 break; | 3916 break; |
3903 } | 3917 } |
3904 case KEYED_PROPERTY: { | 3918 case KEYED_PROPERTY: { |
3905 __ pop(r1); // Key. | 3919 __ pop(r1); // Key. |
3906 __ pop(r2); // Receiver. | 3920 __ pop(r2); // Receiver. |
3907 Handle<Code> ic(Builtins::builtin( | 3921 Handle<Code> ic(isolate()->builtins()->builtin( |
3908 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 3922 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
3909 : Builtins::KeyedStoreIC_Initialize)); | 3923 : Builtins::KeyedStoreIC_Initialize)); |
3910 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3924 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3911 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3925 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3912 if (expr->is_postfix()) { | 3926 if (expr->is_postfix()) { |
3913 if (!context()->IsEffect()) { | 3927 if (!context()->IsEffect()) { |
3914 context()->PlugTOS(); | 3928 context()->PlugTOS(); |
3915 } | 3929 } |
3916 } else { | 3930 } else { |
3917 context()->Plug(r0); | 3931 context()->Plug(r0); |
3918 } | 3932 } |
3919 break; | 3933 break; |
3920 } | 3934 } |
3921 } | 3935 } |
3922 } | 3936 } |
3923 | 3937 |
3924 | 3938 |
3925 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3939 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
3926 ASSERT(!context()->IsEffect()); | 3940 ASSERT(!context()->IsEffect()); |
3927 ASSERT(!context()->IsTest()); | 3941 ASSERT(!context()->IsTest()); |
3928 VariableProxy* proxy = expr->AsVariableProxy(); | 3942 VariableProxy* proxy = expr->AsVariableProxy(); |
3929 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3943 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
3930 Comment cmnt(masm_, "Global variable"); | 3944 Comment cmnt(masm_, "Global variable"); |
3931 __ ldr(r0, GlobalObjectOperand()); | 3945 __ ldr(r0, GlobalObjectOperand()); |
3932 __ mov(r2, Operand(proxy->name())); | 3946 __ mov(r2, Operand(proxy->name())); |
3933 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 3947 Handle<Code> ic(isolate()->builtins()->builtin( |
| 3948 Builtins::LoadIC_Initialize)); |
3934 // Use a regular load, not a contextual load, to avoid a reference | 3949 // Use a regular load, not a contextual load, to avoid a reference |
3935 // error. | 3950 // error. |
3936 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3951 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3937 PrepareForBailout(expr, TOS_REG); | 3952 PrepareForBailout(expr, TOS_REG); |
3938 context()->Plug(r0); | 3953 context()->Plug(r0); |
3939 } else if (proxy != NULL && | 3954 } else if (proxy != NULL && |
3940 proxy->var()->AsSlot() != NULL && | 3955 proxy->var()->AsSlot() != NULL && |
3941 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3956 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
3942 Label done, slow; | 3957 Label done, slow; |
3943 | 3958 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3976 if (!right_literal_value->IsString()) return false; | 3991 if (!right_literal_value->IsString()) return false; |
3977 UnaryOperation* left_unary = left->AsUnaryOperation(); | 3992 UnaryOperation* left_unary = left->AsUnaryOperation(); |
3978 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false; | 3993 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false; |
3979 Handle<String> check = Handle<String>::cast(right_literal_value); | 3994 Handle<String> check = Handle<String>::cast(right_literal_value); |
3980 | 3995 |
3981 { AccumulatorValueContext context(this); | 3996 { AccumulatorValueContext context(this); |
3982 VisitForTypeofValue(left_unary->expression()); | 3997 VisitForTypeofValue(left_unary->expression()); |
3983 } | 3998 } |
3984 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 3999 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
3985 | 4000 |
3986 if (check->Equals(Heap::number_symbol())) { | 4001 if (check->Equals(isolate()->heap()->number_symbol())) { |
3987 __ JumpIfSmi(r0, if_true); | 4002 __ JumpIfSmi(r0, if_true); |
3988 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); | 4003 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); |
3989 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 4004 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
3990 __ cmp(r0, ip); | 4005 __ cmp(r0, ip); |
3991 Split(eq, if_true, if_false, fall_through); | 4006 Split(eq, if_true, if_false, fall_through); |
3992 } else if (check->Equals(Heap::string_symbol())) { | 4007 } else if (check->Equals(isolate()->heap()->string_symbol())) { |
3993 __ JumpIfSmi(r0, if_false); | 4008 __ JumpIfSmi(r0, if_false); |
3994 // Check for undetectable objects => false. | 4009 // Check for undetectable objects => false. |
3995 __ CompareObjectType(r0, r0, r1, FIRST_NONSTRING_TYPE); | 4010 __ CompareObjectType(r0, r0, r1, FIRST_NONSTRING_TYPE); |
3996 __ b(ge, if_false); | 4011 __ b(ge, if_false); |
3997 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); | 4012 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); |
3998 __ tst(r1, Operand(1 << Map::kIsUndetectable)); | 4013 __ tst(r1, Operand(1 << Map::kIsUndetectable)); |
3999 Split(eq, if_true, if_false, fall_through); | 4014 Split(eq, if_true, if_false, fall_through); |
4000 } else if (check->Equals(Heap::boolean_symbol())) { | 4015 } else if (check->Equals(isolate()->heap()->boolean_symbol())) { |
4001 __ CompareRoot(r0, Heap::kTrueValueRootIndex); | 4016 __ CompareRoot(r0, Heap::kTrueValueRootIndex); |
4002 __ b(eq, if_true); | 4017 __ b(eq, if_true); |
4003 __ CompareRoot(r0, Heap::kFalseValueRootIndex); | 4018 __ CompareRoot(r0, Heap::kFalseValueRootIndex); |
4004 Split(eq, if_true, if_false, fall_through); | 4019 Split(eq, if_true, if_false, fall_through); |
4005 } else if (check->Equals(Heap::undefined_symbol())) { | 4020 } else if (check->Equals(isolate()->heap()->undefined_symbol())) { |
4006 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); | 4021 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); |
4007 __ b(eq, if_true); | 4022 __ b(eq, if_true); |
4008 __ JumpIfSmi(r0, if_false); | 4023 __ JumpIfSmi(r0, if_false); |
4009 // Check for undetectable objects => true. | 4024 // Check for undetectable objects => true. |
4010 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); | 4025 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); |
4011 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); | 4026 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); |
4012 __ tst(r1, Operand(1 << Map::kIsUndetectable)); | 4027 __ tst(r1, Operand(1 << Map::kIsUndetectable)); |
4013 Split(ne, if_true, if_false, fall_through); | 4028 Split(ne, if_true, if_false, fall_through); |
4014 | 4029 |
4015 } else if (check->Equals(Heap::function_symbol())) { | 4030 } else if (check->Equals(isolate()->heap()->function_symbol())) { |
4016 __ JumpIfSmi(r0, if_false); | 4031 __ JumpIfSmi(r0, if_false); |
4017 __ CompareObjectType(r0, r1, r0, FIRST_FUNCTION_CLASS_TYPE); | 4032 __ CompareObjectType(r0, r1, r0, FIRST_FUNCTION_CLASS_TYPE); |
4018 Split(ge, if_true, if_false, fall_through); | 4033 Split(ge, if_true, if_false, fall_through); |
4019 | 4034 |
4020 } else if (check->Equals(Heap::object_symbol())) { | 4035 } else if (check->Equals(isolate()->heap()->object_symbol())) { |
4021 __ JumpIfSmi(r0, if_false); | 4036 __ JumpIfSmi(r0, if_false); |
4022 __ CompareRoot(r0, Heap::kNullValueRootIndex); | 4037 __ CompareRoot(r0, Heap::kNullValueRootIndex); |
4023 __ b(eq, if_true); | 4038 __ b(eq, if_true); |
4024 // Check for JS objects => true. | 4039 // Check for JS objects => true. |
4025 __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE); | 4040 __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE); |
4026 __ b(lo, if_false); | 4041 __ b(lo, if_false); |
4027 __ CompareInstanceType(r0, r1, FIRST_FUNCTION_CLASS_TYPE); | 4042 __ CompareInstanceType(r0, r1, FIRST_FUNCTION_CLASS_TYPE); |
4028 __ b(hs, if_false); | 4043 __ b(hs, if_false); |
4029 // Check for undetectable objects => false. | 4044 // Check for undetectable objects => false. |
4030 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); | 4045 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4196 Register FullCodeGenerator::context_register() { | 4211 Register FullCodeGenerator::context_register() { |
4197 return cp; | 4212 return cp; |
4198 } | 4213 } |
4199 | 4214 |
4200 | 4215 |
4201 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { | 4216 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { |
4202 ASSERT(mode == RelocInfo::CODE_TARGET || | 4217 ASSERT(mode == RelocInfo::CODE_TARGET || |
4203 mode == RelocInfo::CODE_TARGET_CONTEXT); | 4218 mode == RelocInfo::CODE_TARGET_CONTEXT); |
4204 switch (ic->kind()) { | 4219 switch (ic->kind()) { |
4205 case Code::LOAD_IC: | 4220 case Code::LOAD_IC: |
4206 __ IncrementCounter(&Counters::named_load_full, 1, r1, r2); | 4221 __ IncrementCounter(COUNTERS->named_load_full(), 1, r1, r2); |
4207 break; | 4222 break; |
4208 case Code::KEYED_LOAD_IC: | 4223 case Code::KEYED_LOAD_IC: |
4209 __ IncrementCounter(&Counters::keyed_load_full, 1, r1, r2); | 4224 __ IncrementCounter(COUNTERS->keyed_load_full(), 1, r1, r2); |
4210 break; | 4225 break; |
4211 case Code::STORE_IC: | 4226 case Code::STORE_IC: |
4212 __ IncrementCounter(&Counters::named_store_full, 1, r1, r2); | 4227 __ IncrementCounter(COUNTERS->named_store_full(), 1, r1, r2); |
4213 break; | 4228 break; |
4214 case Code::KEYED_STORE_IC: | 4229 case Code::KEYED_STORE_IC: |
4215 __ IncrementCounter(&Counters::keyed_store_full, 1, r1, r2); | 4230 __ IncrementCounter(COUNTERS->keyed_store_full(), 1, r1, r2); |
4216 default: | 4231 default: |
4217 break; | 4232 break; |
4218 } | 4233 } |
4219 | 4234 |
4220 __ Call(ic, mode); | 4235 __ Call(ic, mode); |
4221 } | 4236 } |
4222 | 4237 |
4223 | 4238 |
4224 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { | 4239 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { |
4225 switch (ic->kind()) { | 4240 switch (ic->kind()) { |
4226 case Code::LOAD_IC: | 4241 case Code::LOAD_IC: |
4227 __ IncrementCounter(&Counters::named_load_full, 1, r1, r2); | 4242 __ IncrementCounter(COUNTERS->named_load_full(), 1, r1, r2); |
4228 break; | 4243 break; |
4229 case Code::KEYED_LOAD_IC: | 4244 case Code::KEYED_LOAD_IC: |
4230 __ IncrementCounter(&Counters::keyed_load_full, 1, r1, r2); | 4245 __ IncrementCounter(COUNTERS->keyed_load_full(), 1, r1, r2); |
4231 break; | 4246 break; |
4232 case Code::STORE_IC: | 4247 case Code::STORE_IC: |
4233 __ IncrementCounter(&Counters::named_store_full, 1, r1, r2); | 4248 __ IncrementCounter(COUNTERS->named_store_full(), 1, r1, r2); |
4234 break; | 4249 break; |
4235 case Code::KEYED_STORE_IC: | 4250 case Code::KEYED_STORE_IC: |
4236 __ IncrementCounter(&Counters::keyed_store_full, 1, r1, r2); | 4251 __ IncrementCounter(COUNTERS->keyed_store_full(), 1, r1, r2); |
4237 default: | 4252 default: |
4238 break; | 4253 break; |
4239 } | 4254 } |
4240 | 4255 |
4241 __ Call(ic, RelocInfo::CODE_TARGET); | 4256 __ Call(ic, RelocInfo::CODE_TARGET); |
4242 if (patch_site != NULL && patch_site->is_bound()) { | 4257 if (patch_site != NULL && patch_site->is_bound()) { |
4243 patch_site->EmitPatchInfo(); | 4258 patch_site->EmitPatchInfo(); |
4244 } else { | 4259 } else { |
4245 __ nop(); // Signals no inlined code. | 4260 __ nop(); // Signals no inlined code. |
4246 } | 4261 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4284 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 4299 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
4285 __ add(pc, r1, Operand(masm_->CodeObject())); | 4300 __ add(pc, r1, Operand(masm_->CodeObject())); |
4286 } | 4301 } |
4287 | 4302 |
4288 | 4303 |
4289 #undef __ | 4304 #undef __ |
4290 | 4305 |
4291 } } // namespace v8::internal | 4306 } } // namespace v8::internal |
4292 | 4307 |
4293 #endif // V8_TARGET_ARCH_ARM | 4308 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |