Commit 0c20a4c6 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[cleanup] Move Code class out of objects.cc

Drive-by: Refactor FlushInstructionCache to its own header. This removes
dependencies of objects.cc and code.cc

Bug: v8:8562
Change-Id: If23f3b9d4f2068e08c61c0f4b070ecfe1b9a6cc0
Reviewed-on: https://chromium-review.googlesource.com/c/1456081Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59435}
parent eb69c7da
......@@ -1973,6 +1973,8 @@ v8_source_set("v8_base") {
"src/flag-definitions.h",
"src/flags.cc",
"src/flags.h",
"src/flush-instruction-cache.cc",
"src/flush-instruction-cache.h",
"src/frame-constants.h",
"src/frames-inl.h",
"src/frames.cc",
......@@ -2189,6 +2191,7 @@ v8_source_set("v8_base") {
"src/objects/cell-inl.h",
"src/objects/cell.h",
"src/objects/code-inl.h",
"src/objects/code.cc",
"src/objects/code.h",
"src/objects/compilation-cache-inl.h",
"src/objects/compilation-cache.h",
......
......@@ -348,7 +348,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
Memory<Address>(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(pc, sizeof(target));
// FlushInstructionCache(pc, sizeof(target));
// However, on ARM, no instruction is actually patched in the case
// of embedded constants of the form:
// ldr ip, [pp, #...]
......@@ -366,7 +366,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
DCHECK(IsMovW(Memory<int32_t>(pc)));
DCHECK(IsMovT(Memory<int32_t>(pc + kInstrSize)));
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, 2 * kInstrSize);
FlushInstructionCache(pc, 2 * kInstrSize);
}
} else if (IsMovImmed(Memory<int32_t>(pc))) {
// This is an mov / orr immediate load. Patch the immediate embedded in
......@@ -386,14 +386,14 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
IsOrrImmed(Memory<int32_t>(pc + 2 * kInstrSize)) &&
IsOrrImmed(Memory<int32_t>(pc + 3 * kInstrSize)));
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, 4 * kInstrSize);
FlushInstructionCache(pc, 4 * kInstrSize);
}
} else {
intptr_t branch_offset = target - pc - Instruction::kPcLoadDelta;
Instruction* branch = Instruction::At(pc);
branch->SetBranchOffset(branch_offset);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, kInstrSize);
FlushInstructionCache(pc, kInstrSize);
}
}
}
......
......@@ -598,7 +598,7 @@ void Assembler::deserialization_set_special_target_at(Address location,
target = location;
}
instr->SetBranchImmTarget(reinterpret_cast<Instruction*>(target));
Assembler::FlushICache(location, kInstrSize);
FlushInstructionCache(location, kInstrSize);
} else {
DCHECK_EQ(instr->InstructionBits(), 0);
Memory<Address>(location) = target;
......@@ -635,7 +635,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
}
instr->SetBranchImmTarget(reinterpret_cast<Instruction*>(target));
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, kInstrSize);
FlushInstructionCache(pc, kInstrSize);
}
}
}
......
......@@ -39,7 +39,6 @@
#include "src/disassembler.h"
#include "src/isolate.h"
#include "src/ostreams.h"
#include "src/simulator.h" // For flushing instruction cache.
#include "src/snapshot/embedded-data.h"
#include "src/snapshot/serializer-common.h"
#include "src/snapshot/snapshot.h"
......@@ -161,17 +160,6 @@ AssemblerBase::AssemblerBase(const AssemblerOptions& options,
AssemblerBase::~AssemblerBase() = default;
void AssemblerBase::FlushICache(void* start, size_t size) {
if (size == 0) return;
#if defined(USE_SIMULATOR)
base::MutexGuard lock_guard(Simulator::i_cache_mutex());
Simulator::FlushICache(Simulator::i_cache(), start, size);
#else
CpuFeatures::FlushICache(start, size);
#endif // USE_SIMULATOR
}
void AssemblerBase::Print(Isolate* isolate) {
StdoutStream os;
v8::internal::Disassembler::Decode(isolate, &os, buffer_start_, pc_);
......
......@@ -268,11 +268,6 @@ class V8_EXPORT_PRIVATE AssemblerBase : public Malloced {
static const int kMinimalBufferSize = 4*KB;
static void FlushICache(void* start, size_t size);
static void FlushICache(Address start, size_t size) {
return FlushICache(reinterpret_cast<void*>(start), size);
}
protected:
// Add 'target' to the {code_targets_} vector, if necessary, and return the
// offset at which it is stored.
......
......@@ -268,8 +268,8 @@ void SetupIsolateDelegate::ReplacePlaceholders(Isolate* isolate) {
flush_icache = true;
}
if (flush_icache) {
Assembler::FlushICache(code->raw_instruction_start(),
code->raw_instruction_size());
FlushInstructionCache(code->raw_instruction_start(),
code->raw_instruction_size());
}
}
}
......
......@@ -104,8 +104,8 @@ class CpuFeatures : public AllStatic {
static void PrintFeatures();
private:
friend void V8_EXPORT_PRIVATE FlushInstructionCache(void*, size_t);
friend class ExternalReference;
friend class AssemblerBase;
// Flush instruction cache.
static void FlushICache(void* start, size_t size);
......
// Copyright 2019 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/flush-instruction-cache.h"
#include "src/base/platform/mutex.h"
#include "src/cpu-features.h"
#include "src/simulator.h"
namespace v8 {
namespace internal {
void FlushInstructionCache(void* start, size_t size) {
if (size == 0) return;
#if defined(USE_SIMULATOR)
base::MutexGuard lock_guard(Simulator::i_cache_mutex());
Simulator::FlushICache(Simulator::i_cache(), start, size);
#else
CpuFeatures::FlushICache(start, size);
#endif // USE_SIMULATOR
}
} // namespace internal
} // namespace v8
// Copyright 2019 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_FLUSH_INSTRUCTION_CACHE_H_
#define V8_FLUSH_INSTRUCTION_CACHE_H_
#include "include/v8-internal.h"
#include "src/base/macros.h"
namespace v8 {
namespace internal {
V8_EXPORT_PRIVATE void FlushInstructionCache(void* start, size_t size);
V8_EXPORT_PRIVATE V8_INLINE void FlushInstructionCache(Address start,
size_t size) {
return FlushInstructionCache(reinterpret_cast<void*>(start), size);
}
} // namespace internal
} // namespace v8
#endif // V8_FLUSH_INSTRUCTION_CACHE_H_
......@@ -105,7 +105,7 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target,
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
WriteUnalignedValue(pc_, target->ptr());
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc_, sizeof(Address));
FlushInstructionCache(pc_, sizeof(Address));
}
if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null()) {
WriteBarrierForCode(host(), this, target);
......@@ -122,7 +122,7 @@ void RelocInfo::set_target_external_reference(
DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
WriteUnalignedValue(pc_, target);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc_, sizeof(Address));
FlushInstructionCache(pc_, sizeof(Address));
}
}
......@@ -246,7 +246,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
ICacheFlushMode icache_flush_mode) {
WriteUnalignedValue(pc, target - (pc + sizeof(int32_t)));
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, sizeof(int32_t));
FlushInstructionCache(pc, sizeof(int32_t));
}
}
......
......@@ -4114,7 +4114,7 @@ void Assembler::set_target_value_at(Address pc, uint32_t target,
}
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, 2 * sizeof(int32_t));
FlushInstructionCache(pc, 2 * sizeof(int32_t));
}
}
......
......@@ -4352,7 +4352,7 @@ void Assembler::set_target_value_at(Address pc, uint64_t target,
(target & kImm16Mask);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, 4 * kInstrSize);
FlushInstructionCache(pc, 4 * kInstrSize);
}
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -469,7 +469,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
*(p + 3) = instr4;
*(p + 4) = instr5;
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(p, 5 * kInstrSize);
FlushInstructionCache(p, 5 * kInstrSize);
}
#else
uint32_t* p = reinterpret_cast<uint32_t*>(pc);
......@@ -484,7 +484,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
*p = instr1;
*(p + 1) = instr2;
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(p, 2 * kInstrSize);
FlushInstructionCache(p, 2 * kInstrSize);
}
#endif
return;
......
......@@ -5,8 +5,8 @@
#ifndef V8_RELOC_INFO_H_
#define V8_RELOC_INFO_H_
#include "src/flush-instruction-cache.h"
#include "src/globals.h"
#include "src/objects.h"
#include "src/objects/code.h"
namespace v8 {
......
......@@ -297,7 +297,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
Instruction::SetInstructionBits<SixByteInstr>(reinterpret_cast<byte*>(pc),
instr_1);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, 6);
FlushInstructionCache(pc, 6);
}
patched = true;
} else {
......@@ -326,7 +326,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
Instruction::SetInstructionBits<SixByteInstr>(
reinterpret_cast<byte*>(pc + instr1_length), instr_2);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, 12);
FlushInstructionCache(pc, 12);
}
patched = true;
}
......@@ -340,7 +340,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
Instruction::SetInstructionBits<SixByteInstr>(reinterpret_cast<byte*>(pc),
instr_1);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, 6);
FlushInstructionCache(pc, 6);
}
patched = true;
}
......
......@@ -59,8 +59,8 @@ void ObjectDeserializer::FlushICache() {
for (Code code : new_code_objects()) {
// Record all references to embedded objects in the new code object.
WriteBarrierForCode(code);
Assembler::FlushICache(code->raw_instruction_start(),
code->raw_instruction_size());
FlushInstructionCache(code->raw_instruction_start(),
code->raw_instruction_size());
}
}
......
......@@ -78,7 +78,7 @@ void StartupDeserializer::FlushICache() {
DCHECK(!deserializing_user_code());
// The entire isolate is newly deserialized. Simply flush all code pages.
for (Page* p : *isolate()->heap()->code_space()) {
Assembler::FlushICache(p->area_start(), p->area_end() - p->area_start());
FlushInstructionCache(p->area_start(), p->area_end() - p->area_start());
}
}
......
......@@ -21,7 +21,6 @@
#include "src/libsampler/sampler.h"
#include "src/objects-inl.h"
#include "src/profiler/heap-profiler.h"
#include "src/reloc-info.h"
#include "src/runtime-profiler.h"
#include "src/simulator.h"
#include "src/snapshot/natives.h"
......
......@@ -4,7 +4,7 @@
#include "src/visitors.h"
#include "src/objects/code.h"
#include "src/reloc-info.h"
namespace v8 {
namespace internal {
......@@ -23,5 +23,11 @@ const char* RootVisitor::RootName(Root root) {
return nullptr;
}
void ObjectVisitor::VisitRelocInfo(RelocIterator* it) {
for (; !it->done(); it->next()) {
it->rinfo()->Visit(this);
}
}
} // namespace internal
} // namespace v8
......@@ -64,7 +64,7 @@ class JumpTableAssembler : public TurboAssembler {
jtasm.EmitLazyCompileJumpSlot(func_index, lazy_compile_target);
jtasm.NopBytes(kJumpTableSlotSize - jtasm.pc_offset());
if (flush_i_cache) {
Assembler::FlushICache(slot, kJumpTableSlotSize);
FlushInstructionCache(slot, kJumpTableSlotSize);
}
}
......@@ -76,7 +76,7 @@ class JumpTableAssembler : public TurboAssembler {
jtasm.EmitJumpSlot(new_target);
jtasm.NopBytes(kJumpTableSlotSize - jtasm.pc_offset());
if (flush_i_cache) {
Assembler::FlushICache(slot, kJumpTableSlotSize);
FlushInstructionCache(slot, kJumpTableSlotSize);
}
}
......
......@@ -503,8 +503,8 @@ void NativeModule::SetLazyBuiltin(Handle<Code> code) {
i + module_->num_imported_functions, lazy_compile_target,
WasmCode::kNoFlushICache);
}
Assembler::FlushICache(jump_table_->instructions().start(),
jump_table_->instructions().size());
FlushInstructionCache(jump_table_->instructions().start(),
jump_table_->instructions().size());
}
void NativeModule::SetRuntimeStubs(Isolate* isolate) {
......@@ -591,8 +591,8 @@ WasmCode* NativeModule::AddAnonymousCode(Handle<Code> code, WasmCode::Kind kind,
// Flush the i-cache here instead of in AddOwnedCode, to include the changes
// made while iterating over the RelocInfo above.
Assembler::FlushICache(ret->instructions().start(),
ret->instructions().size());
FlushInstructionCache(ret->instructions().start(),
ret->instructions().size());
ret->MaybePrint(name);
ret->Validate();
return ret;
......@@ -652,8 +652,8 @@ WasmCode* NativeModule::AddCode(
// Flush the i-cache here instead of in AddOwnedCode, to include the changes
// made while iterating over the RelocInfo above.
Assembler::FlushICache(ret->instructions().start(),
ret->instructions().size());
FlushInstructionCache(ret->instructions().start(),
ret->instructions().size());
ret->MaybePrint();
ret->Validate();
return ret;
......
......@@ -573,8 +573,8 @@ bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) {
code->Validate();
// Finally, flush the icache for that code.
Assembler::FlushICache(code->instructions().start(),
code->instructions().size());
FlushInstructionCache(code->instructions().start(),
code->instructions().size());
return true;
}
......
......@@ -236,7 +236,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
ICacheFlushMode icache_flush_mode) {
WriteUnalignedValue(pc, static_cast<int32_t>(target - pc - 4));
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, sizeof(int32_t));
FlushInstructionCache(pc, sizeof(int32_t));
}
}
......@@ -335,7 +335,7 @@ void RelocInfo::set_target_external_reference(
DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
WriteUnalignedValue(pc_, target);
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc_, sizeof(Address));
FlushInstructionCache(pc_, sizeof(Address));
}
}
......@@ -356,7 +356,7 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target,
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
WriteUnalignedValue(pc_, target->ptr());
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc_, sizeof(Address));
FlushInstructionCache(pc_, sizeof(Address));
}
if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null()) {
WriteBarrierForCode(host(), this, target);
......
......@@ -104,14 +104,14 @@ TEST(TestFlushICacheOfWritable) {
CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
buffer->size(), v8::PageAllocator::kReadWrite));
FloodWithInc(isolate, buffer.get());
Assembler::FlushICache(buffer->start(), buffer->size());
FlushInstructionCache(buffer->start(), buffer->size());
CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
buffer->size(), v8::PageAllocator::kReadExecute));
CHECK_EQ(23 + kNumInstr, f.Call(23)); // Call into generated code.
CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
buffer->size(), v8::PageAllocator::kReadWrite));
FloodWithNop(isolate, buffer.get());
Assembler::FlushICache(buffer->start(), buffer->size());
FlushInstructionCache(buffer->start(), buffer->size());
CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
buffer->size(), v8::PageAllocator::kReadExecute));
CHECK_EQ(23, f.Call(23)); // Call into generated code.
......@@ -151,14 +151,14 @@ CONDITIONAL_TEST(TestFlushICacheOfExecutable) {
FloodWithInc(isolate, buffer.get());
CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
buffer->size(), v8::PageAllocator::kReadExecute));
Assembler::FlushICache(buffer->start(), buffer->size());
FlushInstructionCache(buffer->start(), buffer->size());
CHECK_EQ(23 + kNumInstr, f.Call(23)); // Call into generated code.
CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
buffer->size(), v8::PageAllocator::kReadWrite));
FloodWithNop(isolate, buffer.get());
CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
buffer->size(), v8::PageAllocator::kReadExecute));
Assembler::FlushICache(buffer->start(), buffer->size());
FlushInstructionCache(buffer->start(), buffer->size());
CHECK_EQ(23, f.Call(23)); // Call into generated code.
}
}
......@@ -180,10 +180,10 @@ TEST(TestFlushICacheOfWritableAndExecutable) {
CHECK(SetPermissions(GetPlatformPageAllocator(), buffer->start(),
buffer->size(), v8::PageAllocator::kReadWriteExecute));
FloodWithInc(isolate, buffer.get());
Assembler::FlushICache(buffer->start(), buffer->size());
FlushInstructionCache(buffer->start(), buffer->size());
CHECK_EQ(23 + kNumInstr, f.Call(23)); // Call into generated code.
FloodWithNop(isolate, buffer.get());
Assembler::FlushICache(buffer->start(), buffer->size());
FlushInstructionCache(buffer->start(), buffer->size());
CHECK_EQ(23, f.Call(23)); // Call into generated code.
}
}
......
......@@ -46,7 +46,7 @@ class TestingAssemblerBuffer : public AssemblerBuffer {
// some older ARM kernels there is a bug which causes an access error on
// cache flush instructions to trigger access error on non-writable memory.
// See https://bugs.chromium.org/p/v8/issues/detail?id=8157
Assembler::FlushICache(buffer_, size_);
FlushInstructionCache(buffer_, size_);
bool result = SetPermissions(GetPlatformPageAllocator(), buffer_, size_,
v8::PageAllocator::kReadExecute);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment