aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/arm64/simulator-arm64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/arm64/simulator-arm64.cc')
-rw-r--r--deps/v8/src/arm64/simulator-arm64.cc157
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