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.

Reply via email to