Index: src/a64/code-stubs-a64.h |
diff --git a/src/a64/code-stubs-a64.h b/src/a64/code-stubs-a64.h |
deleted file mode 100644 |
index 6e79fb9bd4dd8c7fc3941822db3489c2b09ec099..0000000000000000000000000000000000000000 |
--- a/src/a64/code-stubs-a64.h |
+++ /dev/null |
@@ -1,469 +0,0 @@ |
-// Copyright 2013 the V8 project authors. All rights reserved. |
-// Redistribution and use in source and binary forms, with or without |
-// modification, are permitted provided that the following conditions are |
-// met: |
-// |
-// * Redistributions of source code must retain the above copyright |
-// notice, this list of conditions and the following disclaimer. |
-// * Redistributions in binary form must reproduce the above |
-// copyright notice, this list of conditions and the following |
-// disclaimer in the documentation and/or other materials provided |
-// with the distribution. |
-// * Neither the name of Google Inc. nor the names of its |
-// contributors may be used to endorse or promote products derived |
-// from this software without specific prior written permission. |
-// |
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
- |
-#ifndef V8_A64_CODE_STUBS_A64_H_ |
-#define V8_A64_CODE_STUBS_A64_H_ |
- |
-#include "ic-inl.h" |
- |
-namespace v8 { |
-namespace internal { |
- |
- |
-void ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code); |
- |
- |
-class StoreBufferOverflowStub: public PlatformCodeStub { |
- public: |
- explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp) |
- : save_doubles_(save_fp) { } |
- |
- void Generate(MacroAssembler* masm); |
- |
- static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate); |
- virtual bool SometimesSetsUpAFrame() { return false; } |
- |
- private: |
- SaveFPRegsMode save_doubles_; |
- |
- Major MajorKey() { return StoreBufferOverflow; } |
- int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; } |
-}; |
- |
- |
-class StringHelper : public AllStatic { |
- public: |
- // TODO(all): These don't seem to be used any more. Delete them. |
- |
- // Generate string hash. |
- static void GenerateHashInit(MacroAssembler* masm, |
- Register hash, |
- Register character); |
- |
- static void GenerateHashAddCharacter(MacroAssembler* masm, |
- Register hash, |
- Register character); |
- |
- static void GenerateHashGetHash(MacroAssembler* masm, |
- Register hash, |
- Register scratch); |
- |
- private: |
- DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper); |
-}; |
- |
- |
-class RecordWriteStub: public PlatformCodeStub { |
- public: |
- // Stub to record the write of 'value' at 'address' in 'object'. |
- // Typically 'address' = 'object' + <some offset>. |
- // See MacroAssembler::RecordWriteField() for example. |
- RecordWriteStub(Register object, |
- Register value, |
- Register address, |
- RememberedSetAction remembered_set_action, |
- SaveFPRegsMode fp_mode) |
- : object_(object), |
- value_(value), |
- address_(address), |
- remembered_set_action_(remembered_set_action), |
- save_fp_regs_mode_(fp_mode), |
- regs_(object, // An input reg. |
- address, // An input reg. |
- value) { // One scratch reg. |
- } |
- |
- enum Mode { |
- STORE_BUFFER_ONLY, |
- INCREMENTAL, |
- INCREMENTAL_COMPACTION |
- }; |
- |
- virtual bool SometimesSetsUpAFrame() { return false; } |
- |
- static Mode GetMode(Code* stub) { |
- // Find the mode depending on the first two instructions. |
- Instruction* instr1 = |
- reinterpret_cast<Instruction*>(stub->instruction_start()); |
- Instruction* instr2 = instr1->following(); |
- |
- if (instr1->IsUncondBranchImm()) { |
- ASSERT(instr2->IsPCRelAddressing() && (instr2->Rd() == xzr.code())); |
- return INCREMENTAL; |
- } |
- |
- ASSERT(instr1->IsPCRelAddressing() && (instr1->Rd() == xzr.code())); |
- |
- if (instr2->IsUncondBranchImm()) { |
- return INCREMENTAL_COMPACTION; |
- } |
- |
- ASSERT(instr2->IsPCRelAddressing()); |
- |
- return STORE_BUFFER_ONLY; |
- } |
- |
- // We patch the two first instructions of the stub back and forth between an |
- // adr and branch when we start and stop incremental heap marking. |
- // The branch is |
- // b label |
- // The adr is |
- // adr xzr label |
- // so effectively a nop. |
- static void Patch(Code* stub, Mode mode) { |
- // We are going to patch the two first instructions of the stub. |
- PatchingAssembler patcher( |
- reinterpret_cast<Instruction*>(stub->instruction_start()), 2); |
- Instruction* instr1 = patcher.InstructionAt(0); |
- Instruction* instr2 = patcher.InstructionAt(kInstructionSize); |
- // Instructions must be either 'adr' or 'b'. |
- ASSERT(instr1->IsPCRelAddressing() || instr1->IsUncondBranchImm()); |
- ASSERT(instr2->IsPCRelAddressing() || instr2->IsUncondBranchImm()); |
- // Retrieve the offsets to the labels. |
- int32_t offset_to_incremental_noncompacting = instr1->ImmPCOffset(); |
- int32_t offset_to_incremental_compacting = instr2->ImmPCOffset(); |
- |
- switch (mode) { |
- case STORE_BUFFER_ONLY: |
- ASSERT(GetMode(stub) == INCREMENTAL || |
- GetMode(stub) == INCREMENTAL_COMPACTION); |
- patcher.adr(xzr, offset_to_incremental_noncompacting); |
- patcher.adr(xzr, offset_to_incremental_compacting); |
- break; |
- case INCREMENTAL: |
- ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); |
- patcher.b(offset_to_incremental_noncompacting >> kInstructionSizeLog2); |
- patcher.adr(xzr, offset_to_incremental_compacting); |
- break; |
- case INCREMENTAL_COMPACTION: |
- ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); |
- patcher.adr(xzr, offset_to_incremental_noncompacting); |
- patcher.b(offset_to_incremental_compacting >> kInstructionSizeLog2); |
- break; |
- } |
- ASSERT(GetMode(stub) == mode); |
- } |
- |
- private: |
- // This is a helper class to manage the registers associated with the stub. |
- // The 'object' and 'address' registers must be preserved. |
- class RegisterAllocation { |
- public: |
- RegisterAllocation(Register object, |
- Register address, |
- Register scratch) |
- : object_(object), |
- address_(address), |
- scratch0_(scratch), |
- saved_regs_(kCallerSaved) { |
- ASSERT(!AreAliased(scratch, object, address)); |
- |
- // We would like to require more scratch registers for this stub, |
- // but the number of registers comes down to the ones used in |
- // FullCodeGen::SetVar(), which is architecture independent. |
- // We allocate 2 extra scratch registers that we'll save on the stack. |
- CPURegList pool_available = GetValidRegistersForAllocation(); |
- CPURegList used_regs(object, address, scratch); |
- pool_available.Remove(used_regs); |
- scratch1_ = Register(pool_available.PopLowestIndex()); |
- scratch2_ = Register(pool_available.PopLowestIndex()); |
- |
- // SaveCallerRegisters method needs to save caller saved register, however |
- // we don't bother saving ip0 and ip1 because they are used as scratch |
- // registers by the MacroAssembler. |
- saved_regs_.Remove(ip0); |
- saved_regs_.Remove(ip1); |
- |
- // The scratch registers will be restored by other means so we don't need |
- // to save them with the other caller saved registers. |
- saved_regs_.Remove(scratch0_); |
- saved_regs_.Remove(scratch1_); |
- saved_regs_.Remove(scratch2_); |
- } |
- |
- void Save(MacroAssembler* masm) { |
- // We don't have to save scratch0_ because it was given to us as |
- // a scratch register. |
- masm->Push(scratch1_, scratch2_); |
- } |
- |
- void Restore(MacroAssembler* masm) { |
- masm->Pop(scratch2_, scratch1_); |
- } |
- |
- // If we have to call into C then we need to save and restore all caller- |
- // saved registers that were not already preserved. |
- void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { |
- // TODO(all): This can be very expensive, and it is likely that not every |
- // register will need to be preserved. Can we improve this? |
- masm->PushCPURegList(saved_regs_); |
- if (mode == kSaveFPRegs) { |
- masm->PushCPURegList(kCallerSavedFP); |
- } |
- } |
- |
- void RestoreCallerSaveRegisters(MacroAssembler*masm, SaveFPRegsMode mode) { |
- // TODO(all): This can be very expensive, and it is likely that not every |
- // register will need to be preserved. Can we improve this? |
- if (mode == kSaveFPRegs) { |
- masm->PopCPURegList(kCallerSavedFP); |
- } |
- masm->PopCPURegList(saved_regs_); |
- } |
- |
- Register object() { return object_; } |
- Register address() { return address_; } |
- Register scratch0() { return scratch0_; } |
- Register scratch1() { return scratch1_; } |
- Register scratch2() { return scratch2_; } |
- |
- private: |
- Register object_; |
- Register address_; |
- Register scratch0_; |
- Register scratch1_; |
- Register scratch2_; |
- CPURegList saved_regs_; |
- |
- // TODO(all): We should consider moving this somewhere else. |
- static CPURegList GetValidRegistersForAllocation() { |
- // The list of valid registers for allocation is defined as all the |
- // registers without those with a special meaning. |
- // |
- // The default list excludes registers x26 to x31 because they are |
- // reserved for the following purpose: |
- // - x26 root register |
- // - x27 context pointer register |
- // - x28 jssp |
- // - x29 frame pointer |
- // - x30 link register(lr) |
- // - x31 xzr/stack pointer |
- CPURegList list(CPURegister::kRegister, kXRegSizeInBits, 0, 25); |
- |
- // We also remove MacroAssembler's scratch registers. |
- list.Remove(ip0); |
- list.Remove(ip1); |
- list.Remove(x8); |
- list.Remove(x9); |
- |
- return list; |
- } |
- |
- friend class RecordWriteStub; |
- }; |
- |
- // A list of stub variants which are pregenerated. |
- // The variants are stored in the same format as the minor key, so |
- // MinorKeyFor() can be used to populate and check this list. |
- static const int kAheadOfTime[]; |
- |
- void Generate(MacroAssembler* masm); |
- void GenerateIncremental(MacroAssembler* masm, Mode mode); |
- |
- enum OnNoNeedToInformIncrementalMarker { |
- kReturnOnNoNeedToInformIncrementalMarker, |
- kUpdateRememberedSetOnNoNeedToInformIncrementalMarker |
- }; |
- |
- void CheckNeedsToInformIncrementalMarker( |
- MacroAssembler* masm, |
- OnNoNeedToInformIncrementalMarker on_no_need, |
- Mode mode); |
- void InformIncrementalMarker(MacroAssembler* masm); |
- |
- Major MajorKey() { return RecordWrite; } |
- |
- int MinorKey() { |
- return MinorKeyFor(object_, value_, address_, remembered_set_action_, |
- save_fp_regs_mode_); |
- } |
- |
- static int MinorKeyFor(Register object, |
- Register value, |
- Register address, |
- RememberedSetAction action, |
- SaveFPRegsMode fp_mode) { |
- ASSERT(object.Is64Bits()); |
- ASSERT(value.Is64Bits()); |
- ASSERT(address.Is64Bits()); |
- return ObjectBits::encode(object.code()) | |
- ValueBits::encode(value.code()) | |
- AddressBits::encode(address.code()) | |
- RememberedSetActionBits::encode(action) | |
- SaveFPRegsModeBits::encode(fp_mode); |
- } |
- |
- void Activate(Code* code) { |
- code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code); |
- } |
- |
- class ObjectBits: public BitField<int, 0, 5> {}; |
- class ValueBits: public BitField<int, 5, 5> {}; |
- class AddressBits: public BitField<int, 10, 5> {}; |
- class RememberedSetActionBits: public BitField<RememberedSetAction, 15, 1> {}; |
- class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 16, 1> {}; |
- |
- Register object_; |
- Register value_; |
- Register address_; |
- RememberedSetAction remembered_set_action_; |
- SaveFPRegsMode save_fp_regs_mode_; |
- Label slow_; |
- RegisterAllocation regs_; |
-}; |
- |
- |
-// Helper to call C++ functions from generated code. The caller must prepare |
-// the exit frame before doing the call with GenerateCall. |
-class DirectCEntryStub: public PlatformCodeStub { |
- public: |
- DirectCEntryStub() {} |
- void Generate(MacroAssembler* masm); |
- void GenerateCall(MacroAssembler* masm, Register target); |
- |
- private: |
- Major MajorKey() { return DirectCEntry; } |
- int MinorKey() { return 0; } |
- |
- bool NeedsImmovableCode() { return true; } |
-}; |
- |
- |
-class NameDictionaryLookupStub: public PlatformCodeStub { |
- public: |
- enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; |
- |
- explicit NameDictionaryLookupStub(LookupMode mode) : mode_(mode) { } |
- |
- void Generate(MacroAssembler* masm); |
- |
- static void GenerateNegativeLookup(MacroAssembler* masm, |
- Label* miss, |
- Label* done, |
- Register receiver, |
- Register properties, |
- Handle<Name> name, |
- Register scratch0); |
- |
- static void GeneratePositiveLookup(MacroAssembler* masm, |
- Label* miss, |
- Label* done, |
- Register elements, |
- Register name, |
- Register scratch1, |
- Register scratch2); |
- |
- virtual bool SometimesSetsUpAFrame() { return false; } |
- |
- private: |
- static const int kInlinedProbes = 4; |
- static const int kTotalProbes = 20; |
- |
- static const int kCapacityOffset = |
- NameDictionary::kHeaderSize + |
- NameDictionary::kCapacityIndex * kPointerSize; |
- |
- static const int kElementsStartOffset = |
- NameDictionary::kHeaderSize + |
- NameDictionary::kElementsStartIndex * kPointerSize; |
- |
- Major MajorKey() { return NameDictionaryLookup; } |
- |
- int MinorKey() { |
- return LookupModeBits::encode(mode_); |
- } |
- |
- class LookupModeBits: public BitField<LookupMode, 0, 1> {}; |
- |
- LookupMode mode_; |
-}; |
- |
- |
-class SubStringStub: public PlatformCodeStub { |
- public: |
- SubStringStub() {} |
- |
- private: |
- Major MajorKey() { return SubString; } |
- int MinorKey() { return 0; } |
- |
- void Generate(MacroAssembler* masm); |
-}; |
- |
- |
-class StringCompareStub: public PlatformCodeStub { |
- public: |
- StringCompareStub() { } |
- |
- // Compares two flat ASCII strings and returns result in x0. |
- static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm, |
- Register left, |
- Register right, |
- Register scratch1, |
- Register scratch2, |
- Register scratch3, |
- Register scratch4); |
- |
- // Compare two flat ASCII strings for equality and returns result |
- // in x0. |
- static void GenerateFlatAsciiStringEquals(MacroAssembler* masm, |
- Register left, |
- Register right, |
- Register scratch1, |
- Register scratch2, |
- Register scratch3); |
- |
- private: |
- virtual Major MajorKey() { return StringCompare; } |
- virtual int MinorKey() { return 0; } |
- virtual void Generate(MacroAssembler* masm); |
- |
- static void GenerateAsciiCharsCompareLoop(MacroAssembler* masm, |
- Register left, |
- Register right, |
- Register length, |
- Register scratch1, |
- Register scratch2, |
- Label* chars_not_equal); |
-}; |
- |
- |
-struct PlatformCallInterfaceDescriptor { |
- explicit PlatformCallInterfaceDescriptor( |
- TargetAddressStorageMode storage_mode) |
- : storage_mode_(storage_mode) { } |
- |
- TargetAddressStorageMode storage_mode() { return storage_mode_; } |
- |
- private: |
- TargetAddressStorageMode storage_mode_; |
-}; |
- |
- |
-} } // namespace v8::internal |
- |
-#endif // V8_A64_CODE_STUBS_A64_H_ |