| 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 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 if (true_label_ != fall_through_) __ b(true_label_); | 558 if (true_label_ != fall_through_) __ b(true_label_); |
| 559 } else { | 559 } else { |
| 560 if (false_label_ != fall_through_) __ b(false_label_); | 560 if (false_label_ != fall_through_) __ b(false_label_); |
| 561 } | 561 } |
| 562 } | 562 } |
| 563 | 563 |
| 564 | 564 |
| 565 void FullCodeGenerator::DoTest(Label* if_true, | 565 void FullCodeGenerator::DoTest(Label* if_true, |
| 566 Label* if_false, | 566 Label* if_false, |
| 567 Label* fall_through) { | 567 Label* fall_through) { |
| 568 if (CpuFeatures::IsSupported(VFP3)) { | 568 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { |
| 569 CpuFeatures::Scope scope(VFP3); | 569 CpuFeatures::Scope scope(VFP3); |
| 570 // Emit the inlined tests assumed by the stub. | 570 // Emit the inlined tests assumed by the stub. |
| 571 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 571 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 572 __ cmp(result_register(), ip); | 572 __ cmp(result_register(), ip); |
| 573 __ b(eq, if_false); | 573 __ b(eq, if_false); |
| 574 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 574 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
| 575 __ cmp(result_register(), ip); | 575 __ cmp(result_register(), ip); |
| 576 __ b(eq, if_true); | 576 __ b(eq, if_true); |
| 577 __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 577 __ LoadRoot(ip, Heap::kFalseValueRootIndex); |
| 578 __ cmp(result_register(), ip); | 578 __ cmp(result_register(), ip); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 VisitForAccumulatorValue(function); | 783 VisitForAccumulatorValue(function); |
| 784 __ pop(r2); | 784 __ pop(r2); |
| 785 } else { | 785 } else { |
| 786 __ mov(r2, r0); | 786 __ mov(r2, r0); |
| 787 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); | 787 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); |
| 788 } | 788 } |
| 789 ASSERT(prop->key()->AsLiteral() != NULL && | 789 ASSERT(prop->key()->AsLiteral() != NULL && |
| 790 prop->key()->AsLiteral()->handle()->IsSmi()); | 790 prop->key()->AsLiteral()->handle()->IsSmi()); |
| 791 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); | 791 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); |
| 792 | 792 |
| 793 Handle<Code> ic(Builtins::builtin( | 793 Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode() |
| 794 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 794 ? Builtins::KeyedStoreIC_Initialize_Strict |
| 795 : Builtins::KeyedStoreIC_Initialize)); | 795 : Builtins::KeyedStoreIC_Initialize)); |
| 796 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 796 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 797 // Value in r0 is ignored (declarations are statements). | 797 // Value in r0 is ignored (declarations are statements). |
| 798 } | 798 } |
| 799 } | 799 } |
| 800 } | 800 } |
| 801 | 801 |
| 802 | 802 |
| 803 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 803 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 804 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 804 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
| 805 } | 805 } |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1188 key_literal != NULL && | 1188 key_literal != NULL && |
| 1189 obj_proxy->IsArguments() && | 1189 obj_proxy->IsArguments() && |
| 1190 key_literal->handle()->IsSmi()) { | 1190 key_literal->handle()->IsSmi()) { |
| 1191 // Load arguments object if there are no eval-introduced | 1191 // Load arguments object if there are no eval-introduced |
| 1192 // variables. Then load the argument from the arguments | 1192 // variables. Then load the argument from the arguments |
| 1193 // object using keyed load. | 1193 // object using keyed load. |
| 1194 __ ldr(r1, | 1194 __ ldr(r1, |
| 1195 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1195 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
| 1196 slow)); | 1196 slow)); |
| 1197 __ mov(r0, Operand(key_literal->handle())); | 1197 __ mov(r0, Operand(key_literal->handle())); |
| 1198 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1198 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1199 Builtins::KeyedLoadIC_Initialize)); |
| 1199 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1200 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1200 __ jmp(done); | 1201 __ jmp(done); |
| 1201 } | 1202 } |
| 1202 } | 1203 } |
| 1203 } | 1204 } |
| 1204 } | 1205 } |
| 1205 } | 1206 } |
| 1206 | 1207 |
| 1207 | 1208 |
| 1208 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( | 1209 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1254 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset)); | 1255 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset)); |
| 1255 __ b(&loop); | 1256 __ b(&loop); |
| 1256 __ bind(&fast); | 1257 __ bind(&fast); |
| 1257 } | 1258 } |
| 1258 | 1259 |
| 1259 __ ldr(r0, GlobalObjectOperand()); | 1260 __ ldr(r0, GlobalObjectOperand()); |
| 1260 __ mov(r2, Operand(slot->var()->name())); | 1261 __ mov(r2, Operand(slot->var()->name())); |
| 1261 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1262 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
| 1262 ? RelocInfo::CODE_TARGET | 1263 ? RelocInfo::CODE_TARGET |
| 1263 : RelocInfo::CODE_TARGET_CONTEXT; | 1264 : RelocInfo::CODE_TARGET_CONTEXT; |
| 1264 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1265 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1266 Builtins::LoadIC_Initialize)); |
| 1265 EmitCallIC(ic, mode); | 1267 EmitCallIC(ic, mode); |
| 1266 } | 1268 } |
| 1267 | 1269 |
| 1268 | 1270 |
| 1269 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1271 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
| 1270 // Four cases: non-this global variables, lookup slots, all other | 1272 // Four cases: non-this global variables, lookup slots, all other |
| 1271 // types of slots, and parameters that rewrite to explicit property | 1273 // types of slots, and parameters that rewrite to explicit property |
| 1272 // accesses on the arguments object. | 1274 // accesses on the arguments object. |
| 1273 Slot* slot = var->AsSlot(); | 1275 Slot* slot = var->AsSlot(); |
| 1274 Property* property = var->AsProperty(); | 1276 Property* property = var->AsProperty(); |
| 1275 | 1277 |
| 1276 if (var->is_global() && !var->is_this()) { | 1278 if (var->is_global() && !var->is_this()) { |
| 1277 Comment cmnt(masm_, "Global variable"); | 1279 Comment cmnt(masm_, "Global variable"); |
| 1278 // Use inline caching. Variable name is passed in r2 and the global | 1280 // Use inline caching. Variable name is passed in r2 and the global |
| 1279 // object (receiver) in r0. | 1281 // object (receiver) in r0. |
| 1280 __ ldr(r0, GlobalObjectOperand()); | 1282 __ ldr(r0, GlobalObjectOperand()); |
| 1281 __ mov(r2, Operand(var->name())); | 1283 __ mov(r2, Operand(var->name())); |
| 1282 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1284 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1285 Builtins::LoadIC_Initialize)); |
| 1283 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1286 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1284 context()->Plug(r0); | 1287 context()->Plug(r0); |
| 1285 | 1288 |
| 1286 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1289 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 1287 Label done, slow; | 1290 Label done, slow; |
| 1288 | 1291 |
| 1289 // Generate code for loading from variables potentially shadowed | 1292 // Generate code for loading from variables potentially shadowed |
| 1290 // by eval-introduced variables. | 1293 // by eval-introduced variables. |
| 1291 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1294 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1292 | 1295 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1331 | 1334 |
| 1332 // Assert that the key is a smi. | 1335 // Assert that the key is a smi. |
| 1333 Literal* key_literal = property->key()->AsLiteral(); | 1336 Literal* key_literal = property->key()->AsLiteral(); |
| 1334 ASSERT_NOT_NULL(key_literal); | 1337 ASSERT_NOT_NULL(key_literal); |
| 1335 ASSERT(key_literal->handle()->IsSmi()); | 1338 ASSERT(key_literal->handle()->IsSmi()); |
| 1336 | 1339 |
| 1337 // Load the key. | 1340 // Load the key. |
| 1338 __ mov(r0, Operand(key_literal->handle())); | 1341 __ mov(r0, Operand(key_literal->handle())); |
| 1339 | 1342 |
| 1340 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1343 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 1341 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1344 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1345 Builtins::KeyedLoadIC_Initialize)); |
| 1342 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1346 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1343 context()->Plug(r0); | 1347 context()->Plug(r0); |
| 1344 } | 1348 } |
| 1345 } | 1349 } |
| 1346 | 1350 |
| 1347 | 1351 |
| 1348 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1352 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 1349 Comment cmnt(masm_, "[ RegExpLiteral"); | 1353 Comment cmnt(masm_, "[ RegExpLiteral"); |
| 1350 Label materialized; | 1354 Label materialized; |
| 1351 // Registers will be used as follows: | 1355 // Registers will be used as follows: |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1434 UNREACHABLE(); | 1438 UNREACHABLE(); |
| 1435 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1439 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1436 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1440 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1437 // Fall through. | 1441 // Fall through. |
| 1438 case ObjectLiteral::Property::COMPUTED: | 1442 case ObjectLiteral::Property::COMPUTED: |
| 1439 if (key->handle()->IsSymbol()) { | 1443 if (key->handle()->IsSymbol()) { |
| 1440 if (property->emit_store()) { | 1444 if (property->emit_store()) { |
| 1441 VisitForAccumulatorValue(value); | 1445 VisitForAccumulatorValue(value); |
| 1442 __ mov(r2, Operand(key->handle())); | 1446 __ mov(r2, Operand(key->handle())); |
| 1443 __ ldr(r1, MemOperand(sp)); | 1447 __ ldr(r1, MemOperand(sp)); |
| 1444 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1448 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1449 Builtins::StoreIC_Initialize)); |
| 1445 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1450 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1446 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1451 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1447 } else { | 1452 } else { |
| 1448 VisitForEffect(value); | 1453 VisitForEffect(value); |
| 1449 } | 1454 } |
| 1450 break; | 1455 break; |
| 1451 } | 1456 } |
| 1452 // Fall through. | 1457 // Fall through. |
| 1453 case ObjectLiteral::Property::PROTOTYPE: | 1458 case ObjectLiteral::Property::PROTOTYPE: |
| 1454 // Duplicate receiver on stack. | 1459 // Duplicate receiver on stack. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1492 Comment cmnt(masm_, "[ ArrayLiteral"); | 1497 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1493 | 1498 |
| 1494 ZoneList<Expression*>* subexprs = expr->values(); | 1499 ZoneList<Expression*>* subexprs = expr->values(); |
| 1495 int length = subexprs->length(); | 1500 int length = subexprs->length(); |
| 1496 | 1501 |
| 1497 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1502 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1498 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); | 1503 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); |
| 1499 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); | 1504 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); |
| 1500 __ mov(r1, Operand(expr->constant_elements())); | 1505 __ mov(r1, Operand(expr->constant_elements())); |
| 1501 __ Push(r3, r2, r1); | 1506 __ Push(r3, r2, r1); |
| 1502 if (expr->constant_elements()->map() == Heap::fixed_cow_array_map()) { | 1507 if (expr->constant_elements()->map() == |
| 1508 isolate()->heap()->fixed_cow_array_map()) { |
| 1503 FastCloneShallowArrayStub stub( | 1509 FastCloneShallowArrayStub stub( |
| 1504 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length); | 1510 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length); |
| 1505 __ CallStub(&stub); | 1511 __ CallStub(&stub); |
| 1506 __ IncrementCounter(&Counters::cow_arrays_created_stub, 1, r1, r2); | 1512 __ IncrementCounter( |
| 1513 isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2); |
| 1507 } else if (expr->depth() > 1) { | 1514 } else if (expr->depth() > 1) { |
| 1508 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); | 1515 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); |
| 1509 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1516 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
| 1510 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); | 1517 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); |
| 1511 } else { | 1518 } else { |
| 1512 FastCloneShallowArrayStub stub( | 1519 FastCloneShallowArrayStub stub( |
| 1513 FastCloneShallowArrayStub::CLONE_ELEMENTS, length); | 1520 FastCloneShallowArrayStub::CLONE_ELEMENTS, length); |
| 1514 __ CallStub(&stub); | 1521 __ CallStub(&stub); |
| 1515 } | 1522 } |
| 1516 | 1523 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1682 break; | 1689 break; |
| 1683 } | 1690 } |
| 1684 } | 1691 } |
| 1685 | 1692 |
| 1686 | 1693 |
| 1687 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1694 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1688 SetSourcePosition(prop->position()); | 1695 SetSourcePosition(prop->position()); |
| 1689 Literal* key = prop->key()->AsLiteral(); | 1696 Literal* key = prop->key()->AsLiteral(); |
| 1690 __ mov(r2, Operand(key->handle())); | 1697 __ mov(r2, Operand(key->handle())); |
| 1691 // Call load IC. It has arguments receiver and property name r0 and r2. | 1698 // Call load IC. It has arguments receiver and property name r0 and r2. |
| 1692 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1699 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1700 Builtins::LoadIC_Initialize)); |
| 1693 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1701 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1694 } | 1702 } |
| 1695 | 1703 |
| 1696 | 1704 |
| 1697 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1705 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 1698 SetSourcePosition(prop->position()); | 1706 SetSourcePosition(prop->position()); |
| 1699 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1707 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 1700 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1708 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1709 Builtins::KeyedLoadIC_Initialize)); |
| 1701 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1710 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1702 } | 1711 } |
| 1703 | 1712 |
| 1704 | 1713 |
| 1705 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, | 1714 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, |
| 1706 Token::Value op, | 1715 Token::Value op, |
| 1707 OverwriteMode mode, | 1716 OverwriteMode mode, |
| 1708 Expression* left_expr, | 1717 Expression* left_expr, |
| 1709 Expression* right_expr) { | 1718 Expression* right_expr) { |
| 1710 Label done, smi_case, stub_call; | 1719 Label done, smi_case, stub_call; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1835 EffectContext context(this); | 1844 EffectContext context(this); |
| 1836 EmitVariableAssignment(var, Token::ASSIGN); | 1845 EmitVariableAssignment(var, Token::ASSIGN); |
| 1837 break; | 1846 break; |
| 1838 } | 1847 } |
| 1839 case NAMED_PROPERTY: { | 1848 case NAMED_PROPERTY: { |
| 1840 __ push(r0); // Preserve value. | 1849 __ push(r0); // Preserve value. |
| 1841 VisitForAccumulatorValue(prop->obj()); | 1850 VisitForAccumulatorValue(prop->obj()); |
| 1842 __ mov(r1, r0); | 1851 __ mov(r1, r0); |
| 1843 __ pop(r0); // Restore value. | 1852 __ pop(r0); // Restore value. |
| 1844 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 1853 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 1845 Handle<Code> ic(Builtins::builtin( | 1854 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1846 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1855 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 1847 : Builtins::StoreIC_Initialize)); | 1856 : Builtins::StoreIC_Initialize)); |
| 1848 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1857 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1849 break; | 1858 break; |
| 1850 } | 1859 } |
| 1851 case KEYED_PROPERTY: { | 1860 case KEYED_PROPERTY: { |
| 1852 __ push(r0); // Preserve value. | 1861 __ push(r0); // Preserve value. |
| 1853 if (prop->is_synthetic()) { | 1862 if (prop->is_synthetic()) { |
| 1854 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 1863 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
| 1855 ASSERT(prop->key()->AsLiteral() != NULL); | 1864 ASSERT(prop->key()->AsLiteral() != NULL); |
| 1856 { AccumulatorValueContext for_object(this); | 1865 { AccumulatorValueContext for_object(this); |
| 1857 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 1866 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
| 1858 } | 1867 } |
| 1859 __ mov(r2, r0); | 1868 __ mov(r2, r0); |
| 1860 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); | 1869 __ mov(r1, Operand(prop->key()->AsLiteral()->handle())); |
| 1861 } else { | 1870 } else { |
| 1862 VisitForStackValue(prop->obj()); | 1871 VisitForStackValue(prop->obj()); |
| 1863 VisitForAccumulatorValue(prop->key()); | 1872 VisitForAccumulatorValue(prop->key()); |
| 1864 __ mov(r1, r0); | 1873 __ mov(r1, r0); |
| 1865 __ pop(r2); | 1874 __ pop(r2); |
| 1866 } | 1875 } |
| 1867 __ pop(r0); // Restore value. | 1876 __ pop(r0); // Restore value. |
| 1868 Handle<Code> ic(Builtins::builtin( | 1877 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1869 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 1878 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 1870 : Builtins::KeyedStoreIC_Initialize)); | 1879 : Builtins::KeyedStoreIC_Initialize)); |
| 1871 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1880 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1872 break; | 1881 break; |
| 1873 } | 1882 } |
| 1874 } | 1883 } |
| 1875 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1884 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
| 1876 context()->Plug(r0); | 1885 context()->Plug(r0); |
| 1877 } | 1886 } |
| 1878 | 1887 |
| 1879 | 1888 |
| 1880 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1889 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 1881 Token::Value op) { | 1890 Token::Value op) { |
| 1882 // Left-hand sides that rewrite to explicit property accesses do not reach | 1891 // Left-hand sides that rewrite to explicit property accesses do not reach |
| 1883 // here. | 1892 // here. |
| 1884 ASSERT(var != NULL); | 1893 ASSERT(var != NULL); |
| 1885 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1894 ASSERT(var->is_global() || var->AsSlot() != NULL); |
| 1886 | 1895 |
| 1887 if (var->is_global()) { | 1896 if (var->is_global()) { |
| 1888 ASSERT(!var->is_this()); | 1897 ASSERT(!var->is_this()); |
| 1889 // Assignment to a global variable. Use inline caching for the | 1898 // Assignment to a global variable. Use inline caching for the |
| 1890 // assignment. Right-hand-side value is passed in r0, variable name in | 1899 // assignment. Right-hand-side value is passed in r0, variable name in |
| 1891 // r2, and the global object in r1. | 1900 // r2, and the global object in r1. |
| 1892 __ mov(r2, Operand(var->name())); | 1901 __ mov(r2, Operand(var->name())); |
| 1893 __ ldr(r1, GlobalObjectOperand()); | 1902 __ ldr(r1, GlobalObjectOperand()); |
| 1894 Handle<Code> ic(Builtins::builtin( | 1903 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1895 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 1904 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 1896 : Builtins::StoreIC_Initialize)); | 1905 : Builtins::StoreIC_Initialize)); |
| 1897 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1906 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1898 | 1907 |
| 1899 } else if (op == Token::INIT_CONST) { | 1908 } else if (op == Token::INIT_CONST) { |
| 1900 // Like var declarations, const declarations are hoisted to function | 1909 // Like var declarations, const declarations are hoisted to function |
| 1901 // scope. However, unlike var initializers, const initializers are able | 1910 // scope. However, unlike var initializers, const initializers are able |
| 1902 // to drill a hole to that function context, even from inside a 'with' | 1911 // to drill a hole to that function context, even from inside a 'with' |
| 1903 // context. We thus bypass the normal static scope lookup. | 1912 // context. We thus bypass the normal static scope lookup. |
| 1904 Slot* slot = var->AsSlot(); | 1913 Slot* slot = var->AsSlot(); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1995 SetSourcePosition(expr->position()); | 2004 SetSourcePosition(expr->position()); |
| 1996 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 2005 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 1997 // Load receiver to r1. Leave a copy in the stack if needed for turning the | 2006 // Load receiver to r1. Leave a copy in the stack if needed for turning the |
| 1998 // receiver into fast case. | 2007 // receiver into fast case. |
| 1999 if (expr->ends_initialization_block()) { | 2008 if (expr->ends_initialization_block()) { |
| 2000 __ ldr(r1, MemOperand(sp)); | 2009 __ ldr(r1, MemOperand(sp)); |
| 2001 } else { | 2010 } else { |
| 2002 __ pop(r1); | 2011 __ pop(r1); |
| 2003 } | 2012 } |
| 2004 | 2013 |
| 2005 Handle<Code> ic(Builtins::builtin( | 2014 Handle<Code> ic(isolate()->builtins()->builtin( |
| 2006 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 2015 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 2007 : Builtins::StoreIC_Initialize)); | 2016 : Builtins::StoreIC_Initialize)); |
| 2008 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2017 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 2009 | 2018 |
| 2010 // If the assignment ends an initialization block, revert to fast case. | 2019 // If the assignment ends an initialization block, revert to fast case. |
| 2011 if (expr->ends_initialization_block()) { | 2020 if (expr->ends_initialization_block()) { |
| 2012 __ push(r0); // Result of assignment, saved even if not needed. | 2021 __ push(r0); // Result of assignment, saved even if not needed. |
| 2013 // Receiver is under the result value. | 2022 // Receiver is under the result value. |
| 2014 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2023 __ ldr(ip, MemOperand(sp, kPointerSize)); |
| 2015 __ push(ip); | 2024 __ push(ip); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2041 SetSourcePosition(expr->position()); | 2050 SetSourcePosition(expr->position()); |
| 2042 __ pop(r1); // Key. | 2051 __ pop(r1); // Key. |
| 2043 // Load receiver to r2. Leave a copy in the stack if needed for turning the | 2052 // Load receiver to r2. Leave a copy in the stack if needed for turning the |
| 2044 // receiver into fast case. | 2053 // receiver into fast case. |
| 2045 if (expr->ends_initialization_block()) { | 2054 if (expr->ends_initialization_block()) { |
| 2046 __ ldr(r2, MemOperand(sp)); | 2055 __ ldr(r2, MemOperand(sp)); |
| 2047 } else { | 2056 } else { |
| 2048 __ pop(r2); | 2057 __ pop(r2); |
| 2049 } | 2058 } |
| 2050 | 2059 |
| 2051 Handle<Code> ic(Builtins::builtin( | 2060 Handle<Code> ic(isolate()->builtins()->builtin( |
| 2052 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 2061 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 2053 : Builtins::KeyedStoreIC_Initialize)); | 2062 : Builtins::KeyedStoreIC_Initialize)); |
| 2054 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2063 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 2055 | 2064 |
| 2056 // If the assignment ends an initialization block, revert to fast case. | 2065 // If the assignment ends an initialization block, revert to fast case. |
| 2057 if (expr->ends_initialization_block()) { | 2066 if (expr->ends_initialization_block()) { |
| 2058 __ push(r0); // Result of assignment, saved even if not needed. | 2067 __ push(r0); // Result of assignment, saved even if not needed. |
| 2059 // Receiver is under the result value. | 2068 // Receiver is under the result value. |
| 2060 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2069 __ ldr(ip, MemOperand(sp, kPointerSize)); |
| 2061 __ push(ip); | 2070 __ push(ip); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2094 { PreservePositionScope scope(masm()->positions_recorder()); | 2103 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2095 for (int i = 0; i < arg_count; i++) { | 2104 for (int i = 0; i < arg_count; i++) { |
| 2096 VisitForStackValue(args->at(i)); | 2105 VisitForStackValue(args->at(i)); |
| 2097 } | 2106 } |
| 2098 __ mov(r2, Operand(name)); | 2107 __ mov(r2, Operand(name)); |
| 2099 } | 2108 } |
| 2100 // Record source position for debugger. | 2109 // Record source position for debugger. |
| 2101 SetSourcePosition(expr->position()); | 2110 SetSourcePosition(expr->position()); |
| 2102 // Call the IC initialization code. | 2111 // Call the IC initialization code. |
| 2103 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2112 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 2104 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop); | 2113 Handle<Code> ic = |
| 2114 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop); |
| 2105 EmitCallIC(ic, mode); | 2115 EmitCallIC(ic, mode); |
| 2106 RecordJSReturnSite(expr); | 2116 RecordJSReturnSite(expr); |
| 2107 // Restore context register. | 2117 // Restore context register. |
| 2108 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2118 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2109 context()->Plug(r0); | 2119 context()->Plug(r0); |
| 2110 } | 2120 } |
| 2111 | 2121 |
| 2112 | 2122 |
| 2113 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2123 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 2114 Expression* key, | 2124 Expression* key, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2127 int arg_count = args->length(); | 2137 int arg_count = args->length(); |
| 2128 { PreservePositionScope scope(masm()->positions_recorder()); | 2138 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2129 for (int i = 0; i < arg_count; i++) { | 2139 for (int i = 0; i < arg_count; i++) { |
| 2130 VisitForStackValue(args->at(i)); | 2140 VisitForStackValue(args->at(i)); |
| 2131 } | 2141 } |
| 2132 } | 2142 } |
| 2133 // Record source position for debugger. | 2143 // Record source position for debugger. |
| 2134 SetSourcePosition(expr->position()); | 2144 SetSourcePosition(expr->position()); |
| 2135 // Call the IC initialization code. | 2145 // Call the IC initialization code. |
| 2136 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2146 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 2137 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arg_count, in_loop); | 2147 Handle<Code> ic = |
| 2148 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); |
| 2138 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2149 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
| 2139 EmitCallIC(ic, mode); | 2150 EmitCallIC(ic, mode); |
| 2140 RecordJSReturnSite(expr); | 2151 RecordJSReturnSite(expr); |
| 2141 // Restore context register. | 2152 // Restore context register. |
| 2142 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2153 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2143 context()->DropAndPlug(1, r0); // Drop the key still on the stack. | 2154 context()->DropAndPlug(1, r0); // Drop the key still on the stack. |
| 2144 } | 2155 } |
| 2145 | 2156 |
| 2146 | 2157 |
| 2147 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 2158 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2326 MemOperand operand = EmitSlotSearch(slot, r1); | 2337 MemOperand operand = EmitSlotSearch(slot, r1); |
| 2327 __ ldr(r1, operand); | 2338 __ ldr(r1, operand); |
| 2328 | 2339 |
| 2329 ASSERT(prop->key()->AsLiteral() != NULL); | 2340 ASSERT(prop->key()->AsLiteral() != NULL); |
| 2330 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2341 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
| 2331 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); | 2342 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); |
| 2332 | 2343 |
| 2333 // Record source code position for IC call. | 2344 // Record source code position for IC call. |
| 2334 SetSourcePosition(prop->position()); | 2345 SetSourcePosition(prop->position()); |
| 2335 | 2346 |
| 2336 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 2347 Handle<Code> ic(isolate()->builtins()->builtin( |
| 2348 Builtins::KeyedLoadIC_Initialize)); |
| 2337 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2349 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 2338 __ ldr(r1, GlobalObjectOperand()); | 2350 __ ldr(r1, GlobalObjectOperand()); |
| 2339 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2351 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 2340 __ Push(r0, r1); // Function, receiver. | 2352 __ Push(r0, r1); // Function, receiver. |
| 2341 EmitCallWithStub(expr); | 2353 EmitCallWithStub(expr); |
| 2342 } else { | 2354 } else { |
| 2343 { PreservePositionScope scope(masm()->positions_recorder()); | 2355 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2344 VisitForStackValue(prop->obj()); | 2356 VisitForStackValue(prop->obj()); |
| 2345 } | 2357 } |
| 2346 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 2358 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
| 2347 } | 2359 } |
| 2348 } | 2360 } |
| 2349 } else { | 2361 } else { |
| 2350 // Call to some other expression. If the expression is an anonymous | 2362 // Call to some other expression. If the expression is an anonymous |
| 2351 // function literal not called in a loop, mark it as one that should | 2363 // function literal not called in a loop, mark it as one that should |
| 2352 // also use the fast code generator. | 2364 // also use the fast code generator. |
| 2353 FunctionLiteral* lit = fun->AsFunctionLiteral(); | 2365 FunctionLiteral* lit = fun->AsFunctionLiteral(); |
| 2354 if (lit != NULL && | 2366 if (lit != NULL && |
| 2355 lit->name()->Equals(Heap::empty_string()) && | 2367 lit->name()->Equals(isolate()->heap()->empty_string()) && |
| 2356 loop_depth() == 0) { | 2368 loop_depth() == 0) { |
| 2357 lit->set_try_full_codegen(true); | 2369 lit->set_try_full_codegen(true); |
| 2358 } | 2370 } |
| 2359 | 2371 |
| 2360 { PreservePositionScope scope(masm()->positions_recorder()); | 2372 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2361 VisitForStackValue(fun); | 2373 VisitForStackValue(fun); |
| 2362 } | 2374 } |
| 2363 // Load global receiver object. | 2375 // Load global receiver object. |
| 2364 __ ldr(r1, GlobalObjectOperand()); | 2376 __ ldr(r1, GlobalObjectOperand()); |
| 2365 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2377 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2394 } | 2406 } |
| 2395 | 2407 |
| 2396 // Call the construct call builtin that handles allocation and | 2408 // Call the construct call builtin that handles allocation and |
| 2397 // constructor invocation. | 2409 // constructor invocation. |
| 2398 SetSourcePosition(expr->position()); | 2410 SetSourcePosition(expr->position()); |
| 2399 | 2411 |
| 2400 // Load function and argument count into r1 and r0. | 2412 // Load function and argument count into r1 and r0. |
| 2401 __ mov(r0, Operand(arg_count)); | 2413 __ mov(r0, Operand(arg_count)); |
| 2402 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); | 2414 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
| 2403 | 2415 |
| 2404 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); | 2416 Handle<Code> construct_builtin(isolate()->builtins()->builtin( |
| 2417 Builtins::JSConstructCall)); |
| 2405 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); | 2418 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
| 2406 context()->Plug(r0); | 2419 context()->Plug(r0); |
| 2407 } | 2420 } |
| 2408 | 2421 |
| 2409 | 2422 |
| 2410 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { | 2423 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { |
| 2411 ASSERT(args->length() == 1); | 2424 ASSERT(args->length() == 1); |
| 2412 | 2425 |
| 2413 VisitForAccumulatorValue(args->at(0)); | 2426 VisitForAccumulatorValue(args->at(0)); |
| 2414 | 2427 |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2789 __ bind(&slow_allocate_heapnumber); | 2802 __ bind(&slow_allocate_heapnumber); |
| 2790 // Allocate a heap number. | 2803 // Allocate a heap number. |
| 2791 __ CallRuntime(Runtime::kNumberAlloc, 0); | 2804 __ CallRuntime(Runtime::kNumberAlloc, 0); |
| 2792 __ mov(r4, Operand(r0)); | 2805 __ mov(r4, Operand(r0)); |
| 2793 | 2806 |
| 2794 __ bind(&heapnumber_allocated); | 2807 __ bind(&heapnumber_allocated); |
| 2795 | 2808 |
| 2796 // Convert 32 random bits in r0 to 0.(32 random bits) in a double | 2809 // Convert 32 random bits in r0 to 0.(32 random bits) in a double |
| 2797 // by computing: | 2810 // by computing: |
| 2798 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). | 2811 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). |
| 2799 if (CpuFeatures::IsSupported(VFP3)) { | 2812 if (isolate()->cpu_features()->IsSupported(VFP3)) { |
| 2800 __ PrepareCallCFunction(0, r1); | 2813 __ PrepareCallCFunction(0, r1); |
| 2801 __ CallCFunction(ExternalReference::random_uint32_function(), 0); | 2814 __ CallCFunction(ExternalReference::random_uint32_function(), 0); |
| 2802 | 2815 |
| 2803 CpuFeatures::Scope scope(VFP3); | 2816 CpuFeatures::Scope scope(VFP3); |
| 2804 // 0x41300000 is the top half of 1.0 x 2^20 as a double. | 2817 // 0x41300000 is the top half of 1.0 x 2^20 as a double. |
| 2805 // Create this constant using mov/orr to avoid PC relative load. | 2818 // Create this constant using mov/orr to avoid PC relative load. |
| 2806 __ mov(r1, Operand(0x41000000)); | 2819 __ mov(r1, Operand(0x41000000)); |
| 2807 __ orr(r1, r1, Operand(0x300000)); | 2820 __ orr(r1, r1, Operand(0x300000)); |
| 2808 // Move 0x41300000xxxxxxxx (x = random bits) to VFP. | 2821 // Move 0x41300000xxxxxxxx (x = random bits) to VFP. |
| 2809 __ vmov(d7, r0, r1); | 2822 __ vmov(d7, r0, r1); |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3212 } | 3225 } |
| 3213 | 3226 |
| 3214 | 3227 |
| 3215 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { | 3228 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { |
| 3216 ASSERT_EQ(2, args->length()); | 3229 ASSERT_EQ(2, args->length()); |
| 3217 | 3230 |
| 3218 ASSERT_NE(NULL, args->at(0)->AsLiteral()); | 3231 ASSERT_NE(NULL, args->at(0)->AsLiteral()); |
| 3219 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); | 3232 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); |
| 3220 | 3233 |
| 3221 Handle<FixedArray> jsfunction_result_caches( | 3234 Handle<FixedArray> jsfunction_result_caches( |
| 3222 Top::global_context()->jsfunction_result_caches()); | 3235 isolate()->global_context()->jsfunction_result_caches()); |
| 3223 if (jsfunction_result_caches->length() <= cache_id) { | 3236 if (jsfunction_result_caches->length() <= cache_id) { |
| 3224 __ Abort("Attempt to use undefined cache."); | 3237 __ Abort("Attempt to use undefined cache."); |
| 3225 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 3238 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| 3226 context()->Plug(r0); | 3239 context()->Plug(r0); |
| 3227 return; | 3240 return; |
| 3228 } | 3241 } |
| 3229 | 3242 |
| 3230 VisitForAccumulatorValue(args->at(1)); | 3243 VisitForAccumulatorValue(args->at(1)); |
| 3231 | 3244 |
| 3232 Register key = r0; | 3245 Register key = r0; |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3591 | 3604 |
| 3592 // Push the arguments ("left-to-right"). | 3605 // Push the arguments ("left-to-right"). |
| 3593 int arg_count = args->length(); | 3606 int arg_count = args->length(); |
| 3594 for (int i = 0; i < arg_count; i++) { | 3607 for (int i = 0; i < arg_count; i++) { |
| 3595 VisitForStackValue(args->at(i)); | 3608 VisitForStackValue(args->at(i)); |
| 3596 } | 3609 } |
| 3597 | 3610 |
| 3598 if (expr->is_jsruntime()) { | 3611 if (expr->is_jsruntime()) { |
| 3599 // Call the JS runtime function. | 3612 // Call the JS runtime function. |
| 3600 __ mov(r2, Operand(expr->name())); | 3613 __ mov(r2, Operand(expr->name())); |
| 3601 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, NOT_IN_LOOP); | 3614 Handle<Code> ic = |
| 3615 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); |
| 3602 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3616 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3603 // Restore context register. | 3617 // Restore context register. |
| 3604 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3618 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3605 } else { | 3619 } else { |
| 3606 // Call the C runtime function. | 3620 // Call the C runtime function. |
| 3607 __ CallRuntime(expr->function(), arg_count); | 3621 __ CallRuntime(expr->function(), arg_count); |
| 3608 } | 3622 } |
| 3609 context()->Plug(r0); | 3623 context()->Plug(r0); |
| 3610 } | 3624 } |
| 3611 | 3625 |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3895 } else { | 3909 } else { |
| 3896 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3910 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 3897 Token::ASSIGN); | 3911 Token::ASSIGN); |
| 3898 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3912 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3899 context()->Plug(r0); | 3913 context()->Plug(r0); |
| 3900 } | 3914 } |
| 3901 break; | 3915 break; |
| 3902 case NAMED_PROPERTY: { | 3916 case NAMED_PROPERTY: { |
| 3903 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 3917 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 3904 __ pop(r1); | 3918 __ pop(r1); |
| 3905 Handle<Code> ic(Builtins::builtin( | 3919 Handle<Code> ic(isolate()->builtins()->builtin( |
| 3906 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict | 3920 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
| 3907 : Builtins::StoreIC_Initialize)); | 3921 : Builtins::StoreIC_Initialize)); |
| 3908 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3922 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3909 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3923 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3910 if (expr->is_postfix()) { | 3924 if (expr->is_postfix()) { |
| 3911 if (!context()->IsEffect()) { | 3925 if (!context()->IsEffect()) { |
| 3912 context()->PlugTOS(); | 3926 context()->PlugTOS(); |
| 3913 } | 3927 } |
| 3914 } else { | 3928 } else { |
| 3915 context()->Plug(r0); | 3929 context()->Plug(r0); |
| 3916 } | 3930 } |
| 3917 break; | 3931 break; |
| 3918 } | 3932 } |
| 3919 case KEYED_PROPERTY: { | 3933 case KEYED_PROPERTY: { |
| 3920 __ pop(r1); // Key. | 3934 __ pop(r1); // Key. |
| 3921 __ pop(r2); // Receiver. | 3935 __ pop(r2); // Receiver. |
| 3922 Handle<Code> ic(Builtins::builtin( | 3936 Handle<Code> ic(isolate()->builtins()->builtin( |
| 3923 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict | 3937 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 3924 : Builtins::KeyedStoreIC_Initialize)); | 3938 : Builtins::KeyedStoreIC_Initialize)); |
| 3925 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3939 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3926 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3940 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3927 if (expr->is_postfix()) { | 3941 if (expr->is_postfix()) { |
| 3928 if (!context()->IsEffect()) { | 3942 if (!context()->IsEffect()) { |
| 3929 context()->PlugTOS(); | 3943 context()->PlugTOS(); |
| 3930 } | 3944 } |
| 3931 } else { | 3945 } else { |
| 3932 context()->Plug(r0); | 3946 context()->Plug(r0); |
| 3933 } | 3947 } |
| 3934 break; | 3948 break; |
| 3935 } | 3949 } |
| 3936 } | 3950 } |
| 3937 } | 3951 } |
| 3938 | 3952 |
| 3939 | 3953 |
| 3940 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3954 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 3941 ASSERT(!context()->IsEffect()); | 3955 ASSERT(!context()->IsEffect()); |
| 3942 ASSERT(!context()->IsTest()); | 3956 ASSERT(!context()->IsTest()); |
| 3943 VariableProxy* proxy = expr->AsVariableProxy(); | 3957 VariableProxy* proxy = expr->AsVariableProxy(); |
| 3944 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3958 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
| 3945 Comment cmnt(masm_, "Global variable"); | 3959 Comment cmnt(masm_, "Global variable"); |
| 3946 __ ldr(r0, GlobalObjectOperand()); | 3960 __ ldr(r0, GlobalObjectOperand()); |
| 3947 __ mov(r2, Operand(proxy->name())); | 3961 __ mov(r2, Operand(proxy->name())); |
| 3948 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 3962 Handle<Code> ic(isolate()->builtins()->builtin( |
| 3963 Builtins::LoadIC_Initialize)); |
| 3949 // Use a regular load, not a contextual load, to avoid a reference | 3964 // Use a regular load, not a contextual load, to avoid a reference |
| 3950 // error. | 3965 // error. |
| 3951 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3966 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3952 PrepareForBailout(expr, TOS_REG); | 3967 PrepareForBailout(expr, TOS_REG); |
| 3953 context()->Plug(r0); | 3968 context()->Plug(r0); |
| 3954 } else if (proxy != NULL && | 3969 } else if (proxy != NULL && |
| 3955 proxy->var()->AsSlot() != NULL && | 3970 proxy->var()->AsSlot() != NULL && |
| 3956 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3971 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
| 3957 Label done, slow; | 3972 Label done, slow; |
| 3958 | 3973 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3991 if (!right_literal_value->IsString()) return false; | 4006 if (!right_literal_value->IsString()) return false; |
| 3992 UnaryOperation* left_unary = left->AsUnaryOperation(); | 4007 UnaryOperation* left_unary = left->AsUnaryOperation(); |
| 3993 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false; | 4008 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false; |
| 3994 Handle<String> check = Handle<String>::cast(right_literal_value); | 4009 Handle<String> check = Handle<String>::cast(right_literal_value); |
| 3995 | 4010 |
| 3996 { AccumulatorValueContext context(this); | 4011 { AccumulatorValueContext context(this); |
| 3997 VisitForTypeofValue(left_unary->expression()); | 4012 VisitForTypeofValue(left_unary->expression()); |
| 3998 } | 4013 } |
| 3999 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4014 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
| 4000 | 4015 |
| 4001 if (check->Equals(Heap::number_symbol())) { | 4016 if (check->Equals(isolate()->heap()->number_symbol())) { |
| 4002 __ JumpIfSmi(r0, if_true); | 4017 __ JumpIfSmi(r0, if_true); |
| 4003 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); | 4018 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 4004 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 4019 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
| 4005 __ cmp(r0, ip); | 4020 __ cmp(r0, ip); |
| 4006 Split(eq, if_true, if_false, fall_through); | 4021 Split(eq, if_true, if_false, fall_through); |
| 4007 } else if (check->Equals(Heap::string_symbol())) { | 4022 } else if (check->Equals(isolate()->heap()->string_symbol())) { |
| 4008 __ JumpIfSmi(r0, if_false); | 4023 __ JumpIfSmi(r0, if_false); |
| 4009 // Check for undetectable objects => false. | 4024 // Check for undetectable objects => false. |
| 4010 __ CompareObjectType(r0, r0, r1, FIRST_NONSTRING_TYPE); | 4025 __ CompareObjectType(r0, r0, r1, FIRST_NONSTRING_TYPE); |
| 4011 __ b(ge, if_false); | 4026 __ b(ge, if_false); |
| 4012 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); | 4027 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); |
| 4013 __ tst(r1, Operand(1 << Map::kIsUndetectable)); | 4028 __ tst(r1, Operand(1 << Map::kIsUndetectable)); |
| 4014 Split(eq, if_true, if_false, fall_through); | 4029 Split(eq, if_true, if_false, fall_through); |
| 4015 } else if (check->Equals(Heap::boolean_symbol())) { | 4030 } else if (check->Equals(isolate()->heap()->boolean_symbol())) { |
| 4016 __ CompareRoot(r0, Heap::kTrueValueRootIndex); | 4031 __ CompareRoot(r0, Heap::kTrueValueRootIndex); |
| 4017 __ b(eq, if_true); | 4032 __ b(eq, if_true); |
| 4018 __ CompareRoot(r0, Heap::kFalseValueRootIndex); | 4033 __ CompareRoot(r0, Heap::kFalseValueRootIndex); |
| 4019 Split(eq, if_true, if_false, fall_through); | 4034 Split(eq, if_true, if_false, fall_through); |
| 4020 } else if (check->Equals(Heap::undefined_symbol())) { | 4035 } else if (check->Equals(isolate()->heap()->undefined_symbol())) { |
| 4021 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); | 4036 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); |
| 4022 __ b(eq, if_true); | 4037 __ b(eq, if_true); |
| 4023 __ JumpIfSmi(r0, if_false); | 4038 __ JumpIfSmi(r0, if_false); |
| 4024 // Check for undetectable objects => true. | 4039 // Check for undetectable objects => true. |
| 4025 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); | 4040 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 4026 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); | 4041 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); |
| 4027 __ tst(r1, Operand(1 << Map::kIsUndetectable)); | 4042 __ tst(r1, Operand(1 << Map::kIsUndetectable)); |
| 4028 Split(ne, if_true, if_false, fall_through); | 4043 Split(ne, if_true, if_false, fall_through); |
| 4029 | 4044 |
| 4030 } else if (check->Equals(Heap::function_symbol())) { | 4045 } else if (check->Equals(isolate()->heap()->function_symbol())) { |
| 4031 __ JumpIfSmi(r0, if_false); | 4046 __ JumpIfSmi(r0, if_false); |
| 4032 __ CompareObjectType(r0, r1, r0, FIRST_FUNCTION_CLASS_TYPE); | 4047 __ CompareObjectType(r0, r1, r0, FIRST_FUNCTION_CLASS_TYPE); |
| 4033 Split(ge, if_true, if_false, fall_through); | 4048 Split(ge, if_true, if_false, fall_through); |
| 4034 | 4049 |
| 4035 } else if (check->Equals(Heap::object_symbol())) { | 4050 } else if (check->Equals(isolate()->heap()->object_symbol())) { |
| 4036 __ JumpIfSmi(r0, if_false); | 4051 __ JumpIfSmi(r0, if_false); |
| 4037 __ CompareRoot(r0, Heap::kNullValueRootIndex); | 4052 __ CompareRoot(r0, Heap::kNullValueRootIndex); |
| 4038 __ b(eq, if_true); | 4053 __ b(eq, if_true); |
| 4039 // Check for JS objects => true. | 4054 // Check for JS objects => true. |
| 4040 __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE); | 4055 __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE); |
| 4041 __ b(lo, if_false); | 4056 __ b(lo, if_false); |
| 4042 __ CompareInstanceType(r0, r1, FIRST_FUNCTION_CLASS_TYPE); | 4057 __ CompareInstanceType(r0, r1, FIRST_FUNCTION_CLASS_TYPE); |
| 4043 __ b(hs, if_false); | 4058 __ b(hs, if_false); |
| 4044 // Check for undetectable objects => false. | 4059 // Check for undetectable objects => false. |
| 4045 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); | 4060 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4211 Register FullCodeGenerator::context_register() { | 4226 Register FullCodeGenerator::context_register() { |
| 4212 return cp; | 4227 return cp; |
| 4213 } | 4228 } |
| 4214 | 4229 |
| 4215 | 4230 |
| 4216 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { | 4231 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { |
| 4217 ASSERT(mode == RelocInfo::CODE_TARGET || | 4232 ASSERT(mode == RelocInfo::CODE_TARGET || |
| 4218 mode == RelocInfo::CODE_TARGET_CONTEXT); | 4233 mode == RelocInfo::CODE_TARGET_CONTEXT); |
| 4219 switch (ic->kind()) { | 4234 switch (ic->kind()) { |
| 4220 case Code::LOAD_IC: | 4235 case Code::LOAD_IC: |
| 4221 __ IncrementCounter(&Counters::named_load_full, 1, r1, r2); | 4236 __ IncrementCounter(COUNTERS->named_load_full(), 1, r1, r2); |
| 4222 break; | 4237 break; |
| 4223 case Code::KEYED_LOAD_IC: | 4238 case Code::KEYED_LOAD_IC: |
| 4224 __ IncrementCounter(&Counters::keyed_load_full, 1, r1, r2); | 4239 __ IncrementCounter(COUNTERS->keyed_load_full(), 1, r1, r2); |
| 4225 break; | 4240 break; |
| 4226 case Code::STORE_IC: | 4241 case Code::STORE_IC: |
| 4227 __ IncrementCounter(&Counters::named_store_full, 1, r1, r2); | 4242 __ IncrementCounter(COUNTERS->named_store_full(), 1, r1, r2); |
| 4228 break; | 4243 break; |
| 4229 case Code::KEYED_STORE_IC: | 4244 case Code::KEYED_STORE_IC: |
| 4230 __ IncrementCounter(&Counters::keyed_store_full, 1, r1, r2); | 4245 __ IncrementCounter(COUNTERS->keyed_store_full(), 1, r1, r2); |
| 4231 default: | 4246 default: |
| 4232 break; | 4247 break; |
| 4233 } | 4248 } |
| 4234 | 4249 |
| 4235 __ Call(ic, mode); | 4250 __ Call(ic, mode); |
| 4236 } | 4251 } |
| 4237 | 4252 |
| 4238 | 4253 |
| 4239 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { | 4254 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { |
| 4240 switch (ic->kind()) { | 4255 switch (ic->kind()) { |
| 4241 case Code::LOAD_IC: | 4256 case Code::LOAD_IC: |
| 4242 __ IncrementCounter(&Counters::named_load_full, 1, r1, r2); | 4257 __ IncrementCounter(COUNTERS->named_load_full(), 1, r1, r2); |
| 4243 break; | 4258 break; |
| 4244 case Code::KEYED_LOAD_IC: | 4259 case Code::KEYED_LOAD_IC: |
| 4245 __ IncrementCounter(&Counters::keyed_load_full, 1, r1, r2); | 4260 __ IncrementCounter(COUNTERS->keyed_load_full(), 1, r1, r2); |
| 4246 break; | 4261 break; |
| 4247 case Code::STORE_IC: | 4262 case Code::STORE_IC: |
| 4248 __ IncrementCounter(&Counters::named_store_full, 1, r1, r2); | 4263 __ IncrementCounter(COUNTERS->named_store_full(), 1, r1, r2); |
| 4249 break; | 4264 break; |
| 4250 case Code::KEYED_STORE_IC: | 4265 case Code::KEYED_STORE_IC: |
| 4251 __ IncrementCounter(&Counters::keyed_store_full, 1, r1, r2); | 4266 __ IncrementCounter(COUNTERS->keyed_store_full(), 1, r1, r2); |
| 4252 default: | 4267 default: |
| 4253 break; | 4268 break; |
| 4254 } | 4269 } |
| 4255 | 4270 |
| 4256 __ Call(ic, RelocInfo::CODE_TARGET); | 4271 __ Call(ic, RelocInfo::CODE_TARGET); |
| 4257 if (patch_site != NULL && patch_site->is_bound()) { | 4272 if (patch_site != NULL && patch_site->is_bound()) { |
| 4258 patch_site->EmitPatchInfo(); | 4273 patch_site->EmitPatchInfo(); |
| 4259 } else { | 4274 } else { |
| 4260 __ nop(); // Signals no inlined code. | 4275 __ nop(); // Signals no inlined code. |
| 4261 } | 4276 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4299 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 4314 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
| 4300 __ add(pc, r1, Operand(masm_->CodeObject())); | 4315 __ add(pc, r1, Operand(masm_->CodeObject())); |
| 4301 } | 4316 } |
| 4302 | 4317 |
| 4303 | 4318 |
| 4304 #undef __ | 4319 #undef __ |
| 4305 | 4320 |
| 4306 } } // namespace v8::internal | 4321 } } // namespace v8::internal |
| 4307 | 4322 |
| 4308 #endif // V8_TARGET_ARCH_ARM | 4323 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |