diff options
author | Myles Borins <mylesborins@google.com> | 2018-04-10 21:39:51 -0400 |
---|---|---|
committer | James M Snell <jasnell@gmail.com> | 2018-04-16 16:02:46 -0700 |
commit | 9daebb48d6f0ca63e72197a69e46c8ab43bc5d02 (patch) | |
tree | 8605276308c8b4e3597516961266bae1af57557a /deps/v8/src/arm | |
parent | 7d2814e7903155e61f244ae70721da1531cbcaec (diff) | |
download | node-new-9daebb48d6f0ca63e72197a69e46c8ab43bc5d02.tar.gz |
deps: update V8 to 6.6.346.23
PR-URL: https://github.com/nodejs/node/pull/19201
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Diffstat (limited to 'deps/v8/src/arm')
-rw-r--r-- | deps/v8/src/arm/assembler-arm-inl.h | 63 | ||||
-rw-r--r-- | deps/v8/src/arm/assembler-arm.cc | 62 | ||||
-rw-r--r-- | deps/v8/src/arm/assembler-arm.h | 98 | ||||
-rw-r--r-- | deps/v8/src/arm/code-stubs-arm.cc | 16 | ||||
-rw-r--r-- | deps/v8/src/arm/codegen-arm.cc | 10 | ||||
-rw-r--r-- | deps/v8/src/arm/constants-arm.h | 4 | ||||
-rw-r--r-- | deps/v8/src/arm/deoptimizer-arm.cc | 3 | ||||
-rw-r--r-- | deps/v8/src/arm/disasm-arm.cc | 10 | ||||
-rw-r--r-- | deps/v8/src/arm/frame-constants-arm.h | 6 | ||||
-rw-r--r-- | deps/v8/src/arm/interface-descriptors-arm.cc | 6 | ||||
-rw-r--r-- | deps/v8/src/arm/macro-assembler-arm.cc | 165 | ||||
-rw-r--r-- | deps/v8/src/arm/macro-assembler-arm.h | 30 | ||||
-rw-r--r-- | deps/v8/src/arm/simulator-arm.cc | 23 | ||||
-rw-r--r-- | deps/v8/src/arm/simulator-arm.h | 4 |
14 files changed, 319 insertions, 181 deletions
diff --git a/deps/v8/src/arm/assembler-arm-inl.h b/deps/v8/src/arm/assembler-arm-inl.h index f420f2e5cb..4d7d9895ce 100644 --- a/deps/v8/src/arm/assembler-arm-inl.h +++ b/deps/v8/src/arm/assembler-arm-inl.h @@ -46,7 +46,7 @@ namespace v8 { namespace internal { -bool CpuFeatures::SupportsCrankshaft() { return true; } +bool CpuFeatures::SupportsOptimizer() { return true; } bool CpuFeatures::SupportsWasmSimd128() { return IsSupported(NEON); } @@ -109,7 +109,7 @@ void RelocInfo::set_target_object(HeapObject* target, WriteBarrierMode write_barrier_mode, ICacheFlushMode icache_flush_mode) { DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); - Assembler::set_target_address_at(target->GetIsolate(), pc_, constant_pool_, + Assembler::set_target_address_at(pc_, constant_pool_, reinterpret_cast<Address>(target), icache_flush_mode); if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != nullptr) { @@ -143,27 +143,27 @@ Address RelocInfo::target_runtime_entry(Assembler* origin) { return target_address(); } -void RelocInfo::set_target_runtime_entry(Isolate* isolate, Address target, +void RelocInfo::set_target_runtime_entry(Address target, WriteBarrierMode write_barrier_mode, ICacheFlushMode icache_flush_mode) { DCHECK(IsRuntimeEntry(rmode_)); if (target_address() != target) - set_target_address(isolate, target, write_barrier_mode, icache_flush_mode); + set_target_address(target, write_barrier_mode, icache_flush_mode); } -void RelocInfo::WipeOut(Isolate* isolate) { +void RelocInfo::WipeOut() { DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) || IsInternalReference(rmode_)); if (IsInternalReference(rmode_)) { Memory::Address_at(pc_) = nullptr; } else { - Assembler::set_target_address_at(isolate, pc_, constant_pool_, nullptr); + Assembler::set_target_address_at(pc_, constant_pool_, nullptr); } } template <typename ObjectVisitor> -void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { +void RelocInfo::Visit(ObjectVisitor* visitor) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { visitor->VisitEmbeddedPointer(host(), this); @@ -189,7 +189,7 @@ Operand::Operand(const ExternalReference& f) value_.immediate = reinterpret_cast<int32_t>(f.address()); } -Operand::Operand(Smi* value) : rmode_(RelocInfo::NONE32) { +Operand::Operand(Smi* value) : rmode_(RelocInfo::NONE) { value_.immediate = reinterpret_cast<intptr_t>(value); } @@ -273,15 +273,13 @@ Address Assembler::return_address_from_call_start(Address pc) { } } - void Assembler::deserialization_set_special_target_at( - Isolate* isolate, Address constant_pool_entry, Code* code, Address target) { + Address constant_pool_entry, Code* code, Address target) { Memory::Address_at(constant_pool_entry) = target; } - void Assembler::deserialization_set_target_internal_reference_at( - Isolate* isolate, Address pc, Address target, RelocInfo::Mode mode) { + Address pc, Address target, RelocInfo::Mode mode) { Memory::Address_at(pc) = target; } @@ -329,17 +327,15 @@ Address Assembler::target_address_at(Address pc, Address constant_pool) { } } - -void Assembler::set_target_address_at(Isolate* isolate, Address pc, - Address constant_pool, Address target, +void Assembler::set_target_address_at(Address pc, Address constant_pool, + Address target, ICacheFlushMode icache_flush_mode) { - DCHECK_IMPLIES(isolate == nullptr, icache_flush_mode == SKIP_ICACHE_FLUSH); if (is_constant_pool_load(pc)) { // This is a constant pool lookup. Update the entry in the constant pool. Memory::Address_at(constant_pool_entry_address(pc, constant_pool)) = target; // Intuitively, we would think it is necessary to always flush the // instruction cache after patching a target address in the code as follows: - // Assembler::FlushICache(isolate, pc, sizeof(target)); + // Assembler::FlushICache(pc, sizeof(target)); // However, on ARM, no instruction is actually patched in the case // of embedded constants of the form: // ldr ip, [pp, #...] @@ -357,7 +353,7 @@ void Assembler::set_target_address_at(Isolate* isolate, Address pc, DCHECK(IsMovW(Memory::int32_at(pc))); DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize))); if (icache_flush_mode != SKIP_ICACHE_FLUSH) { - Assembler::FlushICache(isolate, pc, 2 * kInstrSize); + Assembler::FlushICache(pc, 2 * kInstrSize); } } else { // This is an mov / orr immediate load. Patch the immediate embedded in @@ -377,13 +373,42 @@ void Assembler::set_target_address_at(Isolate* isolate, Address pc, IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)) && IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize))); if (icache_flush_mode != SKIP_ICACHE_FLUSH) { - Assembler::FlushICache(isolate, pc, 4 * kInstrSize); + Assembler::FlushICache(pc, 4 * kInstrSize); } } } EnsureSpace::EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } +template <typename T> +bool UseScratchRegisterScope::CanAcquireVfp() const { + VfpRegList* available = assembler_->GetScratchVfpRegisterList(); + DCHECK_NOT_NULL(available); + for (int index = 0; index < T::kNumRegisters; index++) { + T reg = T::from_code(index); + uint64_t mask = reg.ToVfpRegList(); + if ((*available & mask) == mask) { + return true; + } + } + return false; +} + +template <typename T> +T UseScratchRegisterScope::AcquireVfp() { + VfpRegList* available = assembler_->GetScratchVfpRegisterList(); + DCHECK_NOT_NULL(available); + for (int index = 0; index < T::kNumRegisters; index++) { + T reg = T::from_code(index); + uint64_t mask = reg.ToVfpRegList(); + if ((*available & mask) == mask) { + *available &= ~mask; + return reg; + } + } + UNREACHABLE(); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/arm/assembler-arm.cc b/deps/v8/src/arm/assembler-arm.cc index a615d67496..1011db4b80 100644 --- a/deps/v8/src/arm/assembler-arm.cc +++ b/deps/v8/src/arm/assembler-arm.cc @@ -347,22 +347,20 @@ uint32_t RelocInfo::embedded_size() const { Assembler::target_address_at(pc_, constant_pool_)); } -void RelocInfo::set_embedded_address(Isolate* isolate, Address address, +void RelocInfo::set_embedded_address(Address address, ICacheFlushMode flush_mode) { - Assembler::set_target_address_at(isolate, pc_, constant_pool_, address, - flush_mode); + Assembler::set_target_address_at(pc_, constant_pool_, address, flush_mode); } -void RelocInfo::set_embedded_size(Isolate* isolate, uint32_t size, - ICacheFlushMode flush_mode) { - Assembler::set_target_address_at(isolate, pc_, constant_pool_, +void RelocInfo::set_embedded_size(uint32_t size, ICacheFlushMode flush_mode) { + Assembler::set_target_address_at(pc_, constant_pool_, reinterpret_cast<Address>(size), flush_mode); } -void RelocInfo::set_js_to_wasm_address(Isolate* isolate, Address address, +void RelocInfo::set_js_to_wasm_address(Address address, ICacheFlushMode icache_flush_mode) { DCHECK_EQ(rmode_, JS_TO_WASM_CALL); - set_embedded_address(isolate, address, icache_flush_mode); + set_embedded_address(address, icache_flush_mode); } Address RelocInfo::js_to_wasm_address() const { @@ -566,10 +564,16 @@ Assembler::Assembler(IsolateData isolate_data, void* buffer, int buffer_size) // it's awkward to use CpuFeatures::VFP32DREGS with CpuFeatureScope. To make // its use consistent with other features, we always enable it if we can. EnableCpuFeature(VFP32DREGS); + // Make sure we pick two D registers which alias a Q register. This way, we + // can use a Q as a scratch if NEON is supported. + scratch_vfp_register_list_ = d14.ToVfpRegList() | d15.ToVfpRegList(); + } else { + // When VFP32DREGS is not supported, d15 become allocatable. Therefore we + // cannot use it as a scratch. + scratch_vfp_register_list_ = d14.ToVfpRegList(); } } - Assembler::~Assembler() { DCHECK_EQ(const_pool_blocked_nesting_, 0); DCHECK_EQ(code_target_sharing_blocked_nesting_, 0); @@ -1214,6 +1218,7 @@ void Assembler::AddrMode1(Instr instr, Register rd, Register rn, DCHECK(x.IsImmediate()); // Upon failure to encode, the opcode should not have changed. DCHECK(opcode == (instr & kOpCodeMask)); + UseScratchRegisterScope temps(this); Condition cond = Instruction::ConditionField(instr); if ((opcode == MOV) && !set_flags) { // Generate a sequence of mov instructions or a load from the constant @@ -1221,7 +1226,7 @@ void Assembler::AddrMode1(Instr instr, Register rd, Register rn, DCHECK(!rn.is_valid()); Move32BitImmediate(rd, x, cond); } else if ((opcode == ADD) && !set_flags && (rd == rn) && - (scratch_register_list_ == 0)) { + !temps.CanAcquire()) { // Split the operation into a sequence of additions if we cannot use a // scratch register. In this case, we cannot re-use rn and the assembler // does not have any scratch registers to spare. @@ -1244,7 +1249,6 @@ void Assembler::AddrMode1(Instr instr, Register rd, Register rn, // The immediate operand cannot be encoded as a shifter operand, so load // it first to a scratch register and change the original instruction to // use it. - UseScratchRegisterScope temps(this); // Re-use the destination register if possible. Register scratch = (rd.is_valid() && rd != rn && rd != pc) ? rd : temps.Acquire(); @@ -1501,6 +1505,10 @@ void Assembler::and_(Register dst, Register src1, const Operand& src2, AddrMode1(cond | AND | s, dst, src1, src2); } +void Assembler::and_(Register dst, Register src1, Register src2, SBit s, + Condition cond) { + and_(dst, src1, Operand(src2), s, cond); +} void Assembler::eor(Register dst, Register src1, const Operand& src2, SBit s, Condition cond) { @@ -2367,6 +2375,11 @@ void Assembler::isb(BarrierOption option) { } } +void Assembler::csdb() { + // Details available in Arm Cache Speculation Side-channels white paper, + // version 1.1, page 4. + emit(0xE320F014); +} // Coprocessor instructions. void Assembler::cdp(Coprocessor coproc, @@ -5153,8 +5166,7 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { void Assembler::ConstantPoolAddEntry(int position, RelocInfo::Mode rmode, intptr_t value) { - DCHECK(rmode != RelocInfo::COMMENT && rmode != RelocInfo::CONST_POOL && - rmode != RelocInfo::NONE64); + DCHECK(rmode != RelocInfo::COMMENT && rmode != RelocInfo::CONST_POOL); bool sharing_ok = RelocInfo::IsNone(rmode) || (rmode >= RelocInfo::FIRST_SHAREABLE_RELOC_MODE); DCHECK_LT(pending_32_bit_constants_.size(), kMaxNumPending32Constants); @@ -5474,24 +5486,24 @@ void PatchingAssembler::Emit(Address addr) { emit(reinterpret_cast<Instr>(addr)); } -void PatchingAssembler::FlushICache(Isolate* isolate) { - Assembler::FlushICache(isolate, buffer_, buffer_size_ - kGap); -} - UseScratchRegisterScope::UseScratchRegisterScope(Assembler* assembler) - : available_(assembler->GetScratchRegisterList()), - old_available_(*available_) {} + : assembler_(assembler), + old_available_(*assembler->GetScratchRegisterList()), + old_available_vfp_(*assembler->GetScratchVfpRegisterList()) {} UseScratchRegisterScope::~UseScratchRegisterScope() { - *available_ = old_available_; + *assembler_->GetScratchRegisterList() = old_available_; + *assembler_->GetScratchVfpRegisterList() = old_available_vfp_; } Register UseScratchRegisterScope::Acquire() { - DCHECK_NOT_NULL(available_); - DCHECK_NE(*available_, 0); - int index = static_cast<int>(base::bits::CountTrailingZeros32(*available_)); - *available_ &= ~(1UL << index); - return Register::from_code(index); + RegList* available = assembler_->GetScratchRegisterList(); + DCHECK_NOT_NULL(available); + DCHECK_NE(*available, 0); + int index = static_cast<int>(base::bits::CountTrailingZeros32(*available)); + Register reg = Register::from_code(index); + *available &= ~reg.bit(); + return reg; } } // namespace internal diff --git a/deps/v8/src/arm/assembler-arm.h b/deps/v8/src/arm/assembler-arm.h index 8b95aad886..32baa0ae8d 100644 --- a/deps/v8/src/arm/assembler-arm.h +++ b/deps/v8/src/arm/assembler-arm.h @@ -56,8 +56,9 @@ namespace internal { V(r0) V(r1) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \ V(r8) V(r9) V(r10) V(fp) V(ip) V(sp) V(lr) V(pc) -#define ALLOCATABLE_GENERAL_REGISTERS(V) \ - V(r0) V(r1) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) V(r8) +#define ALLOCATABLE_GENERAL_REGISTERS(V) \ + V(r0) V(r1) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \ + V(r8) V(r9) #define FLOAT_REGISTERS(V) \ V(s0) V(s1) V(s2) V(s3) V(s4) V(s5) V(s6) V(s7) \ @@ -184,6 +185,17 @@ enum SwVfpRegisterCode { kSwVfpAfterLast }; +// Representation of a list of non-overlapping VFP registers. This list +// represents the data layout of VFP registers as a bitfield: +// S registers cover 1 bit +// D registers cover 2 bits +// Q registers cover 4 bits +// +// This way, we make sure no registers in the list ever overlap. However, a list +// may represent multiple different sets of registers, +// e.g. [d0 s2 s3] <=> [s0 s1 d1]. +typedef uint64_t VfpRegList; + // Single word VFP register. class SwVfpRegister : public RegisterBase<SwVfpRegister, kSwVfpAfterLast> { public: @@ -195,6 +207,11 @@ class SwVfpRegister : public RegisterBase<SwVfpRegister, kSwVfpAfterLast> { *vm = reg_code >> 1; } void split_code(int* vm, int* m) const { split_code(code(), vm, m); } + VfpRegList ToVfpRegList() const { + DCHECK(is_valid()); + // Each bit in the list corresponds to a S register. + return uint64_t{0x1} << code(); + } private: friend class RegisterBase; @@ -217,10 +234,6 @@ enum DoubleRegisterCode { // Double word VFP register. class DwVfpRegister : public RegisterBase<DwVfpRegister, kDoubleAfterLast> { public: - // A few double registers are reserved: one as a scratch register and one to - // hold 0.0, that does not fit in the immediate field of vmov instructions. - // d14: 0.0 - // d15: scratch register. static constexpr int kSizeInBytes = 8; inline static int NumRegisters(); @@ -231,6 +244,11 @@ class DwVfpRegister : public RegisterBase<DwVfpRegister, kDoubleAfterLast> { *vm = reg_code & 0x0F; } void split_code(int* vm, int* m) const { split_code(code(), vm, m); } + VfpRegList ToVfpRegList() const { + DCHECK(is_valid()); + // A D register overlaps two S registers. + return uint64_t{0x3} << (code() * 2); + } private: friend class RegisterBase; @@ -255,6 +273,11 @@ class LowDwVfpRegister SwVfpRegister high() const { return SwVfpRegister::from_code(code() * 2 + 1); } + VfpRegList ToVfpRegList() const { + DCHECK(is_valid()); + // A D register overlaps two S registers. + return uint64_t{0x3} << (code() * 2); + } private: friend class RegisterBase; @@ -282,6 +305,11 @@ class QwNeonRegister : public RegisterBase<QwNeonRegister, kSimd128AfterLast> { DwVfpRegister high() const { return DwVfpRegister::from_code(code() * 2 + 1); } + VfpRegList ToVfpRegList() const { + DCHECK(is_valid()); + // A Q register overlaps four S registers. + return uint64_t{0xf} << (code() * 4); + } private: friend class RegisterBase; @@ -334,12 +362,6 @@ SIMD128_REGISTERS(DECLARE_SIMD128_REGISTER) constexpr LowDwVfpRegister kFirstCalleeSavedDoubleReg = d8; constexpr LowDwVfpRegister kLastCalleeSavedDoubleReg = d15; constexpr LowDwVfpRegister kDoubleRegZero = d13; -constexpr LowDwVfpRegister kScratchDoubleReg = d14; -// This scratch q-register aliases d14 (kScratchDoubleReg) and d15, but is only -// used if NEON is supported, which implies VFP32DREGS. When there are only 16 -// d-registers, d15 is still allocatable. -constexpr QwNeonRegister kScratchQuadReg = q7; -constexpr LowDwVfpRegister kScratchDoubleReg2 = d15; constexpr CRegister no_creg = CRegister::no_reg(); @@ -376,7 +398,7 @@ class Operand BASE_EMBEDDED { public: // immediate INLINE(explicit Operand(int32_t immediate, - RelocInfo::Mode rmode = RelocInfo::NONE32)); + RelocInfo::Mode rmode = RelocInfo::NONE)); INLINE(static Operand Zero()); INLINE(explicit Operand(const ExternalReference& f)); explicit Operand(Handle<HeapObject> handle); @@ -651,7 +673,7 @@ class Assembler : public AssemblerBase { // The isolate argument is unused (and may be nullptr) when skipping flushing. INLINE(static Address target_address_at(Address pc, Address constant_pool)); INLINE(static void set_target_address_at( - Isolate* isolate, Address pc, Address constant_pool, Address target, + Address pc, Address constant_pool, Address target, ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); // Return the code target address at a call site from the return address @@ -665,12 +687,11 @@ class Assembler : public AssemblerBase { // This sets the branch destination (which is in the constant pool on ARM). // This is for calls and branches within generated code. inline static void deserialization_set_special_target_at( - Isolate* isolate, Address constant_pool_entry, Code* code, - Address target); + Address constant_pool_entry, Code* code, Address target); // This sets the internal reference at the pc. inline static void deserialization_set_target_internal_reference_at( - Isolate* isolate, Address pc, Address target, + Address pc, Address target, RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); // Here we are patching the address in the constant pool, not the actual call @@ -685,6 +706,9 @@ class Assembler : public AssemblerBase { // register. static constexpr int kPcLoadDelta = 8; RegList* GetScratchRegisterList() { return &scratch_register_list_; } + VfpRegList* GetScratchVfpRegisterList() { + return &scratch_vfp_register_list_; + } // --------------------------------------------------------------------------- // Code generation @@ -717,6 +741,8 @@ class Assembler : public AssemblerBase { void and_(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, Condition cond = al); + void and_(Register dst, Register src1, Register src2, SBit s = LeaveCC, + Condition cond = al); void eor(Register dst, Register src1, const Operand& src2, SBit s = LeaveCC, Condition cond = al); @@ -936,6 +962,9 @@ class Assembler : public AssemblerBase { void dsb(BarrierOption option); void isb(BarrierOption option); + // Conditional speculation barrier. + void csdb(); + // Coprocessor instructions void cdp(Coprocessor coproc, int opcode_1, @@ -1655,6 +1684,7 @@ class Assembler : public AssemblerBase { // Scratch registers available for use by the Assembler. RegList scratch_register_list_; + VfpRegList scratch_vfp_register_list_; private: // Avoid overflows for displacements etc. @@ -1732,6 +1762,7 @@ class Assembler : public AssemblerBase { friend class BlockConstPoolScope; friend class BlockCodeTargetSharingScope; friend class EnsureSpace; + friend class UseScratchRegisterScope; // The following functions help with avoiding allocations of embedded heap // objects during the code assembly phase. {RequestHeapObject} records the @@ -1747,8 +1778,6 @@ class Assembler : public AssemblerBase { std::forward_list<HeapObjectRequest> heap_object_requests_; }; -constexpr int kNoCodeAgeSequenceLength = 3 * Assembler::kInstrSize; - class EnsureSpace BASE_EMBEDDED { public: INLINE(explicit EnsureSpace(Assembler* assembler)); @@ -1760,7 +1789,6 @@ class PatchingAssembler : public Assembler { ~PatchingAssembler(); void Emit(Address addr); - void FlushICache(Isolate* isolate); }; // This scope utility allows scratch registers to be managed safely. The @@ -1779,12 +1807,38 @@ class UseScratchRegisterScope { // Take a register from the list and return it. Register Acquire(); + SwVfpRegister AcquireS() { return AcquireVfp<SwVfpRegister>(); } + LowDwVfpRegister AcquireLowD() { return AcquireVfp<LowDwVfpRegister>(); } + DwVfpRegister AcquireD() { + DwVfpRegister reg = AcquireVfp<DwVfpRegister>(); + DCHECK(assembler_->VfpRegisterIsAvailable(reg)); + return reg; + } + QwNeonRegister AcquireQ() { + QwNeonRegister reg = AcquireVfp<QwNeonRegister>(); + DCHECK(assembler_->VfpRegisterIsAvailable(reg)); + return reg; + } private: - // Currently available scratch registers. - RegList* available_; + friend class Assembler; + friend class TurboAssembler; + + // Check if we have registers available to acquire. + // These methods are kept private intentionally to restrict their usage to the + // assemblers. Choosing to emit a difference instruction sequence depending on + // the availability of scratch registers is generally their job. + bool CanAcquire() const { return *assembler_->GetScratchRegisterList() != 0; } + template <typename T> + bool CanAcquireVfp() const; + + template <typename T> + T AcquireVfp(); + + Assembler* assembler_; // Available scratch registers at the start of this scope. RegList old_available_; + VfpRegList old_available_vfp_; }; } // namespace internal diff --git a/deps/v8/src/arm/code-stubs-arm.cc b/deps/v8/src/arm/code-stubs-arm.cc index ee706c7656..2695bafc1b 100644 --- a/deps/v8/src/arm/code-stubs-arm.cc +++ b/deps/v8/src/arm/code-stubs-arm.cc @@ -46,7 +46,7 @@ void DoubleToIStub::Generate(MacroAssembler* masm) { UseScratchRegisterScope temps(masm); Register double_low = GetRegisterThatIsNotOneOf(result_reg); Register double_high = GetRegisterThatIsNotOneOf(result_reg, double_low); - LowDwVfpRegister double_scratch = kScratchDoubleReg; + LowDwVfpRegister double_scratch = temps.AcquireLowD(); // Save the old values from these temporary registers on the stack. __ Push(double_high, double_low); @@ -385,6 +385,12 @@ void CEntryStub::Generate(MacroAssembler* masm) { __ cmp(cp, Operand(0)); __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); + // Reset the masking register. This is done independent of the underlying + // feature flag {FLAG_branch_load_poisoning} to make the snapshot work with + // both configurations. It is safe to always do this, because the underlying + // register is caller-saved and can be arbitrarily clobbered. + __ ResetSpeculationPoisonRegister(); + // Compute the handler entry address and jump to it. ConstantPoolUnavailableScope constant_pool_unavailable(masm); __ mov(r1, Operand(pending_handler_entrypoint_address)); @@ -572,8 +578,8 @@ void ProfileEntryHookStub::MaybeCallEntryHookDelayed(TurboAssembler* tasm, Zone* zone) { if (tasm->isolate()->function_entry_hook() != nullptr) { tasm->MaybeCheckConstPool(); - PredictableCodeSizeScope predictable(tasm); - predictable.ExpectSize(tasm->CallStubSize() + 2 * Assembler::kInstrSize); + PredictableCodeSizeScope predictable( + tasm, tasm->CallStubSize() + 2 * Assembler::kInstrSize); tasm->push(lr); tasm->CallStubDelayed(new (zone) ProfileEntryHookStub(nullptr)); tasm->pop(lr); @@ -584,8 +590,8 @@ void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { if (masm->isolate()->function_entry_hook() != nullptr) { ProfileEntryHookStub stub(masm->isolate()); masm->MaybeCheckConstPool(); - PredictableCodeSizeScope predictable(masm); - predictable.ExpectSize(masm->CallStubSize() + 2 * Assembler::kInstrSize); + PredictableCodeSizeScope predictable( + masm, masm->CallStubSize() + 2 * Assembler::kInstrSize); __ push(lr); __ CallStub(&stub); __ pop(lr); diff --git a/deps/v8/src/arm/codegen-arm.cc b/deps/v8/src/arm/codegen-arm.cc index 9fb2eb4e8d..b3e880e048 100644 --- a/deps/v8/src/arm/codegen-arm.cc +++ b/deps/v8/src/arm/codegen-arm.cc @@ -166,9 +166,9 @@ MemCopyUint8Function CreateMemCopyUint8Function(Isolate* isolate, CodeDesc desc; masm.GetCode(isolate, &desc); - DCHECK(!RelocInfo::RequiresRelocation(isolate, desc)); + DCHECK(!RelocInfo::RequiresRelocation(desc)); - Assembler::FlushICache(isolate, buffer, allocated); + Assembler::FlushICache(buffer, allocated); CHECK(SetPermissions(buffer, allocated, PageAllocator::kReadExecute)); return FUNCTION_CAST<MemCopyUint8Function>(buffer); #endif @@ -257,7 +257,7 @@ MemCopyUint16Uint8Function CreateMemCopyUint16Uint8Function( CodeDesc desc; masm.GetCode(isolate, &desc); - Assembler::FlushICache(isolate, buffer, allocated); + Assembler::FlushICache(buffer, allocated); CHECK(SetPermissions(buffer, allocated, PageAllocator::kReadExecute)); return FUNCTION_CAST<MemCopyUint16Uint8Function>(buffer); #endif @@ -282,9 +282,9 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) { CodeDesc desc; masm.GetCode(isolate, &desc); - DCHECK(!RelocInfo::RequiresRelocation(isolate, desc)); + DCHECK(!RelocInfo::RequiresRelocation(desc)); - Assembler::FlushICache(isolate, buffer, allocated); + Assembler::FlushICache(buffer, allocated); CHECK(SetPermissions(buffer, allocated, PageAllocator::kReadExecute)); return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer); #endif diff --git a/deps/v8/src/arm/constants-arm.h b/deps/v8/src/arm/constants-arm.h index 1c865afb09..4e52a91738 100644 --- a/deps/v8/src/arm/constants-arm.h +++ b/deps/v8/src/arm/constants-arm.h @@ -641,8 +641,8 @@ class Instruction { && (Bit(20) == 0) && ((Bit(7) == 0)); } - // Test for a nop instruction, which falls under type 1. - inline bool IsNopType1() const { return Bits(24, 0) == 0x0120F000; } + // Test for nop-like instructions which fall under type 1. + inline bool IsNopLikeType1() const { return Bits(24, 8) == 0x120F0; } // Test for a stop instruction. inline bool IsStop() const { diff --git a/deps/v8/src/arm/deoptimizer-arm.cc b/deps/v8/src/arm/deoptimizer-arm.cc index 9a21ef862c..a4a540512d 100644 --- a/deps/v8/src/arm/deoptimizer-arm.cc +++ b/deps/v8/src/arm/deoptimizer-arm.cc @@ -30,9 +30,6 @@ void Deoptimizer::TableEntryGenerator::Generate() { const int kFloatRegsSize = kFloatSize * SwVfpRegister::kNumRegisters; // Save all allocatable VFP registers before messing with them. - DCHECK_EQ(kDoubleRegZero.code(), 13); - DCHECK_EQ(kScratchDoubleReg.code(), 14); - { // We use a run-time check for VFP32DREGS. CpuFeatureScope scope(masm(), VFP32DREGS, diff --git a/deps/v8/src/arm/disasm-arm.cc b/deps/v8/src/arm/disasm-arm.cc index 9951136561..9459a7e60d 100644 --- a/deps/v8/src/arm/disasm-arm.cc +++ b/deps/v8/src/arm/disasm-arm.cc @@ -937,8 +937,14 @@ void Decoder::DecodeType01(Instruction* instr) { } else { Unknown(instr); // not used by V8 } - } else if ((type == 1) && instr->IsNopType1()) { - Format(instr, "nop'cond"); + } else if ((type == 1) && instr->IsNopLikeType1()) { + if (instr->BitField(7, 0) == 0) { + Format(instr, "nop'cond"); + } else if (instr->BitField(7, 0) == 20) { + Format(instr, "csdb"); + } else { + Unknown(instr); // Not used in V8. + } } else { switch (instr->OpcodeField()) { case AND: { diff --git a/deps/v8/src/arm/frame-constants-arm.h b/deps/v8/src/arm/frame-constants-arm.h index 9307cc22de..1230a26956 100644 --- a/deps/v8/src/arm/frame-constants-arm.h +++ b/deps/v8/src/arm/frame-constants-arm.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef V8_ARM_FRAMES_ARM_H_ -#define V8_ARM_FRAMES_ARM_H_ +#ifndef V8_ARM_FRAME_CONSTANTS_ARM_H_ +#define V8_ARM_FRAME_CONSTANTS_ARM_H_ namespace v8 { namespace internal { @@ -45,4 +45,4 @@ class JavaScriptFrameConstants : public AllStatic { } // namespace internal } // namespace v8 -#endif // V8_ARM_FRAMES_ARM_H_ +#endif // V8_ARM_FRAME_CONSTANTS_ARM_H_ diff --git a/deps/v8/src/arm/interface-descriptors-arm.cc b/deps/v8/src/arm/interface-descriptors-arm.cc index 6b7498fde5..20ecef6c1c 100644 --- a/deps/v8/src/arm/interface-descriptors-arm.cc +++ b/deps/v8/src/arm/interface-descriptors-arm.cc @@ -70,12 +70,6 @@ const Register GrowArrayElementsDescriptor::ObjectRegister() { return r0; } const Register GrowArrayElementsDescriptor::KeyRegister() { return r3; } -void FastNewClosureDescriptor::InitializePlatformSpecific( - CallInterfaceDescriptorData* data) { - Register registers[] = {r1, r2, r3}; - data->InitializePlatformSpecific(arraysize(registers), registers); -} - // static const Register TypeConversionDescriptor::ArgumentRegister() { return r0; } diff --git a/deps/v8/src/arm/macro-assembler-arm.cc b/deps/v8/src/arm/macro-assembler-arm.cc index 30190d3f34..3a96b640a2 100644 --- a/deps/v8/src/arm/macro-assembler-arm.cc +++ b/deps/v8/src/arm/macro-assembler-arm.cc @@ -18,6 +18,7 @@ #include "src/double.h" #include "src/external-reference-table.h" #include "src/frames-inl.h" +#include "src/instruction-stream.h" #include "src/objects-inl.h" #include "src/register-configuration.h" #include "src/runtime/runtime.h" @@ -241,22 +242,6 @@ void TurboAssembler::Ret(int drop, Condition cond) { Ret(cond); } - -void MacroAssembler::Swap(Register reg1, - Register reg2, - Register scratch, - Condition cond) { - if (scratch == no_reg) { - eor(reg1, reg1, Operand(reg2), LeaveCC, cond); - eor(reg2, reg2, Operand(reg1), LeaveCC, cond); - eor(reg1, reg1, Operand(reg2), LeaveCC, cond); - } else { - mov(scratch, reg1, LeaveCC, cond); - mov(reg1, reg2, LeaveCC, cond); - mov(reg2, scratch, LeaveCC, cond); - } -} - void TurboAssembler::Call(Label* target) { bl(target); } void TurboAssembler::Push(Handle<HeapObject> handle) { @@ -305,27 +290,34 @@ void TurboAssembler::Move(QwNeonRegister dst, QwNeonRegister src) { } } -void TurboAssembler::Swap(DwVfpRegister srcdst0, DwVfpRegister srcdst1) { - if (srcdst0 == srcdst1) return; // Swapping aliased registers emits nothing. +void TurboAssembler::Swap(Register srcdst0, Register srcdst1) { + DCHECK(srcdst0 != srcdst1); + UseScratchRegisterScope temps(this); + Register scratch = temps.Acquire(); + mov(scratch, srcdst0); + mov(srcdst0, srcdst1); + mov(srcdst1, scratch); +} +void TurboAssembler::Swap(DwVfpRegister srcdst0, DwVfpRegister srcdst1) { + DCHECK(srcdst0 != srcdst1); DCHECK(VfpRegisterIsAvailable(srcdst0)); DCHECK(VfpRegisterIsAvailable(srcdst1)); if (CpuFeatures::IsSupported(NEON)) { vswp(srcdst0, srcdst1); } else { - DCHECK_NE(srcdst0, kScratchDoubleReg); - DCHECK_NE(srcdst1, kScratchDoubleReg); - vmov(kScratchDoubleReg, srcdst0); + UseScratchRegisterScope temps(this); + DwVfpRegister scratch = temps.AcquireD(); + vmov(scratch, srcdst0); vmov(srcdst0, srcdst1); - vmov(srcdst1, kScratchDoubleReg); + vmov(srcdst1, scratch); } } void TurboAssembler::Swap(QwNeonRegister srcdst0, QwNeonRegister srcdst1) { - if (srcdst0 != srcdst1) { - vswp(srcdst0, srcdst1); - } + DCHECK(srcdst0 != srcdst1); + vswp(srcdst0, srcdst1); } void MacroAssembler::Mls(Register dst, Register src1, Register src2, @@ -817,11 +809,14 @@ void TurboAssembler::VmovExtended(int dst_code, int src_code) { int dst_offset = dst_code & 1; int src_offset = src_code & 1; if (CpuFeatures::IsSupported(NEON)) { + UseScratchRegisterScope temps(this); + DwVfpRegister scratch = temps.AcquireD(); // On Neon we can shift and insert from d-registers. if (src_offset == dst_offset) { // Offsets are the same, use vdup to copy the source to the opposite lane. - vdup(Neon32, kScratchDoubleReg, src_d_reg, src_offset); - src_d_reg = kScratchDoubleReg; + vdup(Neon32, scratch, src_d_reg, src_offset); + // Here we are extending the lifetime of scratch. + src_d_reg = scratch; src_offset = dst_offset ^ 1; } if (dst_offset) { @@ -842,27 +837,30 @@ void TurboAssembler::VmovExtended(int dst_code, int src_code) { // Without Neon, use the scratch registers to move src and/or dst into // s-registers. - int scratchSCode = kScratchDoubleReg.low().code(); - int scratchSCode2 = kScratchDoubleReg2.low().code(); + UseScratchRegisterScope temps(this); + LowDwVfpRegister d_scratch = temps.AcquireLowD(); + LowDwVfpRegister d_scratch2 = temps.AcquireLowD(); + int s_scratch_code = d_scratch.low().code(); + int s_scratch_code2 = d_scratch2.low().code(); if (src_code < SwVfpRegister::kNumRegisters) { // src is an s-register, dst is not. - vmov(kScratchDoubleReg, dst_d_reg); - vmov(SwVfpRegister::from_code(scratchSCode + dst_offset), + vmov(d_scratch, dst_d_reg); + vmov(SwVfpRegister::from_code(s_scratch_code + dst_offset), SwVfpRegister::from_code(src_code)); - vmov(dst_d_reg, kScratchDoubleReg); + vmov(dst_d_reg, d_scratch); } else if (dst_code < SwVfpRegister::kNumRegisters) { // dst is an s-register, src is not. - vmov(kScratchDoubleReg, src_d_reg); + vmov(d_scratch, src_d_reg); vmov(SwVfpRegister::from_code(dst_code), - SwVfpRegister::from_code(scratchSCode + src_offset)); + SwVfpRegister::from_code(s_scratch_code + src_offset)); } else { // Neither src or dst are s-registers. Both scratch double registers are // available when there are 32 VFP registers. - vmov(kScratchDoubleReg, src_d_reg); - vmov(kScratchDoubleReg2, dst_d_reg); - vmov(SwVfpRegister::from_code(scratchSCode + dst_offset), - SwVfpRegister::from_code(scratchSCode2 + src_offset)); - vmov(dst_d_reg, kScratchQuadReg.high()); + vmov(d_scratch, src_d_reg); + vmov(d_scratch2, dst_d_reg); + vmov(SwVfpRegister::from_code(s_scratch_code + dst_offset), + SwVfpRegister::from_code(s_scratch_code2 + src_offset)); + vmov(dst_d_reg, d_scratch2); } } @@ -870,11 +868,13 @@ void TurboAssembler::VmovExtended(int dst_code, const MemOperand& src) { if (dst_code < SwVfpRegister::kNumRegisters) { vldr(SwVfpRegister::from_code(dst_code), src); } else { + UseScratchRegisterScope temps(this); + LowDwVfpRegister scratch = temps.AcquireLowD(); // TODO(bbudge) If Neon supported, use load single lane form of vld1. - int dst_s_code = kScratchDoubleReg.low().code() + (dst_code & 1); - vmov(kScratchDoubleReg, DwVfpRegister::from_code(dst_code / 2)); + int dst_s_code = scratch.low().code() + (dst_code & 1); + vmov(scratch, DwVfpRegister::from_code(dst_code / 2)); vldr(SwVfpRegister::from_code(dst_s_code), src); - vmov(DwVfpRegister::from_code(dst_code / 2), kScratchDoubleReg); + vmov(DwVfpRegister::from_code(dst_code / 2), scratch); } } @@ -883,8 +883,10 @@ void TurboAssembler::VmovExtended(const MemOperand& dst, int src_code) { vstr(SwVfpRegister::from_code(src_code), dst); } else { // TODO(bbudge) If Neon supported, use store single lane form of vst1. - int src_s_code = kScratchDoubleReg.low().code() + (src_code & 1); - vmov(kScratchDoubleReg, DwVfpRegister::from_code(src_code / 2)); + UseScratchRegisterScope temps(this); + LowDwVfpRegister scratch = temps.AcquireLowD(); + int src_s_code = scratch.low().code() + (src_code & 1); + vmov(scratch, DwVfpRegister::from_code(src_code / 2)); vstr(SwVfpRegister::from_code(src_s_code), dst); } } @@ -938,9 +940,11 @@ void TurboAssembler::ReplaceLane(QwNeonRegister dst, QwNeonRegister src, void TurboAssembler::LslPair(Register dst_low, Register dst_high, Register src_low, Register src_high, - Register scratch, Register shift) { + Register shift) { DCHECK(!AreAliased(dst_high, src_low)); DCHECK(!AreAliased(dst_high, shift)); + UseScratchRegisterScope temps(this); + Register scratch = temps.Acquire(); Label less_than_32; Label done; @@ -984,9 +988,11 @@ void TurboAssembler::LslPair(Register dst_low, Register dst_high, void TurboAssembler::LsrPair(Register dst_low, Register dst_high, Register src_low, Register src_high, - Register scratch, Register shift) { + Register shift) { DCHECK(!AreAliased(dst_low, src_high)); DCHECK(!AreAliased(dst_low, shift)); + UseScratchRegisterScope temps(this); + Register scratch = temps.Acquire(); Label less_than_32; Label done; @@ -1031,9 +1037,11 @@ void TurboAssembler::LsrPair(Register dst_low, Register dst_high, void TurboAssembler::AsrPair(Register dst_low, Register dst_high, Register src_low, Register src_high, - Register scratch, Register shift) { + Register shift) { DCHECK(!AreAliased(dst_low, src_high)); DCHECK(!AreAliased(dst_low, shift)); + UseScratchRegisterScope temps(this); + Register scratch = temps.Acquire(); Label less_than_32; Label done; @@ -1362,13 +1370,30 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, void MacroAssembler::CheckDebugHook(Register fun, Register new_target, const ParameterCount& expected, const ParameterCount& actual) { - Label skip_hook; + Label skip_hook, call_hook; + + ExternalReference debug_is_active = + ExternalReference::debug_is_active_address(isolate()); + mov(r4, Operand(debug_is_active)); + ldrsb(r4, MemOperand(r4)); + cmp(r4, Operand(0)); + b(eq, &skip_hook); + ExternalReference debug_hook_avtive = ExternalReference::debug_hook_on_function_call_address(isolate()); mov(r4, Operand(debug_hook_avtive)); ldrsb(r4, MemOperand(r4)); cmp(r4, Operand(0)); + b(ne, &call_hook); + + ldr(r4, FieldMemOperand(fun, JSFunction::kSharedFunctionInfoOffset)); + ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kDebugInfoOffset)); + JumpIfSmi(r4, &skip_hook); + ldr(r4, FieldMemOperand(r4, DebugInfo::kFlagsOffset)); + tst(r4, Operand(Smi::FromInt(DebugInfo::kBreakAtEntry))); b(eq, &skip_hook); + + bind(&call_hook); { FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); @@ -1426,7 +1451,7 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, // We call indirectly through the code field in the function to // allow recompilation to take effect without changing any of the // call sites. - Register code = r4; + Register code = kJavaScriptCallCodeStartRegister; ldr(code, FieldMemOperand(function, JSFunction::kCodeOffset)); add(code, code, Operand(Code::kHeaderSize - kHeapObjectTag)); if (flag == CALL_FUNCTION) { @@ -1480,14 +1505,6 @@ void MacroAssembler::InvokeFunction(Register function, InvokeFunctionCode(r1, no_reg, expected, actual, flag); } -void MacroAssembler::InvokeFunction(Handle<JSFunction> function, - const ParameterCount& expected, - const ParameterCount& actual, - InvokeFlag flag) { - Move(r1, function); - InvokeFunction(r1, expected, actual, flag); -} - void MacroAssembler::MaybeDropFrames() { // Check whether we need to drop frames to restart a function on the stack. ExternalReference restart_fp = @@ -1615,13 +1632,22 @@ void MacroAssembler::TryDoubleToInt32Exact(Register result, void TurboAssembler::TryInlineTruncateDoubleToI(Register result, DwVfpRegister double_input, Label* done) { - LowDwVfpRegister double_scratch = kScratchDoubleReg; - vcvt_s32_f64(double_scratch.low(), double_input); - vmov(result, double_scratch.low()); - UseScratchRegisterScope temps(this); - Register scratch = temps.Acquire(); + SwVfpRegister single_scratch = SwVfpRegister::no_reg(); + if (temps.CanAcquireVfp<SwVfpRegister>()) { + single_scratch = temps.AcquireS(); + } else { + // Re-use the input as a scratch register. However, we can only do this if + // the input register is d0-d15 as there are no s32+ registers. + DCHECK_LT(double_input.code(), LowDwVfpRegister::kNumRegisters); + LowDwVfpRegister double_scratch = + LowDwVfpRegister::from_code(double_input.code()); + single_scratch = double_scratch.low(); + } + vcvt_s32_f64(single_scratch, double_input); + vmov(result, single_scratch); + Register scratch = temps.Acquire(); // If result is not saturated (0x7FFFFFFF or 0x80000000), we are done. sub(scratch, result, Operand(1)); cmp(scratch, Operand(0x7FFFFFFE)); @@ -1704,6 +1730,12 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin, Jump(stub.GetCode(), RelocInfo::CODE_TARGET); } +void MacroAssembler::JumpToInstructionStream(const InstructionStream* stream) { + int32_t bytes_address = reinterpret_cast<int32_t>(stream->bytes()); + mov(kOffHeapTrampolineRegister, Operand(bytes_address, RelocInfo::NONE)); + Jump(kOffHeapTrampolineRegister); +} + void MacroAssembler::IncrementCounter(StatsCounter* counter, int value, Register scratch1, Register scratch2) { DCHECK_GT(value, 0); @@ -2275,6 +2307,15 @@ bool AreAliased(Register reg1, } #endif +void TurboAssembler::ComputeCodeStartAddress(Register dst) { + // We can use the register pc - 8 for the address of the current instruction. + sub(dst, pc, Operand(pc_offset() + TurboAssembler::kPcLoadDelta)); +} + +void TurboAssembler::ResetSpeculationPoisonRegister() { + mov(kSpeculationPoisonRegister, Operand(-1)); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/arm/macro-assembler-arm.h b/deps/v8/src/arm/macro-assembler-arm.h index cf731cbedb..50ce6dc005 100644 --- a/deps/v8/src/arm/macro-assembler-arm.h +++ b/deps/v8/src/arm/macro-assembler-arm.h @@ -20,12 +20,15 @@ constexpr Register kReturnRegister2 = r2; constexpr Register kJSFunctionRegister = r1; constexpr Register kContextRegister = r7; constexpr Register kAllocateSizeRegister = r1; +constexpr Register kSpeculationPoisonRegister = r9; constexpr Register kInterpreterAccumulatorRegister = r0; constexpr Register kInterpreterBytecodeOffsetRegister = r5; constexpr Register kInterpreterBytecodeArrayRegister = r6; constexpr Register kInterpreterDispatchTableRegister = r8; constexpr Register kJavaScriptCallArgCountRegister = r0; +constexpr Register kJavaScriptCallCodeStartRegister = r2; constexpr Register kJavaScriptCallNewTargetRegister = r3; +constexpr Register kOffHeapTrampolineRegister = r4; constexpr Register kRuntimeCallFunctionRegister = r1; constexpr Register kRuntimeCallArgCountRegister = r0; @@ -305,15 +308,15 @@ class TurboAssembler : public Assembler { inline bool AllowThisStubCall(CodeStub* stub); void LslPair(Register dst_low, Register dst_high, Register src_low, - Register src_high, Register scratch, Register shift); + Register src_high, Register shift); void LslPair(Register dst_low, Register dst_high, Register src_low, Register src_high, uint32_t shift); void LsrPair(Register dst_low, Register dst_high, Register src_low, - Register src_high, Register scratch, Register shift); + Register src_high, Register shift); void LsrPair(Register dst_low, Register dst_high, Register src_low, Register src_high, uint32_t shift); void AsrPair(Register dst_low, Register dst_high, Register src_low, - Register src_high, Register scratch, Register shift); + Register src_high, Register shift); void AsrPair(Register dst_low, Register dst_high, Register src_low, Register src_high, uint32_t shift); @@ -481,7 +484,8 @@ class TurboAssembler : public Assembler { void VmovExtended(int dst_code, const MemOperand& src); void VmovExtended(const MemOperand& dst, int src_code); - // Register swap. + // Register swap. Note that the register operands should be distinct. + void Swap(Register srcdst0, Register srcdst1); void Swap(DwVfpRegister srcdst0, DwVfpRegister srcdst1); void Swap(QwNeonRegister srcdst0, QwNeonRegister srcdst1); @@ -530,6 +534,12 @@ class TurboAssembler : public Assembler { #endif } + // Compute the start of the generated instruction stream from the current PC. + // This is an alternative to embedding the {CodeObject} handle as a reference. + void ComputeCodeStartAddress(Register dst); + + void ResetSpeculationPoisonRegister(); + private: bool has_frame_ = false; Isolate* const isolate_; @@ -579,11 +589,6 @@ class MacroAssembler : public TurboAssembler { MacroAssembler(Isolate* isolate, void* buffer, int size, CodeObjectRequired create_code_object); - // Swap two registers. If the scratch register is omitted then a slightly - // less efficient form using xor instead of mov is emitted. - void Swap(Register reg1, Register reg2, Register scratch = no_reg, - Condition cond = al); - void Mls(Register dst, Register src1, Register src2, Register srcA, Condition cond = al); void And(Register dst, Register src1, const Operand& src2, @@ -694,10 +699,6 @@ class MacroAssembler : public TurboAssembler { void InvokeFunction(Register function, const ParameterCount& expected, const ParameterCount& actual, InvokeFlag flag); - void InvokeFunction(Handle<JSFunction> function, - const ParameterCount& expected, - const ParameterCount& actual, InvokeFlag flag); - // Frame restart support void MaybeDropFrames(); @@ -797,6 +798,9 @@ class MacroAssembler : public TurboAssembler { void JumpToExternalReference(const ExternalReference& builtin, bool builtin_exit_frame = false); + // Generates a trampoline to jump to the off-heap instruction stream. + void JumpToInstructionStream(const InstructionStream* stream); + // --------------------------------------------------------------------------- // StatsCounter support diff --git a/deps/v8/src/arm/simulator-arm.cc b/deps/v8/src/arm/simulator-arm.cc index 52fe902237..6a735fcef6 100644 --- a/deps/v8/src/arm/simulator-arm.cc +++ b/deps/v8/src/arm/simulator-arm.cc @@ -547,8 +547,7 @@ void ArmDebugger::Debug() { #undef XSTR } - -static bool ICacheMatch(void* one, void* two) { +bool Simulator::ICacheMatch(void* one, void* two) { DCHECK_EQ(reinterpret_cast<intptr_t>(one) & CachePage::kPageMask, 0); DCHECK_EQ(reinterpret_cast<intptr_t>(two) & CachePage::kPageMask, 0); return one == two; @@ -645,11 +644,6 @@ void Simulator::CheckICache(base::CustomMatcherHashMap* i_cache, Simulator::Simulator(Isolate* isolate) : isolate_(isolate) { - i_cache_ = isolate_->simulator_i_cache(); - if (i_cache_ == nullptr) { - i_cache_ = new base::CustomMatcherHashMap(&ICacheMatch); - isolate_->set_simulator_i_cache(i_cache_); - } // Set up simulator support first. Some of this information is needed to // setup the architecture state. size_t stack_size = 1 * 1024*1024; // allocate 1MB for stack @@ -2314,8 +2308,15 @@ void Simulator::DecodeType01(Instruction* instr) { PrintF("%08x\n", instr->InstructionBits()); UNIMPLEMENTED(); } - } else if ((type == 1) && instr->IsNopType1()) { - // NOP. + } else if ((type == 1) && instr->IsNopLikeType1()) { + if (instr->BitField(7, 0) == 0) { + // NOP. + } else if (instr->BitField(7, 0) == 20) { + // CSDB. + } else { + PrintF("%08x\n", instr->InstructionBits()); + UNIMPLEMENTED(); + } } else { int rd = instr->RdValue(); int rn = instr->RnValue(); @@ -5640,7 +5641,7 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { // Executes the current instruction. void Simulator::InstructionDecode(Instruction* instr) { if (v8::internal::FLAG_check_icache) { - CheckICache(isolate_->simulator_i_cache(), instr); + CheckICache(i_cache(), instr); } pc_modified_ = false; if (::v8::internal::FLAG_trace_sim) { @@ -5822,7 +5823,7 @@ intptr_t Simulator::CallImpl(byte* entry, int argument_count, return get_register(r0); } -int32_t Simulator::CallFPImpl(byte* entry, double d0, double d1) { +intptr_t Simulator::CallFPImpl(byte* entry, double d0, double d1) { if (use_eabi_hardfloat()) { set_d_register_from_double(0, d0); set_d_register_from_double(1, d1); diff --git a/deps/v8/src/arm/simulator-arm.h b/deps/v8/src/arm/simulator-arm.h index 1cb11ffd96..46a84ff4b4 100644 --- a/deps/v8/src/arm/simulator-arm.h +++ b/deps/v8/src/arm/simulator-arm.h @@ -183,6 +183,7 @@ class Simulator : public SimulatorBase { static void SetRedirectInstruction(Instruction* instruction); // ICache checking. + static bool ICacheMatch(void* one, void* two); static void FlushICache(base::CustomMatcherHashMap* i_cache, void* start, size_t size); @@ -381,9 +382,6 @@ class Simulator : public SimulatorBase { // Debugger input. char* last_debugger_input_; - // Icache simulation - base::CustomMatcherHashMap* i_cache_; - // Registered breakpoints. Instruction* break_pc_; Instr break_instr_; |