diff options
Diffstat (limited to 'deps/v8/src/arm64/simulator-arm64.cc')
-rw-r--r-- | deps/v8/src/arm64/simulator-arm64.cc | 157 |
1 files changed, 100 insertions, 57 deletions
diff --git a/deps/v8/src/arm64/simulator-arm64.cc b/deps/v8/src/arm64/simulator-arm64.cc index 5df4361c1b..aa36de4afa 100644 --- a/deps/v8/src/arm64/simulator-arm64.cc +++ b/deps/v8/src/arm64/simulator-arm64.cc @@ -2,17 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "src/arm64/simulator-arm64.h" + +#if defined(USE_SIMULATOR) + #include <stdlib.h> #include <cmath> #include <cstdarg> #include <type_traits> -#if V8_TARGET_ARCH_ARM64 - #include "src/arm64/decoder-arm64-inl.h" -#include "src/arm64/simulator-arm64.h" #include "src/assembler-inl.h" -#include "src/codegen.h" +#include "src/base/lazy-instance.h" #include "src/disasm.h" #include "src/macro-assembler.h" #include "src/objects-inl.h" @@ -22,8 +23,6 @@ namespace v8 { namespace internal { -#if defined(USE_SIMULATOR) - // This macro provides a platform independent use of sscanf. The reason for // SScanF not being implemented in a platform independent way through @@ -58,9 +57,8 @@ TEXT_COLOUR clr_debug_number = FLAG_log_colour ? COLOUR_BOLD(YELLOW) : ""; TEXT_COLOUR clr_debug_message = FLAG_log_colour ? COLOUR(YELLOW) : ""; TEXT_COLOUR clr_printf = FLAG_log_colour ? COLOUR(GREEN) : ""; -// static -base::LazyInstance<Simulator::GlobalMonitor>::type Simulator::global_monitor_ = - LAZY_INSTANCE_INITIALIZER; +DEFINE_LAZY_LEAKY_OBJECT_GETTER(Simulator::GlobalMonitor, + Simulator::GlobalMonitor::Get); // This is basically the same as PrintF, with a guard for FLAG_trace_sim. void Simulator::TraceSim(const char* format, ...) { @@ -277,7 +275,7 @@ uintptr_t Simulator::StackLimit(uintptr_t c_limit) const { // The simulator uses a separate JS stack. If we have exhausted the C stack, // we also drop down the JS limit to reflect the exhaustion on the JS stack. if (GetCurrentStackPosition() < c_limit) { - return reinterpret_cast<uintptr_t>(get_sp()); + return get_sp(); } // Otherwise the limit is the JS stack. Leave a safety margin of 1024 bytes @@ -332,7 +330,7 @@ void Simulator::Init(FILE* stream) { stack_limit_ = stack_ + stack_protection_size_; uintptr_t tos = stack_ + stack_size_ - stack_protection_size_; // The stack pointer must be 16-byte aligned. - set_sp(tos & ~0xFUL); + set_sp(tos & ~0xFULL); stream_ = stream; print_disasm_ = new PrintDisassembler(stream_); @@ -362,13 +360,13 @@ void Simulator::ResetState() { set_lr(kEndOfSimAddress); // Reset debug helpers. - breakpoints_.empty(); + breakpoints_.clear(); break_on_next_ = false; } Simulator::~Simulator() { - global_monitor_.Pointer()->RemoveProcessor(&global_monitor_processor_); + GlobalMonitor::Get()->RemoveProcessor(&global_monitor_processor_); delete[] reinterpret_cast<byte*>(stack_); if (FLAG_log_instruction_stats) { delete instrument_; @@ -403,6 +401,14 @@ void Simulator::RunFrom(Instruction* start) { // uses the ObjectPair structure. // The simulator assumes all runtime calls return two 64-bits values. If they // don't, register x1 is clobbered. This is fine because x1 is caller-saved. +#if defined(V8_OS_WIN) +typedef int64_t (*SimulatorRuntimeCall_ReturnPtr)(int64_t arg0, int64_t arg1, + int64_t arg2, int64_t arg3, + int64_t arg4, int64_t arg5, + int64_t arg6, int64_t arg7, + int64_t arg8); +#endif + typedef ObjectPair (*SimulatorRuntimeCall)(int64_t arg0, int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg5, @@ -464,12 +470,51 @@ void Simulator::DoRuntimeCall(Instruction* instr) { break; case ExternalReference::BUILTIN_CALL: +#if defined(V8_OS_WIN) + { + // Object f(v8::internal::Arguments). + TraceSim("Type: BUILTIN_CALL\n"); + + // When this simulator runs on Windows x64 host, function with ObjectPair + // return type accepts an implicit pointer to caller allocated memory for + // ObjectPair as return value. This diverges the calling convention from + // function which returns primitive type, so function returns ObjectPair + // and primitive type cannot share implementation. + + // We don't know how many arguments are being passed, but we can + // pass 8 without touching the stack. They will be ignored by the + // host function if they aren't used. + TraceSim( + "Arguments: " + "0x%016" PRIx64 ", 0x%016" PRIx64 + ", " + "0x%016" PRIx64 ", 0x%016" PRIx64 + ", " + "0x%016" PRIx64 ", 0x%016" PRIx64 + ", " + "0x%016" PRIx64 ", 0x%016" PRIx64 + ", " + "0x%016" PRIx64, + arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + + SimulatorRuntimeCall_ReturnPtr target = + reinterpret_cast<SimulatorRuntimeCall_ReturnPtr>(external); + + int64_t result = + target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + TraceSim("Returned: 0x%16\n", result); +#ifdef DEBUG + CorruptAllCallerSavedCPURegisters(); +#endif + set_xreg(0, result); + + break; + } +#endif case ExternalReference::BUILTIN_CALL_PAIR: { - // Object* f(v8::internal::Arguments) or + // Object f(v8::internal::Arguments) or // ObjectPair f(v8::internal::Arguments). TraceSim("Type: BUILTIN_CALL\n"); - SimulatorRuntimeCall target = - reinterpret_cast<SimulatorRuntimeCall>(external); // We don't know how many arguments are being passed, but we can // pass 8 without touching the stack. They will be ignored by the @@ -486,15 +531,17 @@ void Simulator::DoRuntimeCall(Instruction* instr) { ", " "0x%016" PRIx64, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + SimulatorRuntimeCall target = + reinterpret_cast<SimulatorRuntimeCall>(external); ObjectPair result = target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - TraceSim("Returned: {%p, %p}\n", static_cast<void*>(result.x), - static_cast<void*>(result.y)); + TraceSim("Returned: {%p, %p}\n", reinterpret_cast<void*>(result.x), + reinterpret_cast<void*>(result.y)); #ifdef DEBUG CorruptAllCallerSavedCPURegisters(); #endif - set_xreg(0, reinterpret_cast<int64_t>(result.x)); - set_xreg(1, reinterpret_cast<int64_t>(result.y)); + set_xreg(0, static_cast<int64_t>(result.x)); + set_xreg(1, static_cast<int64_t>(result.y)); break; } @@ -1489,7 +1536,7 @@ void Simulator::VisitUnconditionalBranchToRegister(Instruction* instr) { void Simulator::VisitTestBranch(Instruction* instr) { unsigned bit_pos = (instr->ImmTestBranchBit5() << 5) | instr->ImmTestBranchBit40(); - bool take_branch = ((xreg(instr->Rt()) & (1UL << bit_pos)) == 0); + bool take_branch = ((xreg(instr->Rt()) & (1ULL << bit_pos)) == 0); switch (instr->Mask(TestBranchMask)) { case TBZ: break; case TBNZ: take_branch = !take_branch; break; @@ -1731,12 +1778,12 @@ void Simulator::LoadStoreHelper(Instruction* instr, uintptr_t stack = 0; { - base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex); + base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); if (instr->IsLoad()) { local_monitor_.NotifyLoad(); } else { local_monitor_.NotifyStore(); - global_monitor_.Pointer()->NotifyStore_Locked(&global_monitor_processor_); + GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_processor_); } } @@ -1858,19 +1905,19 @@ void Simulator::LoadStorePairHelper(Instruction* instr, unsigned rt = instr->Rt(); unsigned rt2 = instr->Rt2(); unsigned addr_reg = instr->Rn(); - size_t access_size = 1 << instr->SizeLSPair(); + size_t access_size = 1ULL << instr->SizeLSPair(); int64_t offset = instr->ImmLSPair() * access_size; uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode); uintptr_t address2 = address + access_size; uintptr_t stack = 0; { - base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex); + base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); if (instr->IsLoad()) { local_monitor_.NotifyLoad(); } else { local_monitor_.NotifyStore(); - global_monitor_.Pointer()->NotifyStore_Locked(&global_monitor_processor_); + GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_processor_); } } @@ -2016,7 +2063,7 @@ void Simulator::VisitLoadLiteral(Instruction* instr) { unsigned rt = instr->Rt(); { - base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex); + base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyLoad(); } @@ -2107,12 +2154,12 @@ void Simulator::VisitLoadStoreAcquireRelease(Instruction* instr) { unsigned access_size = 1 << instr->LoadStoreXSizeLog2(); uintptr_t address = LoadStoreAddress(rn, 0, AddrMode::Offset); DCHECK_EQ(address % access_size, 0); - base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex); + base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); if (is_load != 0) { if (is_exclusive) { local_monitor_.NotifyLoadExcl(address, get_transaction_size(access_size)); - global_monitor_.Pointer()->NotifyLoadExcl_Locked( - address, &global_monitor_processor_); + GlobalMonitor::Get()->NotifyLoadExcl_Locked(address, + &global_monitor_processor_); } else { local_monitor_.NotifyLoad(); } @@ -2144,7 +2191,7 @@ void Simulator::VisitLoadStoreAcquireRelease(Instruction* instr) { DCHECK_NE(rs, rn); if (local_monitor_.NotifyStoreExcl(address, get_transaction_size(access_size)) && - global_monitor_.Pointer()->NotifyStoreExcl_Locked( + GlobalMonitor::Get()->NotifyStoreExcl_Locked( address, &global_monitor_processor_)) { switch (op) { case STLXR_b: @@ -2169,7 +2216,7 @@ void Simulator::VisitLoadStoreAcquireRelease(Instruction* instr) { } } else { local_monitor_.NotifyStore(); - global_monitor_.Pointer()->NotifyStore_Locked(&global_monitor_processor_); + GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_processor_); switch (op) { case STLR_b: MemoryWrite<uint8_t>(address, wreg(rt)); @@ -2266,7 +2313,7 @@ void Simulator::VisitConditionalSelect(Instruction* instr) { break; case CSNEG_w: case CSNEG_x: - new_val = -new_val; + new_val = (uint64_t)(-(int64_t)new_val); break; default: UNIMPLEMENTED(); } @@ -2396,14 +2443,14 @@ static int64_t MultiplyHighSigned(int64_t u, int64_t v) { uint64_t u0, v0, w0; int64_t u1, v1, w1, w2, t; - u0 = u & 0xFFFFFFFFL; + u0 = u & 0xFFFFFFFFLL; u1 = u >> 32; - v0 = v & 0xFFFFFFFFL; + v0 = v & 0xFFFFFFFFLL; v1 = v >> 32; w0 = u0 * v0; t = u1 * v0 + (w0 >> 32); - w1 = t & 0xFFFFFFFFL; + w1 = t & 0xFFFFFFFFLL; w2 = t >> 32; w1 = u0 * v1 + w1; @@ -2458,7 +2505,7 @@ void Simulator::BitfieldHelper(Instruction* instr) { mask = diff < reg_size - 1 ? (static_cast<T>(1) << (diff + 1)) - 1 : static_cast<T>(-1); } else { - uint64_t umask = ((1L << (S + 1)) - 1); + uint64_t umask = ((1LL << (S + 1)) - 1); umask = (umask >> R) | (umask << (reg_size - R)); mask = static_cast<T>(umask); diff += reg_size; @@ -2973,7 +3020,11 @@ void Simulator::VisitSystem(Instruction* instr) { default: UNIMPLEMENTED(); } } else if (instr->Mask(MemBarrierFMask) == MemBarrierFixed) { +#if defined(V8_OS_WIN) + MemoryBarrier(); +#else __sync_synchronize(); +#endif } else { UNIMPLEMENTED(); } @@ -3186,7 +3237,7 @@ void Simulator::Debug() { int64_t value; StdoutStream os; if (GetValue(arg1, &value)) { - Object* obj = reinterpret_cast<Object*>(value); + Object obj(value); os << arg1 << ": \n"; #ifdef DEBUG obj->Print(os); @@ -3239,16 +3290,12 @@ void Simulator::Debug() { while (cur < end) { PrintF(" 0x%016" PRIx64 ": 0x%016" PRIx64 " %10" PRId64, reinterpret_cast<uint64_t>(cur), *cur, *cur); - HeapObject* obj = reinterpret_cast<HeapObject*>(*cur); - int64_t value = *cur; + Object obj(*cur); Heap* current_heap = isolate_->heap(); - if (((value & 1) == 0) || - current_heap->ContainsSlow(obj->address())) { + if (obj.IsSmi() || current_heap->Contains(HeapObject::cast(obj))) { PrintF(" ("); - if ((value & kSmiTagMask) == 0) { - DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits()); - int32_t untagged = (value >> kSmiShift) & 0xFFFFFFFF; - PrintF("smi %" PRId32, untagged); + if (obj.IsSmi()) { + PrintF("smi %" PRId32, Smi::ToInt(obj)); } else { obj->ShortPrint(); } @@ -4483,12 +4530,12 @@ void Simulator::NEONLoadStoreMultiStructHelper(const Instruction* instr, } { - base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex); + base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); if (log_read) { local_monitor_.NotifyLoad(); } else { local_monitor_.NotifyStore(); - global_monitor_.Pointer()->NotifyStore_Locked(&global_monitor_processor_); + GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_processor_); } } @@ -4729,12 +4776,12 @@ void Simulator::NEONLoadStoreSingleStructHelper(const Instruction* instr, } { - base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex); + base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); if (do_load) { local_monitor_.NotifyLoad(); } else { local_monitor_.NotifyStore(); - global_monitor_.Pointer()->NotifyStore_Locked(&global_monitor_processor_); + GlobalMonitor::Get()->NotifyStore_Locked(&global_monitor_processor_); } } @@ -4797,7 +4844,7 @@ void Simulator::VisitNEONModifiedImmediate(Instruction* instr) { vform = q ? kFormat2D : kFormat1D; imm = 0; for (int i = 0; i < 8; ++i) { - if (imm8 & (1 << i)) { + if (imm8 & (1ULL << i)) { imm |= (UINT64_C(0xFF) << (8 * i)); } } @@ -5812,8 +5859,6 @@ bool Simulator::GlobalMonitor::Processor::NotifyStoreExcl_Locked( return false; } -Simulator::GlobalMonitor::GlobalMonitor() : head_(nullptr) {} - void Simulator::GlobalMonitor::NotifyLoadExcl_Locked(uintptr_t addr, Processor* processor) { processor->NotifyLoadExcl_Locked(addr); @@ -5863,7 +5908,7 @@ void Simulator::GlobalMonitor::PrependProcessor_Locked(Processor* processor) { } void Simulator::GlobalMonitor::RemoveProcessor(Processor* processor) { - base::LockGuard<base::Mutex> lock_guard(&mutex); + base::MutexGuard lock_guard(&mutex); if (!IsProcessorInLinkedList_Locked(processor)) { return; } @@ -5880,9 +5925,7 @@ void Simulator::GlobalMonitor::RemoveProcessor(Processor* processor) { processor->next_ = nullptr; } -#endif // USE_SIMULATOR - } // namespace internal } // namespace v8 -#endif // V8_TARGET_ARCH_ARM64 +#endif // USE_SIMULATOR |