[simulator] Refactor redirections to be process-wide.
This refactors the list of redirections of runtime call targets that simulators maintain to be process-wide (as opposed to be per Isolate). Such redirections are used for static C++ call targets which themselves are process-wide, which makes this model a closer fit. Access is already properly synchronized via a mutex. Along the way this also introduces the {SimulatorBase} class as a common base class for all simulator implementations. R=clemensh@chromium.org Change-Id: Iae8602c44b1b34cb916dde2b22c9403b0496b3d4 Reviewed-on: https://chromium-review.googlesource.com/823966 Commit-Queue: Michael Starzinger <mstarzinger@chromium.org> Reviewed-by: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#50074}
This commit is contained in:
parent
1d1f52534e
commit
f4dde20044
2
BUILD.gn
2
BUILD.gn
@ -1994,6 +1994,8 @@ v8_source_set("v8_base") {
|
||||
"src/safepoint-table.h",
|
||||
"src/setup-isolate.h",
|
||||
"src/signature.h",
|
||||
"src/simulator-base.cc",
|
||||
"src/simulator-base.h",
|
||||
"src/simulator.h",
|
||||
"src/snapshot/builtin-deserializer-allocator.cc",
|
||||
"src/snapshot/builtin-deserializer-allocator.h",
|
||||
|
@ -640,14 +640,6 @@ void Simulator::CheckICache(base::CustomMatcherHashMap* i_cache,
|
||||
}
|
||||
|
||||
|
||||
void Simulator::Initialize(Isolate* isolate) {
|
||||
if (isolate->simulator_initialized()) return;
|
||||
isolate->set_simulator_initialized(true);
|
||||
::v8::internal::ExternalReference::set_redirector(isolate,
|
||||
&RedirectExternalReference);
|
||||
}
|
||||
|
||||
|
||||
Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
|
||||
i_cache_ = isolate_->simulator_i_cache();
|
||||
if (i_cache_ == nullptr) {
|
||||
@ -726,12 +718,11 @@ class Redirection {
|
||||
swi_instruction_(al | (0xF * B24) | kCallRtRedirected),
|
||||
type_(type),
|
||||
next_(nullptr) {
|
||||
next_ = isolate->simulator_redirection();
|
||||
Simulator::current(isolate)->
|
||||
FlushICache(isolate->simulator_i_cache(),
|
||||
next_ = Simulator::redirection();
|
||||
Simulator::FlushICache(isolate->simulator_i_cache(),
|
||||
reinterpret_cast<void*>(&swi_instruction_),
|
||||
Instruction::kInstrSize);
|
||||
isolate->set_simulator_redirection(this);
|
||||
Simulator::set_redirection(this);
|
||||
}
|
||||
|
||||
void* address_of_swi_instruction() {
|
||||
@ -743,7 +734,7 @@ class Redirection {
|
||||
|
||||
static Redirection* Get(Isolate* isolate, void* external_function,
|
||||
ExternalReference::Type type) {
|
||||
Redirection* current = isolate->simulator_redirection();
|
||||
Redirection* current = Simulator::redirection();
|
||||
for (; current != nullptr; current = current->next_) {
|
||||
if (current->external_function_ == external_function &&
|
||||
current->type_ == type) {
|
||||
@ -783,9 +774,16 @@ class Redirection {
|
||||
|
||||
|
||||
// static
|
||||
void Simulator::TearDown(base::CustomMatcherHashMap* i_cache,
|
||||
Redirection* first) {
|
||||
Redirection::DeleteChain(first);
|
||||
void SimulatorBase::GlobalTearDown() {
|
||||
delete redirection_mutex_;
|
||||
redirection_mutex_ = nullptr;
|
||||
|
||||
Redirection::DeleteChain(redirection_);
|
||||
redirection_ = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
void SimulatorBase::TearDown(base::CustomMatcherHashMap* i_cache) {
|
||||
if (i_cache != nullptr) {
|
||||
for (base::HashMap::Entry* entry = i_cache->Start(); entry != nullptr;
|
||||
entry = i_cache->Next(entry)) {
|
||||
@ -795,12 +793,10 @@ void Simulator::TearDown(base::CustomMatcherHashMap* i_cache,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void* Simulator::RedirectExternalReference(Isolate* isolate,
|
||||
void* SimulatorBase::RedirectExternalReference(Isolate* isolate,
|
||||
void* external_function,
|
||||
ExternalReference::Type type) {
|
||||
base::LockGuard<base::Mutex> lock_guard(
|
||||
isolate->simulator_redirection_mutex());
|
||||
base::LockGuard<base::Mutex> lock_guard(Simulator::redirection_mutex());
|
||||
Redirection* redirection = Redirection::Get(isolate, external_function, type);
|
||||
return redirection->address_of_swi_instruction();
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "src/arm/constants-arm.h"
|
||||
#include "src/assembler.h"
|
||||
#include "src/base/hashmap.h"
|
||||
#include "src/simulator-base.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -58,8 +59,7 @@ class CachePage {
|
||||
char validity_map_[kValidityMapSize]; // One byte per line.
|
||||
};
|
||||
|
||||
|
||||
class Simulator {
|
||||
class Simulator : public SimulatorBase {
|
||||
public:
|
||||
friend class ArmDebugger;
|
||||
enum Register {
|
||||
@ -159,11 +159,6 @@ class Simulator {
|
||||
// Executes ARM instructions until the PC reaches end_sim_pc.
|
||||
void Execute();
|
||||
|
||||
// Call on program start.
|
||||
static void Initialize(Isolate* isolate);
|
||||
|
||||
static void TearDown(base::CustomMatcherHashMap* i_cache, Redirection* first);
|
||||
|
||||
// V8 generally calls into generated JS code with 5 parameters and into
|
||||
// generated RegExp code with 7 parameters. This is a convenience function,
|
||||
// which sets up the simulator state and grabs the result on return.
|
||||
@ -325,11 +320,6 @@ class Simulator {
|
||||
static CachePage* GetCachePage(base::CustomMatcherHashMap* i_cache,
|
||||
void* page);
|
||||
|
||||
// Runtime call support. Uses the isolate in a thread-safe way.
|
||||
static void* RedirectExternalReference(
|
||||
Isolate* isolate, void* external_function,
|
||||
v8::internal::ExternalReference::Type type);
|
||||
|
||||
// Handle arguments and return value for runtime FP functions.
|
||||
void GetFpArgs(double* x, double* y, int32_t* z);
|
||||
void SetFpResult(const double& result);
|
||||
|
@ -98,13 +98,6 @@ SimSystemRegister SimSystemRegister::DefaultValueFor(SystemRegister id) {
|
||||
}
|
||||
|
||||
|
||||
void Simulator::Initialize(Isolate* isolate) {
|
||||
if (isolate->simulator_initialized()) return;
|
||||
isolate->set_simulator_initialized(true);
|
||||
ExternalReference::set_redirector(isolate, &RedirectExternalReference);
|
||||
}
|
||||
|
||||
|
||||
// Get the active Simulator for the current thread.
|
||||
Simulator* Simulator::current(Isolate* isolate) {
|
||||
Isolate::PerIsolateThreadData* isolate_data =
|
||||
@ -472,9 +465,9 @@ class Redirection {
|
||||
: external_function_(external_function), type_(type), next_(nullptr) {
|
||||
redirect_call_.SetInstructionBits(
|
||||
HLT | Assembler::ImmException(kImmExceptionIsRedirectedCall));
|
||||
next_ = isolate->simulator_redirection();
|
||||
next_ = Simulator::redirection();
|
||||
// TODO(all): Simulator flush I cache
|
||||
isolate->set_simulator_redirection(this);
|
||||
Simulator::set_redirection(this);
|
||||
}
|
||||
|
||||
void* address_of_redirect_call() {
|
||||
@ -488,7 +481,7 @@ class Redirection {
|
||||
|
||||
static Redirection* Get(Isolate* isolate, void* external_function,
|
||||
ExternalReference::Type type) {
|
||||
Redirection* current = isolate->simulator_redirection();
|
||||
Redirection* current = Simulator::redirection();
|
||||
for (; current != nullptr; current = current->next_) {
|
||||
if (current->external_function_ == external_function &&
|
||||
current->type_ == type) {
|
||||
@ -528,9 +521,17 @@ class Redirection {
|
||||
|
||||
|
||||
// static
|
||||
void Simulator::TearDown(base::CustomMatcherHashMap* i_cache,
|
||||
Redirection* first) {
|
||||
Redirection::DeleteChain(first);
|
||||
void SimulatorBase::GlobalTearDown() {
|
||||
delete redirection_mutex_;
|
||||
redirection_mutex_ = nullptr;
|
||||
|
||||
Redirection::DeleteChain(redirection_);
|
||||
redirection_ = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
void SimulatorBase::TearDown(base::CustomMatcherHashMap* i_cache) {
|
||||
// TODO(all): Simulator flush I cache
|
||||
}
|
||||
|
||||
|
||||
@ -761,12 +762,10 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
|
||||
set_pc(return_address);
|
||||
}
|
||||
|
||||
|
||||
void* Simulator::RedirectExternalReference(Isolate* isolate,
|
||||
void* SimulatorBase::RedirectExternalReference(Isolate* isolate,
|
||||
void* external_function,
|
||||
ExternalReference::Type type) {
|
||||
base::LockGuard<base::Mutex> lock_guard(
|
||||
isolate->simulator_redirection_mutex());
|
||||
base::LockGuard<base::Mutex> lock_guard(Simulator::redirection_mutex());
|
||||
Redirection* redirection = Redirection::Get(isolate, external_function, type);
|
||||
return redirection->address_of_redirect_call();
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "src/assembler.h"
|
||||
#include "src/base/compiler-specific.h"
|
||||
#include "src/globals.h"
|
||||
#include "src/simulator-base.h"
|
||||
#include "src/utils.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -636,7 +637,9 @@ class LogicVRegister {
|
||||
bool round_[kQRegSize];
|
||||
};
|
||||
|
||||
class Simulator : public DecoderVisitor {
|
||||
// Using multiple inheritance here is permitted because {DecoderVisitor} is a
|
||||
// pure interface class with only pure virtual methods.
|
||||
class Simulator : public DecoderVisitor, public SimulatorBase {
|
||||
public:
|
||||
static void FlushICache(base::CustomMatcherHashMap* i_cache, void* start,
|
||||
size_t size) {
|
||||
@ -652,10 +655,6 @@ class Simulator : public DecoderVisitor {
|
||||
|
||||
// System functions.
|
||||
|
||||
static void Initialize(Isolate* isolate);
|
||||
|
||||
static void TearDown(base::CustomMatcherHashMap* i_cache, Redirection* first);
|
||||
|
||||
static Simulator* current(v8::internal::Isolate* isolate);
|
||||
|
||||
class CallArgument;
|
||||
@ -762,10 +761,6 @@ class Simulator : public DecoderVisitor {
|
||||
|
||||
void ResetState();
|
||||
|
||||
// Runtime call support. Uses the isolate in a thread-safe way.
|
||||
static void* RedirectExternalReference(Isolate* isolate,
|
||||
void* external_function,
|
||||
ExternalReference::Type type);
|
||||
void DoRuntimeCall(Instruction* instr);
|
||||
|
||||
// Run the simulator.
|
||||
|
@ -2770,9 +2770,8 @@ Isolate::~Isolate() {
|
||||
allocator_ = nullptr;
|
||||
|
||||
#if USE_SIMULATOR
|
||||
Simulator::TearDown(simulator_i_cache_, simulator_redirection_);
|
||||
Simulator::TearDown(simulator_i_cache_);
|
||||
simulator_i_cache_ = nullptr;
|
||||
simulator_redirection_ = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -386,8 +386,7 @@ class ThreadLocalTop BASE_EMBEDDED {
|
||||
|
||||
#define ISOLATE_INIT_SIMULATOR_LIST(V) \
|
||||
V(bool, simulator_initialized, false) \
|
||||
V(base::CustomMatcherHashMap*, simulator_i_cache, nullptr) \
|
||||
V(Redirection*, simulator_redirection, nullptr)
|
||||
V(base::CustomMatcherHashMap*, simulator_i_cache, nullptr)
|
||||
#else
|
||||
|
||||
#define ISOLATE_INIT_SIMULATOR_LIST(V)
|
||||
@ -1327,9 +1326,6 @@ class Isolate {
|
||||
|
||||
#ifdef USE_SIMULATOR
|
||||
base::Mutex* simulator_i_cache_mutex() { return &simulator_i_cache_mutex_; }
|
||||
base::Mutex* simulator_redirection_mutex() {
|
||||
return &simulator_redirection_mutex_;
|
||||
}
|
||||
#endif
|
||||
|
||||
void set_allow_atomics_wait(bool set) { allow_atomics_wait_ = set; }
|
||||
@ -1665,7 +1661,6 @@ class Isolate {
|
||||
|
||||
#ifdef USE_SIMULATOR
|
||||
base::Mutex simulator_i_cache_mutex_;
|
||||
base::Mutex simulator_redirection_mutex_;
|
||||
#endif
|
||||
|
||||
bool allow_atomics_wait_;
|
||||
|
@ -878,14 +878,6 @@ void Simulator::CheckICache(base::CustomMatcherHashMap* i_cache,
|
||||
}
|
||||
|
||||
|
||||
void Simulator::Initialize(Isolate* isolate) {
|
||||
if (isolate->simulator_initialized()) return;
|
||||
isolate->set_simulator_initialized(true);
|
||||
::v8::internal::ExternalReference::set_redirector(isolate,
|
||||
&RedirectExternalReference);
|
||||
}
|
||||
|
||||
|
||||
Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
|
||||
i_cache_ = isolate_->simulator_i_cache();
|
||||
if (i_cache_ == nullptr) {
|
||||
@ -949,12 +941,11 @@ class Redirection {
|
||||
swi_instruction_(rtCallRedirInstr),
|
||||
type_(type),
|
||||
next_(nullptr) {
|
||||
next_ = isolate->simulator_redirection();
|
||||
Simulator::current(isolate)->
|
||||
FlushICache(isolate->simulator_i_cache(),
|
||||
next_ = Simulator::redirection();
|
||||
Simulator::FlushICache(isolate->simulator_i_cache(),
|
||||
reinterpret_cast<void*>(&swi_instruction_),
|
||||
Instruction::kInstrSize);
|
||||
isolate->set_simulator_redirection(this);
|
||||
Simulator::set_redirection(this);
|
||||
}
|
||||
|
||||
void* address_of_swi_instruction() {
|
||||
@ -966,7 +957,7 @@ class Redirection {
|
||||
|
||||
static Redirection* Get(Isolate* isolate, void* external_function,
|
||||
ExternalReference::Type type) {
|
||||
Redirection* current = isolate->simulator_redirection();
|
||||
Redirection* current = Simulator::redirection();
|
||||
for (; current != nullptr; current = current->next_) {
|
||||
if (current->external_function_ == external_function &&
|
||||
current->type_ == type) {
|
||||
@ -1006,9 +997,16 @@ class Redirection {
|
||||
|
||||
|
||||
// static
|
||||
void Simulator::TearDown(base::CustomMatcherHashMap* i_cache,
|
||||
Redirection* first) {
|
||||
Redirection::DeleteChain(first);
|
||||
void SimulatorBase::GlobalTearDown() {
|
||||
delete redirection_mutex_;
|
||||
redirection_mutex_ = nullptr;
|
||||
|
||||
Redirection::DeleteChain(redirection_);
|
||||
redirection_ = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
void SimulatorBase::TearDown(base::CustomMatcherHashMap* i_cache) {
|
||||
if (i_cache != nullptr) {
|
||||
for (base::CustomMatcherHashMap::Entry* entry = i_cache->Start();
|
||||
entry != nullptr; entry = i_cache->Next(entry)) {
|
||||
@ -1018,12 +1016,10 @@ void Simulator::TearDown(base::CustomMatcherHashMap* i_cache,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void* Simulator::RedirectExternalReference(Isolate* isolate,
|
||||
void* SimulatorBase::RedirectExternalReference(Isolate* isolate,
|
||||
void* external_function,
|
||||
ExternalReference::Type type) {
|
||||
base::LockGuard<base::Mutex> lock_guard(
|
||||
isolate->simulator_redirection_mutex());
|
||||
base::LockGuard<base::Mutex> lock_guard(Simulator::redirection_mutex());
|
||||
Redirection* redirection = Redirection::Get(isolate, external_function, type);
|
||||
return redirection->address_of_swi_instruction();
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "src/assembler.h"
|
||||
#include "src/base/hashmap.h"
|
||||
#include "src/simulator-base.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -91,7 +92,7 @@ class SimInstruction : public InstructionGetters<SimInstructionBase> {
|
||||
}
|
||||
};
|
||||
|
||||
class Simulator {
|
||||
class Simulator : public SimulatorBase {
|
||||
public:
|
||||
friend class MipsDebugger;
|
||||
|
||||
@ -236,11 +237,6 @@ class Simulator {
|
||||
// Executes MIPS instructions until the PC reaches end_sim_pc.
|
||||
void Execute();
|
||||
|
||||
// Call on program start.
|
||||
static void Initialize(Isolate* isolate);
|
||||
|
||||
static void TearDown(base::CustomMatcherHashMap* i_cache, Redirection* first);
|
||||
|
||||
// V8 generally calls into generated JS code with 5 parameters and into
|
||||
// generated RegExp code with 7 parameters. This is a convenience function,
|
||||
// which sets up the simulator state and grabs the result on return.
|
||||
@ -505,11 +501,6 @@ class Simulator {
|
||||
// Exceptions.
|
||||
void SignalException(Exception e);
|
||||
|
||||
// Runtime call support. Uses the isolate in a thread-safe way.
|
||||
static void* RedirectExternalReference(Isolate* isolate,
|
||||
void* external_function,
|
||||
ExternalReference::Type type);
|
||||
|
||||
// Handle arguments and return value for runtime FP functions.
|
||||
void GetFpArgs(double* x, double* y, int32_t* z);
|
||||
void SetFpResult(const double& result);
|
||||
|
@ -809,14 +809,6 @@ void Simulator::CheckICache(base::CustomMatcherHashMap* i_cache,
|
||||
}
|
||||
|
||||
|
||||
void Simulator::Initialize(Isolate* isolate) {
|
||||
if (isolate->simulator_initialized()) return;
|
||||
isolate->set_simulator_initialized(true);
|
||||
::v8::internal::ExternalReference::set_redirector(isolate,
|
||||
&RedirectExternalReference);
|
||||
}
|
||||
|
||||
|
||||
Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
|
||||
i_cache_ = isolate_->simulator_i_cache();
|
||||
if (i_cache_ == nullptr) {
|
||||
@ -882,12 +874,11 @@ class Redirection {
|
||||
swi_instruction_(rtCallRedirInstr),
|
||||
type_(type),
|
||||
next_(nullptr) {
|
||||
next_ = isolate->simulator_redirection();
|
||||
Simulator::current(isolate)->
|
||||
FlushICache(isolate->simulator_i_cache(),
|
||||
next_ = Simulator::redirection();
|
||||
Simulator::FlushICache(isolate->simulator_i_cache(),
|
||||
reinterpret_cast<void*>(&swi_instruction_),
|
||||
Instruction::kInstrSize);
|
||||
isolate->set_simulator_redirection(this);
|
||||
Simulator::set_redirection(this);
|
||||
}
|
||||
|
||||
void* address_of_swi_instruction() {
|
||||
@ -899,7 +890,7 @@ class Redirection {
|
||||
|
||||
static Redirection* Get(Isolate* isolate, void* external_function,
|
||||
ExternalReference::Type type) {
|
||||
Redirection* current = isolate->simulator_redirection();
|
||||
Redirection* current = Simulator::redirection();
|
||||
for (; current != nullptr; current = current->next_) {
|
||||
if (current->external_function_ == external_function &&
|
||||
current->type_ == type) {
|
||||
@ -939,9 +930,16 @@ class Redirection {
|
||||
|
||||
|
||||
// static
|
||||
void Simulator::TearDown(base::CustomMatcherHashMap* i_cache,
|
||||
Redirection* first) {
|
||||
Redirection::DeleteChain(first);
|
||||
void SimulatorBase::GlobalTearDown() {
|
||||
delete redirection_mutex_;
|
||||
redirection_mutex_ = nullptr;
|
||||
|
||||
Redirection::DeleteChain(redirection_);
|
||||
redirection_ = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
void SimulatorBase::TearDown(base::CustomMatcherHashMap* i_cache) {
|
||||
if (i_cache != nullptr) {
|
||||
for (base::HashMap::Entry* entry = i_cache->Start(); entry != nullptr;
|
||||
entry = i_cache->Next(entry)) {
|
||||
@ -951,12 +949,10 @@ void Simulator::TearDown(base::CustomMatcherHashMap* i_cache,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void* Simulator::RedirectExternalReference(Isolate* isolate,
|
||||
void* SimulatorBase::RedirectExternalReference(Isolate* isolate,
|
||||
void* external_function,
|
||||
ExternalReference::Type type) {
|
||||
base::LockGuard<base::Mutex> lock_guard(
|
||||
isolate->simulator_redirection_mutex());
|
||||
base::LockGuard<base::Mutex> lock_guard(Simulator::redirection_mutex());
|
||||
Redirection* redirection = Redirection::Get(isolate, external_function, type);
|
||||
return redirection->address_of_swi_instruction();
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "src/assembler.h"
|
||||
#include "src/base/hashmap.h"
|
||||
#include "src/simulator-base.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -91,7 +92,7 @@ class SimInstruction : public InstructionGetters<SimInstructionBase> {
|
||||
}
|
||||
};
|
||||
|
||||
class Simulator {
|
||||
class Simulator : public SimulatorBase {
|
||||
public:
|
||||
friend class MipsDebugger;
|
||||
|
||||
@ -238,11 +239,6 @@ class Simulator {
|
||||
// Executes MIPS instructions until the PC reaches end_sim_pc.
|
||||
void Execute();
|
||||
|
||||
// Call on program start.
|
||||
static void Initialize(Isolate* isolate);
|
||||
|
||||
static void TearDown(base::CustomMatcherHashMap* i_cache, Redirection* first);
|
||||
|
||||
// V8 generally calls into generated JS code with 5 parameters and into
|
||||
// generated RegExp code with 7 parameters. This is a convenience function,
|
||||
// which sets up the simulator state and grabs the result on return.
|
||||
@ -527,11 +523,6 @@ class Simulator {
|
||||
// Exceptions.
|
||||
void SignalException(Exception e);
|
||||
|
||||
// Runtime call support. Uses the isolate in a thread-safe way.
|
||||
static void* RedirectExternalReference(Isolate* isolate,
|
||||
void* external_function,
|
||||
ExternalReference::Type type);
|
||||
|
||||
// Handle arguments and return value for runtime FP functions.
|
||||
void GetFpArgs(double* x, double* y, int32_t* z);
|
||||
void SetFpResult(const double& result);
|
||||
|
@ -733,14 +733,6 @@ void Simulator::CheckICache(base::CustomMatcherHashMap* i_cache,
|
||||
}
|
||||
|
||||
|
||||
void Simulator::Initialize(Isolate* isolate) {
|
||||
if (isolate->simulator_initialized()) return;
|
||||
isolate->set_simulator_initialized(true);
|
||||
::v8::internal::ExternalReference::set_redirector(isolate,
|
||||
&RedirectExternalReference);
|
||||
}
|
||||
|
||||
|
||||
Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
|
||||
i_cache_ = isolate_->simulator_i_cache();
|
||||
if (i_cache_ == nullptr) {
|
||||
@ -807,11 +799,11 @@ class Redirection {
|
||||
swi_instruction_(rtCallRedirInstr | kCallRtRedirected),
|
||||
type_(type),
|
||||
next_(nullptr) {
|
||||
next_ = isolate->simulator_redirection();
|
||||
Simulator::current(isolate)->FlushICache(
|
||||
isolate->simulator_i_cache(),
|
||||
reinterpret_cast<void*>(&swi_instruction_), Instruction::kInstrSize);
|
||||
isolate->set_simulator_redirection(this);
|
||||
next_ = Simulator::redirection();
|
||||
Simulator::FlushICache(isolate->simulator_i_cache(),
|
||||
reinterpret_cast<void*>(&swi_instruction_),
|
||||
Instruction::kInstrSize);
|
||||
Simulator::set_redirection(this);
|
||||
if (ABI_USES_FUNCTION_DESCRIPTORS) {
|
||||
function_descriptor_[0] = reinterpret_cast<intptr_t>(&swi_instruction_);
|
||||
function_descriptor_[1] = 0;
|
||||
@ -832,7 +824,7 @@ class Redirection {
|
||||
|
||||
static Redirection* Get(Isolate* isolate, void* external_function,
|
||||
ExternalReference::Type type) {
|
||||
Redirection* current = isolate->simulator_redirection();
|
||||
Redirection* current = Simulator::redirection();
|
||||
for (; current != nullptr; current = current->next_) {
|
||||
if (current->external_function_ == external_function &&
|
||||
current->type_ == type) {
|
||||
@ -880,9 +872,16 @@ class Redirection {
|
||||
|
||||
|
||||
// static
|
||||
void Simulator::TearDown(base::CustomMatcherHashMap* i_cache,
|
||||
Redirection* first) {
|
||||
Redirection::DeleteChain(first);
|
||||
void SimulatorBase::GlobalTearDown() {
|
||||
delete redirection_mutex_;
|
||||
redirection_mutex_ = nullptr;
|
||||
|
||||
Redirection::DeleteChain(redirection_);
|
||||
redirection_ = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
void SimulatorBase::TearDown(base::CustomMatcherHashMap* i_cache) {
|
||||
if (i_cache != nullptr) {
|
||||
for (base::HashMap::Entry* entry = i_cache->Start(); entry != nullptr;
|
||||
entry = i_cache->Next(entry)) {
|
||||
@ -892,12 +891,10 @@ void Simulator::TearDown(base::CustomMatcherHashMap* i_cache,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void* Simulator::RedirectExternalReference(Isolate* isolate,
|
||||
void* SimulatorBase::RedirectExternalReference(Isolate* isolate,
|
||||
void* external_function,
|
||||
ExternalReference::Type type) {
|
||||
base::LockGuard<base::Mutex> lock_guard(
|
||||
isolate->simulator_redirection_mutex());
|
||||
base::LockGuard<base::Mutex> lock_guard(Simulator::redirection_mutex());
|
||||
Redirection* redirection = Redirection::Get(isolate, external_function, type);
|
||||
return redirection->address();
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "src/assembler.h"
|
||||
#include "src/base/hashmap.h"
|
||||
#include "src/ppc/constants-ppc.h"
|
||||
#include "src/simulator-base.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -51,8 +52,7 @@ class CachePage {
|
||||
char validity_map_[kValidityMapSize]; // One byte per line.
|
||||
};
|
||||
|
||||
|
||||
class Simulator {
|
||||
class Simulator : public SimulatorBase {
|
||||
public:
|
||||
friend class PPCDebugger;
|
||||
enum Register {
|
||||
@ -167,11 +167,6 @@ class Simulator {
|
||||
// Executes PPC instructions until the PC reaches end_sim_pc.
|
||||
void Execute();
|
||||
|
||||
// Call on program start.
|
||||
static void Initialize(Isolate* isolate);
|
||||
|
||||
static void TearDown(base::CustomMatcherHashMap* i_cache, Redirection* first);
|
||||
|
||||
// V8 generally calls into generated JS code with 5 parameters and into
|
||||
// generated RegExp code with 7 parameters. This is a convenience function,
|
||||
// which sets up the simulator state and grabs the result on return.
|
||||
@ -298,11 +293,6 @@ class Simulator {
|
||||
static CachePage* GetCachePage(base::CustomMatcherHashMap* i_cache,
|
||||
void* page);
|
||||
|
||||
// Runtime call support. Uses the isolate in a thread-safe way.
|
||||
static void* RedirectExternalReference(
|
||||
Isolate* isolate, void* external_function,
|
||||
v8::internal::ExternalReference::Type type);
|
||||
|
||||
// Handle arguments and return value for runtime FP functions.
|
||||
void GetFpArgs(double* x, double* y, intptr_t* z);
|
||||
void SetFpResult(const double& result);
|
||||
|
@ -728,15 +728,6 @@ void Simulator::CheckICache(base::CustomMatcherHashMap* i_cache,
|
||||
}
|
||||
}
|
||||
|
||||
void Simulator::Initialize(Isolate* isolate) {
|
||||
if (isolate->simulator_initialized()) return;
|
||||
isolate->set_simulator_initialized(true);
|
||||
::v8::internal::ExternalReference::set_redirector(isolate,
|
||||
&RedirectExternalReference);
|
||||
static base::OnceType once = V8_ONCE_INIT;
|
||||
base::CallOnce(&once, &Simulator::EvalTableInit);
|
||||
}
|
||||
|
||||
Simulator::EvaluateFuncType Simulator::EvalTable[] = {nullptr};
|
||||
|
||||
void Simulator::EvalTableInit() {
|
||||
@ -1494,6 +1485,8 @@ Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
|
||||
isolate_->set_simulator_i_cache(i_cache_);
|
||||
}
|
||||
Initialize(isolate);
|
||||
static base::OnceType once = V8_ONCE_INIT;
|
||||
base::CallOnce(&once, &Simulator::EvalTableInit);
|
||||
// Set up simulator support first. Some of this information is needed to
|
||||
// setup the architecture state.
|
||||
#if V8_TARGET_ARCH_S390X
|
||||
@ -1558,11 +1551,11 @@ class Redirection {
|
||||
#endif
|
||||
type_(type),
|
||||
next_(nullptr) {
|
||||
next_ = isolate->simulator_redirection();
|
||||
Simulator::current(isolate)->FlushICache(
|
||||
isolate->simulator_i_cache(),
|
||||
reinterpret_cast<void*>(&swi_instruction_), sizeof(FourByteInstr));
|
||||
isolate->set_simulator_redirection(this);
|
||||
next_ = Simulator::redirection();
|
||||
Simulator::FlushICache(isolate->simulator_i_cache(),
|
||||
reinterpret_cast<void*>(&swi_instruction_),
|
||||
sizeof(FourByteInstr));
|
||||
Simulator::set_redirection(this);
|
||||
if (ABI_USES_FUNCTION_DESCRIPTORS) {
|
||||
function_descriptor_[0] = reinterpret_cast<intptr_t>(&swi_instruction_);
|
||||
function_descriptor_[1] = 0;
|
||||
@ -1583,7 +1576,7 @@ class Redirection {
|
||||
|
||||
static Redirection* Get(Isolate* isolate, void* external_function,
|
||||
ExternalReference::Type type) {
|
||||
Redirection* current = isolate->simulator_redirection();
|
||||
Redirection* current = Simulator::redirection();
|
||||
for (; current != nullptr; current = current->next_) {
|
||||
if (current->external_function_ == external_function &&
|
||||
current->type_ == type) {
|
||||
@ -1630,9 +1623,16 @@ class Redirection {
|
||||
};
|
||||
|
||||
// static
|
||||
void Simulator::TearDown(base::CustomMatcherHashMap* i_cache,
|
||||
Redirection* first) {
|
||||
Redirection::DeleteChain(first);
|
||||
void SimulatorBase::GlobalTearDown() {
|
||||
delete redirection_mutex_;
|
||||
redirection_mutex_ = nullptr;
|
||||
|
||||
Redirection::DeleteChain(redirection_);
|
||||
redirection_ = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
void SimulatorBase::TearDown(base::CustomMatcherHashMap* i_cache) {
|
||||
if (i_cache != nullptr) {
|
||||
for (base::HashMap::Entry* entry = i_cache->Start(); entry != nullptr;
|
||||
entry = i_cache->Next(entry)) {
|
||||
@ -1642,11 +1642,10 @@ void Simulator::TearDown(base::CustomMatcherHashMap* i_cache,
|
||||
}
|
||||
}
|
||||
|
||||
void* Simulator::RedirectExternalReference(Isolate* isolate,
|
||||
void* SimulatorBase::RedirectExternalReference(Isolate* isolate,
|
||||
void* external_function,
|
||||
ExternalReference::Type type) {
|
||||
base::LockGuard<base::Mutex> lock_guard(
|
||||
isolate->simulator_redirection_mutex());
|
||||
base::LockGuard<base::Mutex> lock_guard(Simulator::redirection_mutex());
|
||||
Redirection* redirection = Redirection::Get(isolate, external_function, type);
|
||||
return redirection->address();
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "src/assembler.h"
|
||||
#include "src/base/hashmap.h"
|
||||
#include "src/s390/constants-s390.h"
|
||||
#include "src/simulator-base.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -50,7 +51,7 @@ class CachePage {
|
||||
char validity_map_[kValidityMapSize]; // One byte per line.
|
||||
};
|
||||
|
||||
class Simulator {
|
||||
class Simulator : public SimulatorBase {
|
||||
public:
|
||||
friend class S390Debugger;
|
||||
enum Register {
|
||||
@ -162,11 +163,6 @@ class Simulator {
|
||||
// Executes S390 instructions until the PC reaches end_sim_pc.
|
||||
void Execute();
|
||||
|
||||
// Call on program start.
|
||||
static void Initialize(Isolate* isolate);
|
||||
|
||||
static void TearDown(base::CustomMatcherHashMap* i_cache, Redirection* first);
|
||||
|
||||
// V8 generally calls into generated JS code with 5 parameters and into
|
||||
// generated RegExp code with 7 parameters. This is a convenience function,
|
||||
// which sets up the simulator state and grabs the result on return.
|
||||
@ -396,11 +392,6 @@ class Simulator {
|
||||
static CachePage* GetCachePage(base::CustomMatcherHashMap* i_cache,
|
||||
void* page);
|
||||
|
||||
// Runtime call support. Uses the isolate in a thread-safe way.
|
||||
static void* RedirectExternalReference(
|
||||
Isolate* isolate, void* external_function,
|
||||
v8::internal::ExternalReference::Type type);
|
||||
|
||||
// Handle arguments and return value for runtime FP functions.
|
||||
void GetFpArgs(double* x, double* y, intptr_t* z);
|
||||
void SetFpResult(const double& result);
|
||||
|
37
src/simulator-base.cc
Normal file
37
src/simulator-base.cc
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/simulator-base.h"
|
||||
|
||||
#include "src/assembler.h"
|
||||
#include "src/isolate.h"
|
||||
|
||||
#if defined(USE_SIMULATOR)
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// static
|
||||
base::Mutex* SimulatorBase::redirection_mutex_ = nullptr;
|
||||
|
||||
// static
|
||||
Redirection* SimulatorBase::redirection_ = nullptr;
|
||||
|
||||
// static
|
||||
void SimulatorBase::InitializeOncePerProcess() {
|
||||
DCHECK_NULL(redirection_mutex_);
|
||||
redirection_mutex_ = new base::Mutex();
|
||||
}
|
||||
|
||||
// static
|
||||
void SimulatorBase::Initialize(Isolate* isolate) {
|
||||
if (isolate->simulator_initialized()) return;
|
||||
isolate->set_simulator_initialized(true);
|
||||
ExternalReference::set_redirector(isolate, &RedirectExternalReference);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // defined(USE_SIMULATOR)
|
45
src/simulator-base.h
Normal file
45
src/simulator-base.h
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_SIMULATOR_BASE_H_
|
||||
#define V8_SIMULATOR_BASE_H_
|
||||
|
||||
#include "src/assembler.h"
|
||||
#include "src/globals.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class Redirection;
|
||||
|
||||
class SimulatorBase {
|
||||
public:
|
||||
// Call on process start and exit.
|
||||
static void InitializeOncePerProcess();
|
||||
// TODO(mstarzinger): Move implementation to "simulator-base.cc" file.
|
||||
static void GlobalTearDown();
|
||||
|
||||
// Call on isolate initialization and teardown.
|
||||
static void Initialize(Isolate* isolate);
|
||||
// TODO(mstarzinger): Move implementation to "simulator-base.cc" file.
|
||||
static void TearDown(base::CustomMatcherHashMap* i_cache);
|
||||
|
||||
static base::Mutex* redirection_mutex() { return redirection_mutex_; }
|
||||
static Redirection* redirection() { return redirection_; }
|
||||
static void set_redirection(Redirection* r) { redirection_ = r; }
|
||||
|
||||
private:
|
||||
// Runtime call support. Uses the isolate in a thread-safe way.
|
||||
static void* RedirectExternalReference(
|
||||
Isolate* isolate, void* external_function,
|
||||
v8::internal::ExternalReference::Type type);
|
||||
|
||||
static base::Mutex* redirection_mutex_;
|
||||
static Redirection* redirection_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_SIMULATOR_BASE_H_
|
@ -6,6 +6,7 @@
|
||||
#define V8_SIMULATOR_H_
|
||||
|
||||
#include "src/globals.h"
|
||||
#include "src/simulator-base.h"
|
||||
|
||||
#if V8_TARGET_ARCH_IA32
|
||||
#include "src/ia32/simulator-ia32.h"
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/profiler/heap-profiler.h"
|
||||
#include "src/runtime-profiler.h"
|
||||
#include "src/simulator.h"
|
||||
#include "src/snapshot/natives.h"
|
||||
#include "src/snapshot/snapshot.h"
|
||||
#include "src/tracing/tracing-category-observer.h"
|
||||
@ -42,6 +43,9 @@ bool V8::Initialize() {
|
||||
|
||||
|
||||
void V8::TearDown() {
|
||||
#if defined(USE_SIMULATOR)
|
||||
Simulator::GlobalTearDown();
|
||||
#endif
|
||||
Bootstrapper::TearDownExtensions();
|
||||
ElementsAccessor::TearDown();
|
||||
RegisteredExtension::UnregisterAll();
|
||||
@ -69,6 +73,9 @@ void V8::InitializeOncePerProcessImpl() {
|
||||
|
||||
Isolate::InitializeOncePerProcess();
|
||||
|
||||
#if defined(USE_SIMULATOR)
|
||||
Simulator::InitializeOncePerProcess();
|
||||
#endif
|
||||
sampler::Sampler::SetUp();
|
||||
CpuFeatures::Probe(false);
|
||||
ElementsAccessor::InitializeOncePerProcess();
|
||||
|
@ -1346,6 +1346,8 @@
|
||||
'safepoint-table.h',
|
||||
'setup-isolate.h',
|
||||
'signature.h',
|
||||
'simulator-base.cc',
|
||||
'simulator-base.h',
|
||||
'simulator.h',
|
||||
'snapshot/builtin-deserializer-allocator.cc',
|
||||
'snapshot/builtin-deserializer-allocator.h',
|
||||
|
Loading…
Reference in New Issue
Block a user