| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 __ eor(result_reg, result_reg, Operand(scratch_high, ASR, 31)); | 686 __ eor(result_reg, result_reg, Operand(scratch_high, ASR, 31)); |
| 687 __ add(result_reg, result_reg, Operand(scratch_high, LSR, 31)); | 687 __ add(result_reg, result_reg, Operand(scratch_high, LSR, 31)); |
| 688 | 688 |
| 689 __ bind(&done); | 689 __ bind(&done); |
| 690 | 690 |
| 691 __ Pop(scratch_high, scratch_low); | 691 __ Pop(scratch_high, scratch_low); |
| 692 __ Ret(); | 692 __ Ret(); |
| 693 } | 693 } |
| 694 | 694 |
| 695 | 695 |
| 696 bool WriteInt32ToHeapNumberStub::IsPregenerated(Isolate* isolate) { | |
| 697 // These variants are compiled ahead of time. See next method. | |
| 698 if (the_int_.is(r1) && the_heap_number_.is(r0) && scratch_.is(r2)) { | |
| 699 return true; | |
| 700 } | |
| 701 if (the_int_.is(r2) && the_heap_number_.is(r0) && scratch_.is(r3)) { | |
| 702 return true; | |
| 703 } | |
| 704 // Other register combinations are generated as and when they are needed, | |
| 705 // so it is unsafe to call them from stubs (we can't generate a stub while | |
| 706 // we are generating a stub). | |
| 707 return false; | |
| 708 } | |
| 709 | |
| 710 | |
| 711 void WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime( | 696 void WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime( |
| 712 Isolate* isolate) { | 697 Isolate* isolate) { |
| 713 WriteInt32ToHeapNumberStub stub1(r1, r0, r2); | 698 WriteInt32ToHeapNumberStub stub1(r1, r0, r2); |
| 714 WriteInt32ToHeapNumberStub stub2(r2, r0, r3); | 699 WriteInt32ToHeapNumberStub stub2(r2, r0, r3); |
| 715 stub1.GetCode(isolate)->set_is_pregenerated(true); | 700 stub1.GetCode(isolate)->set_is_pregenerated(true); |
| 716 stub2.GetCode(isolate)->set_is_pregenerated(true); | 701 stub2.GetCode(isolate)->set_is_pregenerated(true); |
| 717 } | 702 } |
| 718 | 703 |
| 719 | 704 |
| 720 // See comment for class. | 705 // See comment for class. |
| (...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1667 __ Ret(); | 1652 __ Ret(); |
| 1668 } | 1653 } |
| 1669 } | 1654 } |
| 1670 | 1655 |
| 1671 | 1656 |
| 1672 bool CEntryStub::NeedsImmovableCode() { | 1657 bool CEntryStub::NeedsImmovableCode() { |
| 1673 return true; | 1658 return true; |
| 1674 } | 1659 } |
| 1675 | 1660 |
| 1676 | 1661 |
| 1677 bool CEntryStub::IsPregenerated(Isolate* isolate) { | |
| 1678 return (!save_doubles_ || isolate->fp_stubs_generated()) && | |
| 1679 result_size_ == 1; | |
| 1680 } | |
| 1681 | |
| 1682 | |
| 1683 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { | 1662 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { |
| 1684 CEntryStub::GenerateAheadOfTime(isolate); | 1663 CEntryStub::GenerateAheadOfTime(isolate); |
| 1685 WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate); | 1664 WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate); |
| 1686 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); | 1665 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); |
| 1687 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); | 1666 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); |
| 1688 RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate); | |
| 1689 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); | 1667 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); |
| 1690 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); | 1668 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); |
| 1691 BinaryOpStub::GenerateAheadOfTime(isolate); | 1669 BinaryOpStub::GenerateAheadOfTime(isolate); |
| 1692 } | 1670 } |
| 1693 | 1671 |
| 1694 | 1672 |
| 1695 void CodeStub::GenerateFPStubs(Isolate* isolate) { | 1673 void CodeStub::GenerateFPStubs(Isolate* isolate) { |
| 1696 SaveFPRegsMode mode = kSaveFPRegs; | 1674 SaveFPRegsMode mode = kSaveFPRegs; |
| 1697 CEntryStub save_doubles(1, mode); | 1675 CEntryStub save_doubles(1, mode); |
| 1698 StoreBufferOverflowStub stub(mode); | 1676 StoreBufferOverflowStub stub(mode); |
| (...skipping 3641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5340 __ bind(&in_dictionary); | 5318 __ bind(&in_dictionary); |
| 5341 __ mov(result, Operand(1)); | 5319 __ mov(result, Operand(1)); |
| 5342 __ Ret(); | 5320 __ Ret(); |
| 5343 | 5321 |
| 5344 __ bind(¬_in_dictionary); | 5322 __ bind(¬_in_dictionary); |
| 5345 __ mov(result, Operand::Zero()); | 5323 __ mov(result, Operand::Zero()); |
| 5346 __ Ret(); | 5324 __ Ret(); |
| 5347 } | 5325 } |
| 5348 | 5326 |
| 5349 | 5327 |
| 5350 struct AheadOfTimeWriteBarrierStubList { | |
| 5351 Register object, value, address; | |
| 5352 RememberedSetAction action; | |
| 5353 }; | |
| 5354 | |
| 5355 | |
| 5356 #define REG(Name) { kRegister_ ## Name ## _Code } | |
| 5357 | |
| 5358 static const AheadOfTimeWriteBarrierStubList kAheadOfTime[] = { | |
| 5359 // Used in RegExpExecStub. | |
| 5360 { REG(r6), REG(r4), REG(r3), EMIT_REMEMBERED_SET }, | |
| 5361 // Used in CompileArrayPushCall. | |
| 5362 // Also used in StoreIC::GenerateNormal via GenerateDictionaryStore. | |
| 5363 // Also used in KeyedStoreIC::GenerateGeneric. | |
| 5364 { REG(r3), REG(r4), REG(r5), EMIT_REMEMBERED_SET }, | |
| 5365 // Used in StoreStubCompiler::CompileStoreField via GenerateStoreField. | |
| 5366 { REG(r1), REG(r2), REG(r3), EMIT_REMEMBERED_SET }, | |
| 5367 { REG(r3), REG(r2), REG(r1), EMIT_REMEMBERED_SET }, | |
| 5368 // Used in KeyedStoreStubCompiler::CompileStoreField via GenerateStoreField. | |
| 5369 { REG(r2), REG(r1), REG(r3), EMIT_REMEMBERED_SET }, | |
| 5370 { REG(r3), REG(r1), REG(r2), EMIT_REMEMBERED_SET }, | |
| 5371 // KeyedStoreStubCompiler::GenerateStoreFastElement. | |
| 5372 { REG(r3), REG(r2), REG(r4), EMIT_REMEMBERED_SET }, | |
| 5373 { REG(r2), REG(r3), REG(r4), EMIT_REMEMBERED_SET }, | |
| 5374 // ElementsTransitionGenerator::GenerateMapChangeElementTransition | |
| 5375 // and ElementsTransitionGenerator::GenerateSmiToDouble | |
| 5376 // and ElementsTransitionGenerator::GenerateDoubleToObject | |
| 5377 { REG(r2), REG(r3), REG(r9), EMIT_REMEMBERED_SET }, | |
| 5378 { REG(r2), REG(r3), REG(r9), OMIT_REMEMBERED_SET }, | |
| 5379 // ElementsTransitionGenerator::GenerateDoubleToObject | |
| 5380 { REG(r6), REG(r2), REG(r0), EMIT_REMEMBERED_SET }, | |
| 5381 { REG(r2), REG(r6), REG(r9), EMIT_REMEMBERED_SET }, | |
| 5382 // StoreArrayLiteralElementStub::Generate | |
| 5383 { REG(r5), REG(r0), REG(r6), EMIT_REMEMBERED_SET }, | |
| 5384 // FastNewClosureStub::Generate | |
| 5385 { REG(r2), REG(r4), REG(r1), EMIT_REMEMBERED_SET }, | |
| 5386 // StringAddStub::Generate | |
| 5387 { REG(r3), REG(r1), REG(r4), EMIT_REMEMBERED_SET }, | |
| 5388 { REG(r3), REG(r0), REG(r4), EMIT_REMEMBERED_SET }, | |
| 5389 // Null termination. | |
| 5390 { REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET} | |
| 5391 }; | |
| 5392 | |
| 5393 #undef REG | |
| 5394 | |
| 5395 | |
| 5396 bool RecordWriteStub::IsPregenerated(Isolate* isolate) { | |
| 5397 for (const AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; | |
| 5398 !entry->object.is(no_reg); | |
| 5399 entry++) { | |
| 5400 if (object_.is(entry->object) && | |
| 5401 value_.is(entry->value) && | |
| 5402 address_.is(entry->address) && | |
| 5403 remembered_set_action_ == entry->action && | |
| 5404 save_fp_regs_mode_ == kDontSaveFPRegs) { | |
| 5405 return true; | |
| 5406 } | |
| 5407 } | |
| 5408 return false; | |
| 5409 } | |
| 5410 | |
| 5411 | |
| 5412 void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime( | 5328 void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime( |
| 5413 Isolate* isolate) { | 5329 Isolate* isolate) { |
| 5414 StoreBufferOverflowStub stub1(kDontSaveFPRegs); | 5330 StoreBufferOverflowStub stub1(kDontSaveFPRegs); |
| 5415 stub1.GetCode(isolate)->set_is_pregenerated(true); | 5331 stub1.GetCode(isolate)->set_is_pregenerated(true); |
| 5416 // Hydrogen code stubs need stub2 at snapshot time. | 5332 // Hydrogen code stubs need stub2 at snapshot time. |
| 5417 StoreBufferOverflowStub stub2(kSaveFPRegs); | 5333 StoreBufferOverflowStub stub2(kSaveFPRegs); |
| 5418 stub2.GetCode(isolate)->set_is_pregenerated(true); | 5334 stub2.GetCode(isolate)->set_is_pregenerated(true); |
| 5419 } | 5335 } |
| 5420 | 5336 |
| 5421 | 5337 |
| 5422 void RecordWriteStub::GenerateFixedRegStubsAheadOfTime(Isolate* isolate) { | |
| 5423 for (const AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; | |
| 5424 !entry->object.is(no_reg); | |
| 5425 entry++) { | |
| 5426 RecordWriteStub stub(entry->object, | |
| 5427 entry->value, | |
| 5428 entry->address, | |
| 5429 entry->action, | |
| 5430 kDontSaveFPRegs); | |
| 5431 stub.GetCode(isolate)->set_is_pregenerated(true); | |
| 5432 } | |
| 5433 } | |
| 5434 | |
| 5435 | |
| 5436 bool CodeStub::CanUseFPRegisters() { | 5338 bool CodeStub::CanUseFPRegisters() { |
| 5437 return true; // VFP2 is a base requirement for V8 | 5339 return true; // VFP2 is a base requirement for V8 |
| 5438 } | 5340 } |
| 5439 | 5341 |
| 5440 | 5342 |
| 5441 // Takes the input in 3 registers: address_ value_ and object_. A pointer to | 5343 // Takes the input in 3 registers: address_ value_ and object_. A pointer to |
| 5442 // the value has just been written into the object, now this stub makes sure | 5344 // the value has just been written into the object, now this stub makes sure |
| 5443 // we keep the GC informed. The word in the object where the value has been | 5345 // we keep the GC informed. The word in the object where the value has been |
| 5444 // written is in the address register. | 5346 // written is in the address register. |
| 5445 void RecordWriteStub::Generate(MacroAssembler* masm) { | 5347 void RecordWriteStub::Generate(MacroAssembler* masm) { |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5731 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | 5633 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); |
| 5732 ParameterCount argument_count(r0); | 5634 ParameterCount argument_count(r0); |
| 5733 __ InvokeFunction( | 5635 __ InvokeFunction( |
| 5734 r1, argument_count, JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 5636 r1, argument_count, JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 5735 } | 5637 } |
| 5736 | 5638 |
| 5737 | 5639 |
| 5738 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { | 5640 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { |
| 5739 if (masm->isolate()->function_entry_hook() != NULL) { | 5641 if (masm->isolate()->function_entry_hook() != NULL) { |
| 5740 PredictableCodeSizeScope predictable(masm, 4 * Assembler::kInstrSize); | 5642 PredictableCodeSizeScope predictable(masm, 4 * Assembler::kInstrSize); |
| 5741 AllowStubCallsScope allow_stub_calls(masm, true); | |
| 5742 ProfileEntryHookStub stub; | 5643 ProfileEntryHookStub stub; |
| 5743 __ push(lr); | 5644 __ push(lr); |
| 5744 __ CallStub(&stub); | 5645 __ CallStub(&stub); |
| 5745 __ pop(lr); | 5646 __ pop(lr); |
| 5746 } | 5647 } |
| 5747 } | 5648 } |
| 5748 | 5649 |
| 5749 | 5650 |
| 5750 void ProfileEntryHookStub::Generate(MacroAssembler* masm) { | 5651 void ProfileEntryHookStub::Generate(MacroAssembler* masm) { |
| 5751 // The entry hook is a "push lr" instruction, followed by a call. | 5652 // The entry hook is a "push lr" instruction, followed by a call. |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6132 __ bind(&fast_elements_case); | 6033 __ bind(&fast_elements_case); |
| 6133 GenerateCase(masm, FAST_ELEMENTS); | 6034 GenerateCase(masm, FAST_ELEMENTS); |
| 6134 } | 6035 } |
| 6135 | 6036 |
| 6136 | 6037 |
| 6137 #undef __ | 6038 #undef __ |
| 6138 | 6039 |
| 6139 } } // namespace v8::internal | 6040 } } // namespace v8::internal |
| 6140 | 6041 |
| 6141 #endif // V8_TARGET_ARCH_ARM | 6042 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |