[simulator] Refactor simulator I-cache to be process-wide.

This refactors the instruction cache simulation to now be maintained
process-wide (as opposed to be per Isolate). It prepares for allowing
to share code between Isolates (e.g. WebAssembly or shared builtins)
while still allowing to simulate execution of such shared code.

R=clemensh@chromium.org

Change-Id: I5a6f083f4e32597565dc646f13b4445014c0daaa
Reviewed-on: https://chromium-review.googlesource.com/909130
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51219}
This commit is contained in:
Michael Starzinger 2018-02-08 09:33:57 -08:00 committed by Commit Bot
parent 93114c47bd
commit 10474c1047
54 changed files with 134 additions and 203 deletions

View File

@ -339,7 +339,7 @@ void Assembler::set_target_address_at(Isolate* isolate, Address pc,
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 +357,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,7 +377,7 @@ 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);
}
}
}

View File

@ -5480,7 +5480,7 @@ void PatchingAssembler::Emit(Address addr) {
}
void PatchingAssembler::FlushICache(Isolate* isolate) {
Assembler::FlushICache(isolate, buffer_, buffer_size_ - kGap);
Assembler::FlushICache(buffer_, buffer_size_ - kGap);
}
UseScratchRegisterScope::UseScratchRegisterScope(Assembler* assembler)

View File

@ -168,7 +168,7 @@ MemCopyUint8Function CreateMemCopyUint8Function(Isolate* isolate,
masm.GetCode(isolate, &desc);
DCHECK(!RelocInfo::RequiresRelocation(isolate, 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
@ -284,7 +284,7 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
masm.GetCode(isolate, &desc);
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
CHECK(SetPermissions(buffer, allocated, PageAllocator::kReadExecute));
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
#endif

View File

@ -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
@ -5640,7 +5634,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) {

View File

@ -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_;

View File

@ -595,7 +595,7 @@ void Assembler::set_target_address_at(Isolate* isolate, Address pc,
Memory::Address_at(target_pointer_address_at(pc)) = 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, an instruction is actually patched in the case of
// embedded constants of the form:
// ldr ip, [pc, #...]

View File

@ -3703,7 +3703,7 @@ class PatchingAssembler : public Assembler {
DCHECK(IsConstPoolEmpty());
// Flush the Instruction cache.
size_t length = buffer_size_ - kGap;
if (isolate_ != nullptr) Assembler::FlushICache(isolate_, buffer_, length);
if (isolate_ != nullptr) Assembler::FlushICache(buffer_, length);
}
// See definition of PatchAdrFar() for details.

View File

@ -646,6 +646,7 @@ class LogicVRegister {
class Simulator : public DecoderVisitor, public SimulatorBase {
public:
static void SetRedirectInstruction(Instruction* instruction);
static bool ICacheMatch(void* one, void* two) { return false; }
static void FlushICache(base::CustomMatcherHashMap* i_cache, void* start,
size_t size) {
USE(i_cache);

View File

@ -176,12 +176,12 @@ AssemblerBase::~AssemblerBase() {
if (own_buffer_) DeleteArray(buffer_);
}
void AssemblerBase::FlushICache(Isolate* isolate, void* start, size_t size) {
void AssemblerBase::FlushICache(void* start, size_t size) {
if (size == 0) return;
#if defined(USE_SIMULATOR)
base::LockGuard<base::Mutex> lock_guard(isolate->simulator_i_cache_mutex());
Simulator::FlushICache(isolate->simulator_i_cache(), start, size);
base::LockGuard<base::Mutex> lock_guard(Simulator::i_cache_mutex());
Simulator::FlushICache(Simulator::i_cache(), start, size);
#else
CpuFeatures::FlushICache(start, size);
#endif // USE_SIMULATOR

View File

@ -163,7 +163,7 @@ class AssemblerBase: public Malloced {
static const int kMinimalBufferSize = 4*KB;
static void FlushICache(Isolate* isolate, void* start, size_t size);
static void FlushICache(void* start, size_t size);
protected:
// The buffer into which code and relocation info are generated. It could
@ -801,9 +801,7 @@ class ExternalReference BASE_EMBEDDED {
static void SetUp();
// These functions must use the isolate in a thread-safe way.
typedef void* ExternalReferenceRedirector(Isolate* isolate, void* original,
Type type);
typedef void* ExternalReferenceRedirector(void* original, Type type);
ExternalReference() : address_(nullptr) {}
@ -1074,9 +1072,8 @@ class ExternalReference BASE_EMBEDDED {
reinterpret_cast<ExternalReferenceRedirector*>(
isolate->external_reference_redirector());
void* address = reinterpret_cast<void*>(address_arg);
void* answer = (redirector == nullptr)
? address
: (*redirector)(isolate, address, type);
void* answer =
(redirector == nullptr) ? address : (*redirector)(address, type);
return answer;
}

View File

@ -202,7 +202,7 @@ void SetupIsolateDelegate::ReplacePlaceholders(Isolate* isolate) {
flush_icache = true;
}
if (flush_icache) {
Assembler::FlushICache(isolate, code->instruction_start(),
Assembler::FlushICache(code->instruction_start(),
code->instruction_size());
}
}

View File

@ -105,7 +105,7 @@ void RelocInfo::set_target_object(HeapObject* target,
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
Memory::Object_at(pc_) = target;
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(target->GetIsolate(), pc_, sizeof(Address));
Assembler::FlushICache(pc_, sizeof(Address));
}
if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != nullptr) {
host()->GetHeap()->RecordWriteIntoCode(host(), this, target);
@ -165,7 +165,7 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitEmbeddedPointer(host(), this);
Assembler::FlushICache(isolate, pc_, sizeof(Address));
Assembler::FlushICache(pc_, sizeof(Address));
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(host(), this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
@ -257,7 +257,7 @@ void Assembler::set_target_address_at(Isolate* isolate, Address pc,
int32_t* p = reinterpret_cast<int32_t*>(pc);
*p = target - (pc + sizeof(int32_t));
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate, p, sizeof(int32_t));
Assembler::FlushICache(p, sizeof(int32_t));
}
}

View File

@ -211,7 +211,7 @@ void RelocInfo::set_embedded_address(Isolate* isolate, Address address,
ICacheFlushMode icache_flush_mode) {
Memory::Address_at(pc_) = address;
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate, pc_, sizeof(Address));
Assembler::FlushICache(pc_, sizeof(Address));
}
}
@ -219,7 +219,7 @@ void RelocInfo::set_embedded_size(Isolate* isolate, uint32_t size,
ICacheFlushMode icache_flush_mode) {
Memory::uint32_at(pc_) = size;
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate, pc_, sizeof(uint32_t));
Assembler::FlushICache(pc_, sizeof(uint32_t));
}
}

View File

@ -37,7 +37,7 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
masm.GetCode(isolate, &desc);
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
CHECK(SetPermissions(buffer, allocated, PageAllocator::kReadExecute));
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
}
@ -448,7 +448,7 @@ MemMoveFunction CreateMemMoveFunction(Isolate* isolate) {
CodeDesc desc;
masm.GetCode(isolate, &desc);
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
CHECK(SetPermissions(buffer, allocated, PageAllocator::kReadExecute));
// TODO(jkummerow): It would be nice to register this code creation event
// with the PROFILE / GDBJIT system.

View File

@ -2771,11 +2771,6 @@ Isolate::~Isolate() {
delete allocator_;
allocator_ = nullptr;
#if USE_SIMULATOR
Simulator::TearDown(simulator_i_cache_);
simulator_i_cache_ = nullptr;
#endif
}

View File

@ -380,17 +380,6 @@ class ThreadLocalTop BASE_EMBEDDED {
};
#if USE_SIMULATOR
#define ISOLATE_INIT_SIMULATOR_LIST(V) \
V(base::CustomMatcherHashMap*, simulator_i_cache, nullptr)
#else
#define ISOLATE_INIT_SIMULATOR_LIST(V)
#endif
#ifdef DEBUG
#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V) \
@ -451,8 +440,7 @@ typedef std::vector<HeapObject*> DebugObjectCache;
V(debug::Coverage::Mode, code_coverage_mode, debug::Coverage::kBestEffort) \
V(debug::TypeProfile::Mode, type_profile_mode, debug::TypeProfile::kNone) \
V(int, last_stack_frame_info_id, 0) \
V(int, last_console_context_id, 0) \
ISOLATE_INIT_SIMULATOR_LIST(V)
V(int, last_console_context_id, 0)
#define THREAD_LOCAL_TOP_ACCESSOR(type, name) \
inline void set_##name(type v) { thread_local_top_.name##_ = v; } \
@ -1310,10 +1298,6 @@ class Isolate {
PRINTF_FORMAT(2, 3) void PrintWithTimestamp(const char* format, ...);
#ifdef USE_SIMULATOR
base::Mutex* simulator_i_cache_mutex() { return &simulator_i_cache_mutex_; }
#endif
void set_allow_atomics_wait(bool set) { allow_atomics_wait_ = set; }
bool allow_atomics_wait() { return allow_atomics_wait_; }
@ -1647,10 +1631,6 @@ class Isolate {
v8::Isolate::AbortOnUncaughtExceptionCallback
abort_on_uncaught_exception_callback_;
#ifdef USE_SIMULATOR
base::Mutex simulator_i_cache_mutex_;
#endif
bool allow_atomics_wait_;
ManagedObjectFinalizer managed_object_finalizers_list_;

View File

@ -3933,7 +3933,7 @@ void Assembler::set_target_value_at(Isolate* isolate, Address pc,
}
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate, pc, 2 * sizeof(int32_t));
Assembler::FlushICache(pc, 2 * sizeof(int32_t));
}
}

View File

@ -543,7 +543,7 @@ MemCopyUint8Function CreateMemCopyUint8Function(Isolate* isolate,
masm.GetCode(isolate, &desc);
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
CHECK(SetPermissions(buffer, allocated, PageAllocator::kReadExecute));
return FUNCTION_CAST<MemCopyUint8Function>(buffer);
#endif
@ -570,7 +570,7 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
masm.GetCode(isolate, &desc);
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
CHECK(SetPermissions(buffer, allocated, PageAllocator::kReadExecute));
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
#endif

View File

@ -783,8 +783,7 @@ void MipsDebugger::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;
@ -883,11 +882,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.
stack_ = reinterpret_cast<char*>(malloc(stack_size_));
@ -6912,7 +6906,7 @@ void Simulator::DecodeTypeJump() {
// 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;
v8::internal::EmbeddedVector<char, 256> buffer;

View File

@ -258,6 +258,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);
@ -538,9 +539,6 @@ class Simulator : public SimulatorBase {
// Debugger input.
char* last_debugger_input_;
// Icache simulation.
base::CustomMatcherHashMap* i_cache_;
v8::internal::Isolate* isolate_;
// Registered breakpoints.

View File

@ -4258,7 +4258,7 @@ void Assembler::set_target_value_at(Isolate* isolate, Address pc,
(target & kImm16Mask);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate, pc, 4 * Assembler::kInstrSize);
Assembler::FlushICache(pc, 4 * Assembler::kInstrSize);
}
}

View File

@ -544,7 +544,7 @@ MemCopyUint8Function CreateMemCopyUint8Function(Isolate* isolate,
masm.GetCode(isolte, &desc);
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
CHECK(SetPermissions(buffer, allocated, PageAllocator::kReadExecute));
return FUNCTION_CAST<MemCopyUint8Function>(buffer);
#endif
@ -571,7 +571,7 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
masm.GetCode(isolate, &desc);
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
CHECK(SetPermissions(buffer, allocated, PageAllocator::kReadExecute));
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
#endif

View File

@ -715,8 +715,7 @@ void MipsDebugger::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;
@ -814,11 +813,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.
stack_size_ = FLAG_sim_stack_size * KB;
@ -7260,7 +7254,7 @@ void Simulator::DecodeTypeJump() {
// 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;

View File

@ -260,6 +260,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);
@ -559,9 +560,6 @@ class Simulator : public SimulatorBase {
// Debugger input.
char* last_debugger_input_;
// Icache simulation.
base::CustomMatcherHashMap* i_cache_;
v8::internal::Isolate* isolate_;
// Registered breakpoints.

View File

@ -14010,7 +14010,7 @@ void Code::Relocate(intptr_t delta) {
for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) {
it.rinfo()->apply(delta);
}
Assembler::FlushICache(GetIsolate(), instruction_start(), instruction_size());
Assembler::FlushICache(instruction_start(), instruction_size());
}
@ -14062,7 +14062,7 @@ void Code::CopyFrom(const CodeDesc& desc) {
it.rinfo()->apply(delta);
}
}
Assembler::FlushICache(GetIsolate(), instruction_start(), instruction_size());
Assembler::FlushICache(instruction_start(), instruction_size());
}

View File

@ -476,7 +476,7 @@ void Assembler::set_target_address_at(Isolate* isolate, Address pc,
*(p + 3) = instr4;
*(p + 4) = instr5;
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate, p, 5 * kInstrSize);
Assembler::FlushICache(p, 5 * kInstrSize);
}
#else
uint32_t* p = reinterpret_cast<uint32_t*>(pc);
@ -491,7 +491,7 @@ void Assembler::set_target_address_at(Isolate* isolate, Address pc,
*p = instr1;
*(p + 1) = instr2;
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate, p, 2 * kInstrSize);
Assembler::FlushICache(p, 2 * kInstrSize);
}
#endif
return;

View File

@ -2151,7 +2151,7 @@ PatchingAssembler::~PatchingAssembler() {
}
void PatchingAssembler::FlushICache(Isolate* isolate) {
Assembler::FlushICache(isolate, buffer_, buffer_size_ - kGap);
Assembler::FlushICache(buffer_, buffer_size_ - kGap);
}
} // namespace internal

View File

@ -39,7 +39,7 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
DCHECK(ABI_USES_FUNCTION_DESCRIPTORS ||
!RelocInfo::RequiresRelocation(isolate, desc));
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
CHECK(SetPermissions(buffer, allocated, PageAllocator::kReadExecute));
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
#endif

View File

@ -1684,7 +1684,7 @@ void TurboAssembler::Abort(AbortReason reason) {
Label abort_start;
bind(&abort_start);
#ifdef DEBUG
const char* msg = GetBailoutReason(reason);
const char* msg = GetAbortReason(reason);
if (msg != nullptr) {
RecordComment("Abort message: ");
RecordComment(msg);

View File

@ -639,8 +639,7 @@ void PPCDebugger::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;
@ -738,11 +737,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.
#if V8_TARGET_ARCH_PPC64
@ -3916,7 +3910,7 @@ void Simulator::Trace(Instruction* instr) {
// Executes the current instruction.
void Simulator::ExecuteInstruction(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) {

View File

@ -190,6 +190,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);
@ -328,9 +329,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_;

View File

@ -315,7 +315,7 @@ void Assembler::set_target_address_at(Isolate* isolate, Address pc,
Instruction::SetInstructionBits<SixByteInstr>(reinterpret_cast<byte*>(pc),
instr_1);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate, pc, 6);
Assembler::FlushICache(pc, 6);
}
patched = true;
} else {
@ -344,7 +344,7 @@ void Assembler::set_target_address_at(Isolate* isolate, Address pc,
Instruction::SetInstructionBits<SixByteInstr>(
reinterpret_cast<byte*>(pc + instr1_length), instr_2);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate, pc, 12);
Assembler::FlushICache(pc, 12);
}
patched = true;
}
@ -358,7 +358,7 @@ void Assembler::set_target_address_at(Isolate* isolate, Address pc,
Instruction::SetInstructionBits<SixByteInstr>(reinterpret_cast<byte*>(pc),
instr_1);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate, pc, 6);
Assembler::FlushICache(pc, 6);
}
patched = true;
}

