Revision: 21390
Author: [email protected]
Date: Tue May 20 14:49:05 2014 UTC
Log: MIPS: Avoid flushing the icache unnecessarily when updating
target addresses in code.
Port r21380 (ef20a0a)
Original commit message:
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
BUG=
[email protected]
Review URL: https://codereview.chromium.org/296723003
Patch from Balazs Kilvady <[email protected]>.
http://code.google.com/p/v8/source/detail?r=21390
Modified:
/branches/bleeding_edge/src/mips/assembler-mips-inl.h
/branches/bleeding_edge/src/mips/assembler-mips.cc
/branches/bleeding_edge/src/mips/assembler-mips.h
=======================================
--- /branches/bleeding_edge/src/mips/assembler-mips-inl.h Fri May 16
15:18:24 2014 UTC
+++ /branches/bleeding_edge/src/mips/assembler-mips-inl.h Tue May 20
14:49:05 2014 UTC
@@ -112,7 +112,7 @@
//
-----------------------------------------------------------------------------
// RelocInfo.
-void RelocInfo::apply(intptr_t delta) {
+void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) {
if (IsCodeTarget(rmode_)) {
uint32_t scope1 = (uint32_t) target_address() & ~kImm28Mask;
uint32_t scope2 = reinterpret_cast<uint32_t>(pc_) & ~kImm28Mask;
@@ -171,10 +171,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));
@@ -200,12 +203,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(
@@ -227,9 +233,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);
}
@@ -246,11 +254,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(
@@ -275,7 +285,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);
Assembler::set_target_address_at(pc_ + Assembler::kInstrSize,
host_,
=======================================
--- /branches/bleeding_edge/src/mips/assembler-mips.cc Fri May 16 15:18:24
2014 UTC
+++ /branches/bleeding_edge/src/mips/assembler-mips.cc Tue May 20 14:49:05
2014 UTC
@@ -2166,7 +2166,9 @@
// There is an optimization below, which emits a nop when the address
// fits in just 16 bits. This is unlikely to help, and should be
benchmarked,
// and possibly removed.
-void Assembler::set_target_address_at(Address pc, Address target) {
+void Assembler::set_target_address_at(Address pc,
+ Address target,
+ ICacheFlushMode icache_flush_mode) {
Instr instr2 = instr_at(pc + kInstrSize);
uint32_t rt_code = GetRtField(instr2);
uint32_t* p = reinterpret_cast<uint32_t*>(pc);
@@ -2260,7 +2262,9 @@
patched_jump = true;
}
- CPU::FlushICache(pc, (patched_jump ? 3 : 2) * sizeof(int32_t));
+ if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
+ CPU::FlushICache(pc, (patched_jump ? 3 : 2) * sizeof(int32_t));
+ }
}
=======================================
--- /branches/bleeding_edge/src/mips/assembler-mips.h Fri May 16 15:18:24
2014 UTC
+++ /branches/bleeding_edge/src/mips/assembler-mips.h Tue May 20 14:49:05
2014 UTC
@@ -478,7 +478,10 @@
// Read/Modify the code target address in the branch/call instruction at
pc.
static Address target_address_at(Address pc);
- static void set_target_address_at(Address pc, Address target);
+ static void set_target_address_at(Address pc,
+ Address target,
+ ICacheFlushMode icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED);
// On MIPS there is no Constant Pool so we skip that parameter.
INLINE(static Address target_address_at(Address pc,
ConstantPoolArray*
constant_pool)) {
@@ -486,8 +489,10 @@
}
INLINE(static void set_target_address_at(Address pc,
ConstantPoolArray*
constant_pool,
- Address target)) {
- set_target_address_at(pc, target);
+ Address target,
+ ICacheFlushMode
icache_flush_mode =
+ FLUSH_ICACHE_IF_NEEDED)) {
+ set_target_address_at(pc, target, icache_flush_mode);
}
INLINE(static Address target_address_at(Address pc, Code* code)) {
ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
@@ -495,9 +500,11 @@
}
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
--
--
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.