From: plind44@gmail.com Date: Tue, 20 May 2014 14:49:05 +0000 (+0000) Subject: MIPS: Avoid flushing the icache unnecessarily when updating target addresses in code. X-Git-Tag: upstream/4.7.83~9062 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=eabf06021c3b6a17bc15d441ac78472e08973b2a;p=platform%2Fupstream%2Fv8.git 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= R=plind44@gmail.com Review URL: https://codereview.chromium.org/296723003 Patch from Balazs Kilvady . git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21390 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/mips/assembler-mips-inl.h b/src/mips/assembler-mips-inl.h index 6a4d059..b7afb84 100644 --- a/src/mips/assembler-mips-inl.h +++ b/src/mips/assembler-mips-inl.h @@ -112,7 +112,7 @@ int FPURegister::ToAllocationIndex(FPURegister reg) { // ----------------------------------------------------------------------------- // 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(pc_) & ~kImm28Mask; @@ -171,10 +171,13 @@ int RelocInfo::target_address_size() { } -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 @@ Handle RelocInfo::target_object_handle(Assembler* origin) { } -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
(target)); - if (mode == UPDATE_WRITE_BARRIER && + reinterpret_cast
(target), + icache_flush_mode); + if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL && target->IsHeapObject()) { host()->GetHeap()->incremental_marking()->RecordWrite( @@ -227,9 +233,11 @@ Address RelocInfo::target_runtime_entry(Assembler* origin) { 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 @@ Cell* RelocInfo::target_cell() { } -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 @@ Code* RelocInfo::code_age_stub() { } -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_, diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc index 7e0be71..621a20a 100644 --- a/src/mips/assembler-mips.cc +++ b/src/mips/assembler-mips.cc @@ -2166,7 +2166,9 @@ void Assembler::QuietNaN(HeapObject* object) { // 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(pc); @@ -2260,7 +2262,9 @@ void Assembler::set_target_address_at(Address pc, Address target) { 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)); + } } diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h index cae8a10..8f1b5b7 100644 --- a/src/mips/assembler-mips.h +++ b/src/mips/assembler-mips.h @@ -478,7 +478,10 @@ class Assembler : public AssemblerBase { // 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 @@ class Assembler : public AssemblerBase { } 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 @@ class Assembler : public AssemblerBase { } 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