View File

@ -36,7 +36,7 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
DCHECK(ABI_USES_FUNCTION_DESCRIPTORS ||
!RelocInfo::RequiresRelocation(isolate, desc));
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
CHECK(SetPermissions(buffer, allocated, PageAllocator::kReadExecute));
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
#endif

View File

@ -640,7 +640,7 @@ void S390Debugger::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;
@ -1488,11 +1488,6 @@ void Simulator::EvalTableInit() {
} // NOLINT
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_);
}
static base::OnceType once = V8_ONCE_INIT;
base::CallOnce(&once, &Simulator::EvalTableInit);
// Set up simulator support first. Some of this information is needed to
@ -2332,7 +2327,7 @@ void Simulator::ExecuteInstruction(Instruction* instr, bool auto_incr_pc) {
icount_++;
if (v8::internal::FLAG_check_icache) {
CheckICache(isolate_->simulator_i_cache(), instr);
CheckICache(i_cache(), instr);
}
pc_modified_ = false;

View File

@ -187,6 +187,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);
@ -425,9 +426,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_;

View File

@ -19,10 +19,22 @@ base::Mutex* SimulatorBase::redirection_mutex_ = nullptr;
// static
Redirection* SimulatorBase::redirection_ = nullptr;
// static
base::Mutex* SimulatorBase::i_cache_mutex_ = nullptr;
// static
base::CustomMatcherHashMap* SimulatorBase::i_cache_ = nullptr;
// static
void SimulatorBase::InitializeOncePerProcess() {
DCHECK_NULL(redirection_mutex_);
redirection_mutex_ = new base::Mutex();
DCHECK_NULL(i_cache_mutex_);
i_cache_mutex_ = new base::Mutex();
DCHECK_NULL(i_cache_);
i_cache_ = new base::CustomMatcherHashMap(&Simulator::ICacheMatch);
}
// static
@ -32,6 +44,18 @@ void SimulatorBase::GlobalTearDown() {
Redirection::DeleteChain(redirection_);
redirection_ = nullptr;
delete i_cache_mutex_;
i_cache_mutex_ = nullptr;
if (i_cache_ != nullptr) {
for (base::HashMap::Entry* entry = i_cache_->Start(); entry != nullptr;
entry = i_cache_->Next(entry)) {
delete static_cast<CachePage*>(entry->value);
}
}
delete i_cache_;
i_cache_ = nullptr;
}
// static
@ -40,32 +64,19 @@ void SimulatorBase::Initialize(Isolate* isolate) {
}
// 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)) {
delete static_cast<CachePage*>(entry->value);
}
delete i_cache;
}
}
// static
void* SimulatorBase::RedirectExternalReference(Isolate* isolate,
void* external_function,
void* SimulatorBase::RedirectExternalReference(void* external_function,
ExternalReference::Type type) {
base::LockGuard<base::Mutex> lock_guard(Simulator::redirection_mutex());
Redirection* redirection = Redirection::Get(isolate, external_function, type);
Redirection* redirection = Redirection::Get(external_function, type);
return redirection->address_of_instruction();
}
Redirection::Redirection(Isolate* isolate, void* external_function,
ExternalReference::Type type)
Redirection::Redirection(void* external_function, ExternalReference::Type type)
: external_function_(external_function), type_(type), next_(nullptr) {
next_ = Simulator::redirection();
Simulator::SetRedirectInstruction(
reinterpret_cast<Instruction*>(address_of_instruction()));
Simulator::FlushICache(isolate->simulator_i_cache(),
Simulator::FlushICache(Simulator::i_cache(),
reinterpret_cast<void*>(&instruction_),
sizeof(instruction_));
Simulator::set_redirection(this);
@ -77,7 +88,7 @@ Redirection::Redirection(Isolate* isolate, void* external_function,
}
// static
Redirection* Redirection::Get(Isolate* isolate, void* external_function,
Redirection* Redirection::Get(void* external_function,
ExternalReference::Type type) {
Redirection* current = Simulator::redirection();
for (; current != nullptr; current = current->next_) {
@ -86,7 +97,7 @@ Redirection* Redirection::Get(Isolate* isolate, void* external_function,
return current;
}
}
return new Redirection(isolate, external_function, type);
return new Redirection(external_function, type);
}
} // namespace internal

View File

@ -24,14 +24,16 @@ class SimulatorBase {
static void InitializeOncePerProcess();
static void GlobalTearDown();
// Call on isolate initialization and teardown.
// Call on isolate initialization.
static void Initialize(Isolate* isolate);
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; }
static base::Mutex* i_cache_mutex() { return i_cache_mutex_; }
static base::CustomMatcherHashMap* i_cache() { return i_cache_; }
protected:
template <typename Return, typename SimT, typename CallImpl, typename... Args>
static Return VariadicCall(SimT* sim, CallImpl call, byte* entry,
@ -44,14 +46,16 @@ class SimulatorBase {
}
private:
// Runtime call support. Uses the isolate in a thread-safe way.
static void* RedirectExternalReference(Isolate* isolate,
void* external_function,
// Runtime call support.
static void* RedirectExternalReference(void* external_function,
ExternalReference::Type type);
static base::Mutex* redirection_mutex_;
static Redirection* redirection_;
static base::Mutex* i_cache_mutex_;
static base::CustomMatcherHashMap* i_cache_;
// Helper methods to convert arbitrary integer or pointer arguments to the
// needed generic argument type intptr_t.
@ -117,8 +121,7 @@ class SimulatorBase {
// - V8_TARGET_ARCH_S390: svc (Supervisor Call)
class Redirection {
public:
Redirection(Isolate* isolate, void* external_function,
ExternalReference::Type type);
Redirection(void* external_function, ExternalReference::Type type);
Address address_of_instruction() {
#if ABI_USES_FUNCTION_DESCRIPTORS
@ -131,7 +134,7 @@ class Redirection {
void* external_function() { return external_function_; }
ExternalReference::Type type() { return type_; }
static Redirection* Get(Isolate* isolate, void* external_function,
static Redirection* Get(void* external_function,
ExternalReference::Type type);
static Redirection* FromInstruction(Instruction* instruction) {

View File

@ -136,8 +136,7 @@ Code* BuiltinDeserializer::DeserializeBuiltinRaw(int builtin_id) {
// Flush the instruction cache.
Code* code = Code::cast(o);
Assembler::FlushICache(isolate(), code->instruction_start(),
code->instruction_size());
Assembler::FlushICache(code->instruction_start(), code->instruction_size());
return code;
}
@ -161,8 +160,7 @@ Code* BuiltinDeserializer::DeserializeHandlerRaw(Bytecode bytecode,
// Flush the instruction cache.
Code* code = Code::cast(o);
Assembler::FlushICache(isolate(), code->instruction_start(),
code->instruction_size());
Assembler::FlushICache(code->instruction_start(), code->instruction_size());
return code;
}

View File

@ -93,8 +93,7 @@ void ObjectDeserializer::
for (Code* code : new_code_objects()) {
// Record all references to embedded objects in the new code object.
isolate()->heap()->RecordWritesIntoCode(code);
Assembler::FlushICache(isolate(), code->instruction_start(),
code->instruction_size());
Assembler::FlushICache(code->instruction_start(), code->instruction_size());
}
}

View File

@ -78,8 +78,7 @@ void StartupDeserializer::FlushICacheForNewIsolate() {
DCHECK(!deserializing_user_code());
// The entire isolate is newly deserialized. Simply flush all code pages.
for (Page* p : *isolate()->heap()->code_space()) {
Assembler::FlushICache(isolate(), p->area_start(),
p->area_end() - p->area_start());
Assembler::FlushICache(p->area_start(), p->area_end() - p->area_start());
}
}

View File

@ -785,7 +785,7 @@ const wasm::WasmCode* LazyCompilationOrchestrator::CompileFunction(
if (!code_wrapper.IsCodeObject()) {
const wasm::WasmCode* wasm_code = code_wrapper.GetWasmCode();
Assembler::FlushICache(isolate, wasm_code->instructions().start(),
Assembler::FlushICache(wasm_code->instructions().start(),
wasm_code->instructions().size());
counters->wasm_generated_code_size()->Increment(
static_cast<int>(wasm_code->instructions().size()));
@ -793,8 +793,7 @@ const wasm::WasmCode* LazyCompilationOrchestrator::CompileFunction(
static_cast<int>(wasm_code->reloc_info().size()));
} else {
Assembler::FlushICache(isolate, code->instruction_start(),
code->instruction_size());
Assembler::FlushICache(code->instruction_start(), code->instruction_size());
counters->wasm_generated_code_size()->Increment(code->body_size());
counters->wasm_reloc_size()->Increment(code->relocation_info()->length());
}
@ -1530,21 +1529,20 @@ bool compile_lazy(const WasmModule* module) {
(FLAG_asm_wasm_lazy_compilation && module->is_asm_js());
}
void FlushICache(Isolate* isolate, const wasm::NativeModule* native_module) {
void FlushICache(const wasm::NativeModule* native_module) {
for (uint32_t i = 0, e = native_module->FunctionCount(); i < e; ++i) {
const wasm::WasmCode* code = native_module->GetCode(i);
if (code == nullptr) continue;
Assembler::FlushICache(isolate, code->instructions().start(),
Assembler::FlushICache(code->instructions().start(),
code->instructions().size());
}
}
void FlushICache(Isolate* isolate, Handle<FixedArray> functions) {
void FlushICache(Handle<FixedArray> functions) {
for (int i = 0, e = functions->length(); i < e; ++i) {
if (!functions->get(i)->IsCode()) continue;
Code* code = Code::cast(functions->get(i));
Assembler::FlushICache(isolate, code->instruction_start(),
code->instruction_size());
Assembler::FlushICache(code->instruction_start(), code->instruction_size());
}
}
@ -2375,11 +2373,11 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
code_specialization.ApplyToWholeInstance(*instance, SKIP_ICACHE_FLUSH);
if (FLAG_wasm_jit_to_native) {
FlushICache(isolate_, native_module);
FlushICache(native_module);
} else {
FlushICache(isolate_, code_table);
FlushICache(code_table);
}
FlushICache(isolate_, wrapper_table);
FlushICache(wrapper_table);
//--------------------------------------------------------------------------
// Unpack and notify signal handler of protected instructions.

View File

@ -344,8 +344,8 @@ WasmCode* NativeModule::AddOwnedCode(
auto insert_before = std::upper_bound(owned_code_.begin(), owned_code_.end(),
code, owned_code_comparer_);
owned_code_.insert(insert_before, std::move(code));
wasm_code_manager_->FlushICache(ret->instructions().start(),
ret->instructions().size());
Assembler::FlushICache(ret->instructions().start(),
ret->instructions().size());
return ret;
}
@ -1011,11 +1011,6 @@ intptr_t WasmCodeManager::remaining_uncommitted() const {
return remaining_uncommitted_.Value();
}
void WasmCodeManager::FlushICache(Address start, size_t size) {
Assembler::FlushICache(reinterpret_cast<internal::Isolate*>(isolate_), start,
size);
}
NativeModuleModificationScope::NativeModuleModificationScope(
NativeModule* native_module)
: native_module_(native_module) {

View File

@ -356,10 +356,6 @@ class V8_EXPORT_PRIVATE WasmCodeManager final {
WasmCode* GetCodeFromStartAddress(Address pc) const;
intptr_t remaining_uncommitted() const;
// TODO(mtrofin): replace this API with an alternative that is Isolate-
// independent.
void FlushICache(Address start, size_t size);
private:
friend class NativeModule;

View File

@ -1546,7 +1546,7 @@ void WasmCompiledModule::Reset(Isolate* isolate,
// TODO(wasm): Check if this is faster than passing FLUSH_ICACHE_IF_NEEDED
// above.
if (changed) {
Assembler::FlushICache(isolate, code->instructions().start(),
Assembler::FlushICache(code->instructions().start(),
code->instructions().size());
}
}

View File

@ -275,7 +275,7 @@ void Assembler::set_target_address_at(Isolate* isolate, Address pc,
DCHECK_IMPLIES(isolate == nullptr, icache_flush_mode == SKIP_ICACHE_FLUSH);
Memory::int32_at(pc) = static_cast<int32_t>(target - pc - 4);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate, pc, sizeof(int32_t));
Assembler::FlushICache(pc, sizeof(int32_t));
}
}
@ -380,7 +380,7 @@ void RelocInfo::set_target_object(HeapObject* target,
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
Memory::Object_at(pc_) = target;
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(target->GetIsolate(), pc_, sizeof(Address));
Assembler::FlushICache(pc_, sizeof(Address));
}
if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != nullptr) {
host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this,
@ -422,7 +422,7 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitEmbeddedPointer(host(), this);
Assembler::FlushICache(isolate, pc_, sizeof(Address));
Assembler::FlushICache(pc_, sizeof(Address));
} else if (RelocInfo::IsCodeTarget(mode)) {
visitor->VisitCodeTarget(host(), this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {

View File

@ -131,7 +131,7 @@ void RelocInfo::set_embedded_address(Isolate* isolate, Address address,
ICacheFlushMode icache_flush_mode) {
Memory::Address_at(pc_) = address;
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate, pc_, sizeof(Address));
Assembler::FlushICache(pc_, sizeof(Address));
}
}
@ -139,7 +139,7 @@ void RelocInfo::set_embedded_size(Isolate* isolate, uint32_t size,
ICacheFlushMode icache_flush_mode) {
Memory::uint32_at(pc_) = size;
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(isolate, pc_, sizeof(uint32_t));
Assembler::FlushICache(pc_, sizeof(uint32_t));
}
}

View File

@ -30,7 +30,7 @@ UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
masm.GetCode(isolate, &desc);
DCHECK(!RelocInfo::RequiresRelocation(isolate, desc));
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
CHECK(SetPermissions(buffer, allocated, PageAllocator::kReadExecute));
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
}

View File

@ -38,8 +38,7 @@ static void UpdateFunctionTableSizeReferences(Handle<Code> code,
}
}
if (modified) {
Assembler::FlushICache(isolate, code->instruction_start(),
code->instruction_size());
Assembler::FlushICache(code->instruction_start(), code->instruction_size());
}
}

View File

@ -196,13 +196,13 @@ static void InitializeVM() {
RESET(); \
START_AFTER_RESET();
#define RUN() \
MakeAssemblerBufferExecutable(buf, allocated); \
Assembler::FlushICache(isolate, buf, masm.SizeOfGeneratedCode()); \
{ \
void (*test_function)(void); \
memcpy(&test_function, &buf, sizeof(buf)); \
test_function(); \
#define RUN() \
MakeAssemblerBufferExecutable(buf, allocated); \
Assembler::FlushICache(buf, masm.SizeOfGeneratedCode()); \
{ \
void (*test_function)(void); \
memcpy(&test_function, &buf, sizeof(buf)); \
test_function(); \
}
#define END() \

View File

@ -116,7 +116,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
CodeDesc desc;
masm.GetCode(isolate, &desc);
MakeAssemblerBufferExecutable(buffer, allocated);
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
return (reinterpret_cast<ConvertDToIFunc>(
reinterpret_cast<intptr_t>(buffer)));
}

View File

@ -129,7 +129,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
CodeDesc desc;
masm.GetCode(isolate, &desc);
MakeAssemblerBufferExecutable(buffer, allocated);
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
return (reinterpret_cast<ConvertDToIFunc>(
reinterpret_cast<intptr_t>(buffer)));
}

View File

@ -129,7 +129,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
CodeDesc desc;
masm.GetCode(isolate, &desc);
MakeAssemblerBufferExecutable(buffer, allocated);
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
return (reinterpret_cast<ConvertDToIFunc>(
reinterpret_cast<intptr_t>(buffer)));
}

View File

@ -126,7 +126,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate,
CodeDesc desc;
masm.GetCode(isolate, &desc);
MakeAssemblerBufferExecutable(buffer, allocated);
Assembler::FlushICache(isolate, buffer, allocated);
Assembler::FlushICache(buffer, allocated);
return (reinterpret_cast<ConvertDToIFunc>(
reinterpret_cast<intptr_t>(buffer)));
}

View File

@ -54,8 +54,7 @@ WASM_COMPILED_EXEC_TEST(RunPatchWasmContext) {
patched = true;
}
CHECK(patched);
Assembler::FlushICache(isolate, code->instruction_start(),
code->instruction_size());
Assembler::FlushICache(code->instruction_start(), code->instruction_size());
}
// Run with the new global data.