Revision: 21380
Author: [email protected]
Date: Tue May 20 09:21:45 2014 UTC
Log: Avoid flushing the icache unnecessarily when updating target
addresses in code.
This CL updates RelocInfo update operations and set_target_address_at to
enable
skipping of the icache flush if it going to be batched up later.
Code::CopyFrom and Code::Relocate are modified to avoid individual icache
flushes since the whole code area will be flushed after the reloc info is
updated.
These changes reduce a regression when enabling the OOL constant pool on
Arm,
since this change can cause MovT/MovW instructions for relocatable targets
if the constant pool is full.
Scores for Mandreel latency on a Nexus 5:
- OOL CP disabled: 3533
- OOL CP enabled, without this CL: 1825
- OOL CP enabled, with change: 3015
[email protected], [email protected]
Review URL: https://codereview.chromium.org/284153004
http://code.google.com/p/v8/source/detail?r=21380
Modified:
/branches/bleeding_edge/src/arm/assembler-arm-inl.h
/branches/bleeding_edge/src/arm/assembler-arm.h
/branches/bleeding_edge/src/arm64/assembler-arm64-inl.h
/branches/bleeding_edge/src/arm64/assembler-arm64.h
/branches/bleeding_edge/src/assembler.h
/branches/bleeding_edge/src/ia32/assembler-ia32-inl.h
/branches/bleeding_edge/src/ia32/assembler-ia32.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/x64/assembler-x64-inl.h
/branches/bleeding_edge/src/x64/assembler-x64.h
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm-inl.h Fri May 16 15:18:24
2014 UTC
+++ /branches/bleeding_edge/src/arm/assembler-arm-inl.h Tue May 20 09:21:45
2014 UTC
@@ -91,7 +91,7 @@
}
-void RelocInfo::apply(intptr_t delta) {
+void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) {
if (RelocInfo::IsInternalReference(rmode_)) {
// absolute code pointer inside code object moves with the code object.
int32_t* p = reinterpret_cast<int32_t*>(pc_);
@@ -142,10 +142,13 @@
}
-void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
+void RelocInfo::set_target_address(Address target,
+ WriteBarrierMode write_barrier_mode,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
- Assembler::set_target_address_at(pc_, host_, target);
- if (mode == UPDATE_WRITE_BARRIER && host() != NULL &&
IsCodeTarget(rmode_)) {
+ Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode);
+ if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
+ host() != NULL && IsCodeTarget(rmode_)) {
Object* target_code = Code::GetCodeFromTargetAddress(target);
host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
host(), this, HeapObject::cast(target_code));
@@ -166,12 +169,15 @@
}
-void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) {
+void RelocInfo::set_target_object(Object* target,
+ WriteBarrierMode write_barrier_mode,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
ASSERT(!target->IsConsString());
Assembler::set_target_address_at(pc_, host_,
- reinterpret_cast<Address>(target));
- if (mode == UPDATE_WRITE_BARRIER &&
+ reinterpret_cast<Address>(target),
+ icache_flush_mode);
+ if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
host() != NULL &&
target->IsHeapObject()) {
host()->GetHeap()->incremental_marking()->RecordWrite(
@@ -193,9 +199,11 @@
void RelocInfo::set_target_runtime_entry(Address target,
- WriteBarrierMode mode) {
+ WriteBarrierMode
write_barrier_mode,
+ ICacheFlushMode
icache_flush_mode) {
ASSERT(IsRuntimeEntry(rmode_));
- if (target_address() != target) set_target_address(target, mode);
+ if (target_address() != target)
+ set_target_address(target, write_barrier_mode, icache_flush_mode);
}
@@ -212,11 +220,13 @@
}
-void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode mode) {
+void RelocInfo::set_target_cell(Cell* cell,
+ WriteBarrierMode write_barrier_mode,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(rmode_ == RelocInfo::CELL);
Address address = cell->address() + Cell::kValueOffset;
Memory::Address_at(pc_) = address;
- if (mode == UPDATE_WRITE_BARRIER && host() != NULL) {
+ if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) {
// TODO(1550) We are passing NULL as a slot because cell can never be
on
// evacuation candidate.
host()->GetHeap()->incremental_marking()->RecordWrite(
@@ -242,7 +252,8 @@
}
-void RelocInfo::set_code_age_stub(Code* stub) {
+void RelocInfo::set_code_age_stub(Code* stub,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
Memory::Address_at(pc_ +
(kNoCodeAgeSequenceLength - Assembler::kInstrSize)) =
@@ -504,26 +515,29 @@
ASSERT(immediate < 0x10000);
return ((immediate & 0xf000) << 4) | (immediate & 0xfff);
}
+
+
+static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate) {
+ instruction &= ~EncodeMovwImmediate(0xffff);
+ return instruction | EncodeMovwImmediate(immediate);
+}
void Assembler::set_target_address_at(Address pc,
ConstantPoolArray* constant_pool,
- Address target) {
+ Address target,
+ ICacheFlushMode icache_flush_mode) {
if (IsMovW(Memory::int32_at(pc))) {
ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize)));
uint32_t* instr_ptr = reinterpret_cast<uint32_t*>(pc);
uint32_t immediate = reinterpret_cast<uint32_t>(target);
- uint32_t intermediate = instr_ptr[0];
- intermediate &= ~EncodeMovwImmediate(0xFFFF);
- intermediate |= EncodeMovwImmediate(immediate & 0xFFFF);
- instr_ptr[0] = intermediate;
- intermediate = instr_ptr[1];
- intermediate &= ~EncodeMovwImmediate(0xFFFF);
- intermediate |= EncodeMovwImmediate(immediate >> 16);
- instr_ptr[1] = intermediate;
+ instr_ptr[0] = PatchMovwImmediate(instr_ptr[0], immediate & 0xFFFF);
+ instr_ptr[1] = PatchMovwImmediate(instr_ptr[1], immediate >> 16);
ASSERT(IsMovW(Memory::int32_at(pc)));
ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize)));
- CPU::FlushICache(pc, 2 * kInstrSize);
+ if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
+ CPU::FlushICache(pc, 2 * kInstrSize);
+ }
} else if (FLAG_enable_ool_constant_pool) {
ASSERT(IsLdrPpImmediateOffset(Memory::int32_at(pc)));
Memory::Address_at(
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.h Fri May 16 15:18:24
2014 UTC
+++ /branches/bleeding_edge/src/arm/assembler-arm.h Tue May 20 09:21:45
2014 UTC
@@ -763,16 +763,20 @@
ConstantPoolArray*
constant_pool));
INLINE(static void set_target_address_at(Address pc,
ConstantPoolArray*
constant_pool,
- Address target));
+ Address target,
+ ICacheFlushMode
icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED));
INLINE(static Address target_address_at(Address pc, Code* code)) {
ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
return target_address_at(pc, constant_pool);
}
INLINE(static void set_target_address_at(Address pc,
Code* code,
- Address target)) {
+ Address target,
+ ICacheFlushMode
icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED)) {
ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
- set_target_address_at(pc, constant_pool, target);
+ set_target_address_at(pc, constant_pool, target, icache_flush_mode);
}
// Return the code target address at a call site from the return address
=======================================
--- /branches/bleeding_edge/src/arm64/assembler-arm64-inl.h Fri May 16
15:18:24 2014 UTC
+++ /branches/bleeding_edge/src/arm64/assembler-arm64-inl.h Tue May 20
09:21:45 2014 UTC
@@ -17,15 +17,18 @@
bool CpuFeatures::SupportsCrankshaft() { return true; }
-void RelocInfo::apply(intptr_t delta) {
+void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) {
UNIMPLEMENTED();
}
-void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
+void RelocInfo::set_target_address(Address target,
+ WriteBarrierMode write_barrier_mode,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
- Assembler::set_target_address_at(pc_, host_, target);
- if (mode == UPDATE_WRITE_BARRIER && host() != NULL &&
IsCodeTarget(rmode_)) {
+ Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode);
+ if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL &&
+ IsCodeTarget(rmode_)) {
Object* target_code = Code::GetCodeFromTargetAddress(target);
host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
host(), this, HeapObject::cast(target_code));
@@ -625,7 +628,8 @@
void Assembler::set_target_address_at(Address pc,
ConstantPoolArray* constant_pool,
- Address target) {
+ Address target,
+ ICacheFlushMode icache_flush_mode) {
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:
@@ -640,9 +644,10 @@
void Assembler::set_target_address_at(Address pc,
Code* code,
- Address target) {
+ Address target,
+ ICacheFlushMode icache_flush_mode) {
ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
- set_target_address_at(pc, constant_pool, target);
+ set_target_address_at(pc, constant_pool, target, icache_flush_mode);
}
@@ -684,12 +689,15 @@
}
-void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) {
+void RelocInfo::set_target_object(Object* target,
+ WriteBarrierMode write_barrier_mode,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
ASSERT(!target->IsConsString());
Assembler::set_target_address_at(pc_, host_,
- reinterpret_cast<Address>(target));
- if (mode == UPDATE_WRITE_BARRIER &&
+ reinterpret_cast<Address>(target),
+ icache_flush_mode);
+ if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
host() != NULL &&
target->IsHeapObject()) {
host()->GetHeap()->incremental_marking()->RecordWrite(
@@ -711,9 +719,12 @@
void RelocInfo::set_target_runtime_entry(Address target,
- WriteBarrierMode mode) {
+ WriteBarrierMode
write_barrier_mode,
+ ICacheFlushMode
icache_flush_mode) {
ASSERT(IsRuntimeEntry(rmode_));
- if (target_address() != target) set_target_address(target, mode);
+ if (target_address() != target) {
+ set_target_address(target, write_barrier_mode, icache_flush_mode);
+ }
}
@@ -730,7 +741,9 @@
}
-void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode mode) {
+void RelocInfo::set_target_cell(Cell* cell,
+ WriteBarrierMode write_barrier_mode,
+ ICacheFlushMode icache_flush_mode) {
UNIMPLEMENTED();
}
@@ -753,7 +766,8 @@
}
-void RelocInfo::set_code_age_stub(Code* stub) {
+void RelocInfo::set_code_age_stub(Code* stub,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
ASSERT(!Code::IsYoungSequence(stub->GetIsolate(), pc_));
// Overwrite the stub entry point in the code age sequence. This is
loaded as
=======================================
--- /branches/bleeding_edge/src/arm64/assembler-arm64.h Fri May 16 15:18:24
2014 UTC
+++ /branches/bleeding_edge/src/arm64/assembler-arm64.h Tue May 20 09:21:45
2014 UTC
@@ -788,11 +788,15 @@
ConstantPoolArray*
constant_pool);
inline static void set_target_address_at(Address pc,
ConstantPoolArray*
constant_pool,
- Address target);
+ Address target,
+ ICacheFlushMode
icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED);
static inline Address target_address_at(Address pc, Code* code);
static inline void set_target_address_at(Address pc,
Code* code,
- Address target);
+ Address target,
+ ICacheFlushMode
icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED);
// Return the code target address at a call site from the return address
of
// that call in the instruction stream.
=======================================
--- /branches/bleeding_edge/src/assembler.h Fri May 16 15:18:24 2014 UTC
+++ /branches/bleeding_edge/src/assembler.h Tue May 20 09:21:45 2014 UTC
@@ -276,6 +276,12 @@
enum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs };
+// Specifies whether to perform icache flush operations on RelocInfo
updates.
+// If FLUSH_ICACHE_IF_NEEDED, the icache will always be flushed if an
+// instruction was modified. If SKIP_ICACHE_FLUSH the flush will always be
+// skipped (only use this if you will flush the icache manually before it
is
+// executed).
+enum ICacheFlushMode { FLUSH_ICACHE_IF_NEEDED, SKIP_ICACHE_FLUSH };
//
-----------------------------------------------------------------------------
// Relocation information
@@ -360,7 +366,6 @@
LAST_STANDARD_NONCOMPACT_ENUM = INTERNAL_REFERENCE
};
-
RelocInfo() {}
RelocInfo(byte* pc, Mode rmode, intptr_t data, Code* host)
@@ -452,7 +457,9 @@
void set_host(Code* host) { host_ = host; }
// Apply a relocation by delta bytes
- INLINE(void apply(intptr_t delta));
+ INLINE(void apply(intptr_t delta,
+ ICacheFlushMode icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED));
// Is the pointer this relocation info refers to coded like a plain
pointer
// or is it strange in some way (e.g. relative or patched into a series
of
@@ -468,22 +475,35 @@
// can only be called if IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
INLINE(Address target_address());
INLINE(void set_target_address(Address target,
- WriteBarrierMode mode =
UPDATE_WRITE_BARRIER));
+ WriteBarrierMode write_barrier_mode =
+ UPDATE_WRITE_BARRIER,
+ ICacheFlushMode icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED));
INLINE(Object* target_object());
INLINE(Handle<Object> target_object_handle(Assembler* origin));
INLINE(void set_target_object(Object* target,
- WriteBarrierMode mode =
UPDATE_WRITE_BARRIER));
+ WriteBarrierMode write_barrier_mode =
+ UPDATE_WRITE_BARRIER,
+ ICacheFlushMode icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED));
INLINE(Address target_runtime_entry(Assembler* origin));
INLINE(void set_target_runtime_entry(Address target,
- WriteBarrierMode mode =
- UPDATE_WRITE_BARRIER));
+ WriteBarrierMode write_barrier_mode
=
+ UPDATE_WRITE_BARRIER,
+ ICacheFlushMode icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED));
INLINE(Cell* target_cell());
INLINE(Handle<Cell> target_cell_handle());
INLINE(void set_target_cell(Cell* cell,
- WriteBarrierMode mode =
UPDATE_WRITE_BARRIER));
+ WriteBarrierMode write_barrier_mode =
+ UPDATE_WRITE_BARRIER,
+ ICacheFlushMode icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED));
INLINE(Handle<Object> code_age_stub_handle(Assembler* origin));
INLINE(Code* code_age_stub());
- INLINE(void set_code_age_stub(Code* stub));
+ INLINE(void set_code_age_stub(Code* stub,
+ ICacheFlushMode icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED));
// Returns the address of the constant pool entry where the target
address
// is held. This should only be called if IsInConstantPool returns true.
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32-inl.h Fri May 16
15:18:24 2014 UTC
+++ /branches/bleeding_edge/src/ia32/assembler-ia32-inl.h Tue May 20
09:21:45 2014 UTC
@@ -53,34 +53,35 @@
// The modes possibly affected by apply must be in kApplyMask.
-void RelocInfo::apply(intptr_t delta) {
+void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) {
+ bool flush_icache = icache_flush_mode != SKIP_ICACHE_FLUSH;
if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) {
int32_t* p = reinterpret_cast<int32_t*>(pc_);
*p -= delta; // Relocate entry.
- CPU::FlushICache(p, sizeof(uint32_t));
+ if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t));
} else if (rmode_ == CODE_AGE_SEQUENCE) {
if (*pc_ == kCallOpcode) {
int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
*p -= delta; // Relocate entry.
- CPU::FlushICache(p, sizeof(uint32_t));
+ if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t));
}
} else if (rmode_ == JS_RETURN && IsPatchedReturnSequence()) {
// Special handling of js_return when a break point is set (call
// instruction has been inserted).
int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
*p -= delta; // Relocate entry.
- CPU::FlushICache(p, sizeof(uint32_t));
+ if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t));
} else if (rmode_ == DEBUG_BREAK_SLOT &&
IsPatchedDebugBreakSlotSequence()) {
// Special handling of a debug break slot when a break point is set
(call
// instruction has been inserted).
int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
*p -= delta; // Relocate entry.
- CPU::FlushICache(p, sizeof(uint32_t));
+ if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t));
} else if (IsInternalReference(rmode_)) {
// absolute code pointer inside code object moves with the code object.
int32_t* p = reinterpret_cast<int32_t*>(pc_);
*p += delta; // Relocate entry.
- CPU::FlushICache(p, sizeof(uint32_t));
+ if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t));
}
}
@@ -110,10 +111,13 @@
}
-void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
- Assembler::set_target_address_at(pc_, host_, target);
+void RelocInfo::set_target_address(Address target,
+ WriteBarrierMode write_barrier_mode,
+ ICacheFlushMode icache_flush_mode) {
+ Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode);
ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
- if (mode == UPDATE_WRITE_BARRIER && host() != NULL &&
IsCodeTarget(rmode_)) {
+ if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL &&
+ IsCodeTarget(rmode_)) {
Object* target_code = Code::GetCodeFromTargetAddress(target);
host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
host(), this, HeapObject::cast(target_code));
@@ -133,12 +137,16 @@
}
-void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) {
+void RelocInfo::set_target_object(Object* target,
+ WriteBarrierMode write_barrier_mode,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
ASSERT(!target->IsConsString());
Memory::Object_at(pc_) = target;
- CPU::FlushICache(pc_, sizeof(Address));
- if (mode == UPDATE_WRITE_BARRIER &&
+ if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
+ CPU::FlushICache(pc_, sizeof(Address));
+ }
+ if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
host() != NULL &&
target->IsHeapObject()) {
host()->GetHeap()->incremental_marking()->RecordWrite(
@@ -160,9 +168,12 @@
void RelocInfo::set_target_runtime_entry(Address target,
- WriteBarrierMode mode) {
+ WriteBarrierMode
write_barrier_mode,
+ ICacheFlushMode
icache_flush_mode) {
ASSERT(IsRuntimeEntry(rmode_));
- if (target_address() != target) set_target_address(target, mode);
+ if (target_address() != target) {
+ set_target_address(target, write_barrier_mode, icache_flush_mode);
+ }
}
@@ -179,12 +190,16 @@
}
-void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode mode) {
+void RelocInfo::set_target_cell(Cell* cell,
+ WriteBarrierMode write_barrier_mode,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(rmode_ == RelocInfo::CELL);
Address address = cell->address() + Cell::kValueOffset;
Memory::Address_at(pc_) = address;
- CPU::FlushICache(pc_, sizeof(Address));
- if (mode == UPDATE_WRITE_BARRIER && host() != NULL) {
+ if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
+ CPU::FlushICache(pc_, sizeof(Address));
+ }
+ if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) {
// TODO(1550) We are passing NULL as a slot because cell can never be
on
// evacuation candidate.
host()->GetHeap()->incremental_marking()->RecordWrite(
@@ -208,10 +223,12 @@
}
-void RelocInfo::set_code_age_stub(Code* stub) {
+void RelocInfo::set_code_age_stub(Code* stub,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(*pc_ == kCallOpcode);
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
- Assembler::set_target_address_at(pc_ + 1, host_,
stub->instruction_start());
+ Assembler::set_target_address_at(pc_ + 1, host_,
stub->instruction_start(),
+ icache_flush_mode);
}
@@ -451,10 +468,13 @@
void Assembler::set_target_address_at(Address pc,
ConstantPoolArray* constant_pool,
- Address target) {
+ Address target,
+ ICacheFlushMode icache_flush_mode) {
int32_t* p = reinterpret_cast<int32_t*>(pc);
*p = target - (pc + sizeof(int32_t));
- CPU::FlushICache(p, sizeof(int32_t));
+ if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
+ CPU::FlushICache(p, sizeof(int32_t));
+ }
}
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.h Fri May 16 15:18:24
2014 UTC
+++ /branches/bleeding_edge/src/ia32/assembler-ia32.h Tue May 20 09:21:45
2014 UTC
@@ -493,14 +493,18 @@
ConstantPoolArray*
constant_pool);
inline static void set_target_address_at(Address pc,
ConstantPoolArray*
constant_pool,
- Address target);
+ Address target,
+ ICacheFlushMode
icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED);
static inline Address target_address_at(Address pc, Code* code) {
ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
return target_address_at(pc, constant_pool);
}
static inline void set_target_address_at(Address pc,
Code* code,
- Address target) {
+ Address target,
+ ICacheFlushMode
icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED) {
ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
set_target_address_at(pc, constant_pool, target);
}
=======================================
--- /branches/bleeding_edge/src/objects.cc Wed May 14 09:12:21 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc Tue May 20 09:21:45 2014 UTC
@@ -10969,7 +10969,7 @@
void Code::Relocate(intptr_t delta) {
for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done();
it.next()) {
- it.rinfo()->apply(delta);
+ it.rinfo()->apply(delta, SKIP_ICACHE_FLUSH);
}
CPU::FlushICache(instruction_start(), instruction_size());
}
@@ -11001,26 +11001,28 @@
RelocInfo::Mode mode = it.rinfo()->rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
Handle<Object> p = it.rinfo()->target_object_handle(origin);
- it.rinfo()->set_target_object(*p, SKIP_WRITE_BARRIER);
+ it.rinfo()->set_target_object(*p, SKIP_WRITE_BARRIER,
SKIP_ICACHE_FLUSH);
} else if (mode == RelocInfo::CELL) {
Handle<Cell> cell = it.rinfo()->target_cell_handle();
- it.rinfo()->set_target_cell(*cell, SKIP_WRITE_BARRIER);
+ it.rinfo()->set_target_cell(*cell, SKIP_WRITE_BARRIER,
SKIP_ICACHE_FLUSH);
} else if (RelocInfo::IsCodeTarget(mode)) {
// rewrite code handles in inline cache targets to direct
// pointers to the first instruction in the code object
Handle<Object> p = it.rinfo()->target_object_handle(origin);
Code* code = Code::cast(*p);
it.rinfo()->set_target_address(code->instruction_start(),
- SKIP_WRITE_BARRIER);
+ SKIP_WRITE_BARRIER,
+ SKIP_ICACHE_FLUSH);
} else if (RelocInfo::IsRuntimeEntry(mode)) {
Address p = it.rinfo()->target_runtime_entry(origin);
- it.rinfo()->set_target_runtime_entry(p, SKIP_WRITE_BARRIER);
+ it.rinfo()->set_target_runtime_entry(p, SKIP_WRITE_BARRIER,
+ SKIP_ICACHE_FLUSH);
} else if (mode == RelocInfo::CODE_AGE_SEQUENCE) {
Handle<Object> p = it.rinfo()->code_age_stub_handle(origin);
Code* code = Code::cast(*p);
- it.rinfo()->set_code_age_stub(code);
+ it.rinfo()->set_code_age_stub(code, SKIP_ICACHE_FLUSH);
} else {
- it.rinfo()->apply(delta);
+ it.rinfo()->apply(delta, SKIP_ICACHE_FLUSH);
}
}
CPU::FlushICache(instruction_start(), instruction_size());
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64-inl.h Fri May 16 15:18:24
2014 UTC
+++ /branches/bleeding_edge/src/x64/assembler-x64-inl.h Tue May 20 09:21:45
2014 UTC
@@ -193,9 +193,12 @@
void Assembler::set_target_address_at(Address pc,
ConstantPoolArray* constant_pool,
- Address target) {
+ Address target,
+ ICacheFlushMode icache_flush_mode) {
Memory::int32_at(pc) = static_cast<int32_t>(target - pc - 4);
- CPU::FlushICache(pc, sizeof(int32_t));
+ if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
+ CPU::FlushICache(pc, sizeof(int32_t));
+ }
}
@@ -218,19 +221,20 @@
// Implementation of RelocInfo
// The modes possibly affected by apply must be in kApplyMask.
-void RelocInfo::apply(intptr_t delta) {
+void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) {
+ bool flush_icache = icache_flush_mode != SKIP_ICACHE_FLUSH;
if (IsInternalReference(rmode_)) {
// absolute code pointer inside code object moves with the code object.
Memory::Address_at(pc_) += static_cast<int32_t>(delta);
- CPU::FlushICache(pc_, sizeof(Address));
+ if (flush_icache) CPU::FlushICache(pc_, sizeof(Address));
} else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) {
Memory::int32_at(pc_) -= static_cast<int32_t>(delta);
- CPU::FlushICache(pc_, sizeof(int32_t));
+ if (flush_icache) CPU::FlushICache(pc_, sizeof(int32_t));
} else if (rmode_ == CODE_AGE_SEQUENCE) {
if (*pc_ == kCallOpcode) {
int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
*p -= static_cast<int32_t>(delta); // Relocate entry.
- CPU::FlushICache(p, sizeof(uint32_t));
+ if (flush_icache) CPU::FlushICache(p, sizeof(uint32_t));
}
}
}
@@ -265,10 +269,13 @@
}
-void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
+void RelocInfo::set_target_address(Address target,
+ WriteBarrierMode write_barrier_mode,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
- Assembler::set_target_address_at(pc_, host_, target);
- if (mode == UPDATE_WRITE_BARRIER && host() != NULL &&
IsCodeTarget(rmode_)) {
+ Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode);
+ if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL &&
+ IsCodeTarget(rmode_)) {
Object* target_code = Code::GetCodeFromTargetAddress(target);
host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
host(), this, HeapObject::cast(target_code));
@@ -298,12 +305,16 @@
}
-void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) {
+void RelocInfo::set_target_object(Object* target,
+ WriteBarrierMode write_barrier_mode,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
ASSERT(!target->IsConsString());
Memory::Object_at(pc_) = target;
- CPU::FlushICache(pc_, sizeof(Address));
- if (mode == UPDATE_WRITE_BARRIER &&
+ if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
+ CPU::FlushICache(pc_, sizeof(Address));
+ }
+ if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
host() != NULL &&
target->IsHeapObject()) {
host()->GetHeap()->incremental_marking()->RecordWrite(
@@ -319,9 +330,12 @@
void RelocInfo::set_target_runtime_entry(Address target,
- WriteBarrierMode mode) {
+ WriteBarrierMode
write_barrier_mode,
+ ICacheFlushMode
icache_flush_mode) {
ASSERT(IsRuntimeEntry(rmode_));
- if (target_address() != target) set_target_address(target, mode);
+ if (target_address() != target) {
+ set_target_address(target, write_barrier_mode, icache_flush_mode);
+ }
}
@@ -338,12 +352,16 @@
}
-void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode mode) {
+void RelocInfo::set_target_cell(Cell* cell,
+ WriteBarrierMode write_barrier_mode,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(rmode_ == RelocInfo::CELL);
Address address = cell->address() + Cell::kValueOffset;
Memory::Address_at(pc_) = address;
- CPU::FlushICache(pc_, sizeof(Address));
- if (mode == UPDATE_WRITE_BARRIER &&
+ if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
+ CPU::FlushICache(pc_, sizeof(Address));
+ }
+ if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
host() != NULL) {
// TODO(1550) We are passing NULL as a slot because cell can never be
on
// evacuation candidate.
@@ -397,10 +415,12 @@
}
-void RelocInfo::set_code_age_stub(Code* stub) {
+void RelocInfo::set_code_age_stub(Code* stub,
+ ICacheFlushMode icache_flush_mode) {
ASSERT(*pc_ == kCallOpcode);
ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
- Assembler::set_target_address_at(pc_ + 1, host_,
stub->instruction_start());
+ Assembler::set_target_address_at(pc_ + 1, host_,
stub->instruction_start(),
+ icache_flush_mode);
}
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.h Fri May 16 15:18:24
2014 UTC
+++ /branches/bleeding_edge/src/x64/assembler-x64.h Tue May 20 09:21:45
2014 UTC
@@ -518,16 +518,20 @@
ConstantPoolArray*
constant_pool);
static inline void set_target_address_at(Address pc,
ConstantPoolArray*
constant_pool,
- Address target);
+ Address target,
+ ICacheFlushMode
icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED) ;
static inline Address target_address_at(Address pc, Code* code) {
ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
return target_address_at(pc, constant_pool);
}
static inline void set_target_address_at(Address pc,
Code* code,
- Address target) {
+ Address target,
+ ICacheFlushMode
icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED) {
ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
- set_target_address_at(pc, constant_pool, target);
+ set_target_address_at(pc, constant_pool, target, icache_flush_mode);
}
// Return the code target address at a call site from the return address
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.