Revision: 20715
Author:   [email protected]
Date:     Mon Apr 14 11:08:14 2014 UTC
Log: ARM64: Avoid iterating through all unresolved branch infos when many are pending.

Instead, inspect the label chain and delete pending information for every branch
in the chain.

[email protected]

Review URL: https://codereview.chromium.org/227043010
http://code.google.com/p/v8/source/detail?r=20715

Modified:
 /branches/bleeding_edge/src/arm64/assembler-arm64.cc
 /branches/bleeding_edge/src/arm64/assembler-arm64.h
 /branches/bleeding_edge/src/arm64/instructions-arm64.h

=======================================
--- /branches/bleeding_edge/src/arm64/assembler-arm64.cc Mon Apr 7 12:33:03 2014 UTC +++ /branches/bleeding_edge/src/arm64/assembler-arm64.cc Mon Apr 14 11:08:14 2014 UTC
@@ -543,6 +543,40 @@

   return offset;
 }
+
+
+void Assembler::DeleteUnresolvedBranchInfoForLabelTraverse(Label* label) {
+  ASSERT(label->is_linked());
+  CheckLabelLinkChain(label);
+
+  int link_offset = label->pos();
+  int link_pcoffset;
+  bool end_of_chain = false;
+
+  while (!end_of_chain) {
+    Instruction * link = InstructionAt(link_offset);
+    link_pcoffset = link->ImmPCOffset();
+
+    // ADR instructions are not handled by veneers.
+    if (link->IsImmBranch()) {
+      int max_reachable_pc = InstructionOffset(link) +
+          Instruction::ImmBranchRange(link->BranchType());
+ typedef std::multimap<int, FarBranchInfo>::iterator unresolved_info_it;
+      std::pair<unresolved_info_it, unresolved_info_it> range;
+      range = unresolved_branches_.equal_range(max_reachable_pc);
+      unresolved_info_it it;
+      for (it = range.first; it != range.second; ++it) {
+        if (it->second.pc_offset_ == link_offset) {
+          unresolved_branches_.erase(it);
+          break;
+        }
+      }
+    }
+
+    end_of_chain = (link_pcoffset == 0);
+    link_offset = link_offset + link_pcoffset;
+  }
+}


 void Assembler::DeleteUnresolvedBranchInfoForLabel(Label* label) {
@@ -552,16 +586,9 @@
   }

   if (label->is_linked()) {
- // Branches to this label will be resolved when the label is bound below.
-    std::multimap<int, FarBranchInfo>::iterator it_tmp, it;
-    it = unresolved_branches_.begin();
-    while (it != unresolved_branches_.end()) {
-      it_tmp = it++;
-      if (it_tmp->second.label_ == label) {
-        CHECK(it_tmp->first >= pc_offset());
-        unresolved_branches_.erase(it_tmp);
-      }
-    }
+ // Branches to this label will be resolved when the label is bound, normally
+    // just after all the associated info has been deleted.
+    DeleteUnresolvedBranchInfoForLabelTraverse(label);
   }
   if (unresolved_branches_.empty()) {
     next_veneer_pool_check_ = kMaxInt;
=======================================
--- /branches/bleeding_edge/src/arm64/assembler-arm64.h Mon Apr 14 11:04:46 2014 UTC +++ /branches/bleeding_edge/src/arm64/assembler-arm64.h Mon Apr 14 11:08:14 2014 UTC
@@ -1693,6 +1693,10 @@
   Instruction* InstructionAt(int offset) const {
     return reinterpret_cast<Instruction*>(buffer_ + offset);
   }
+
+  ptrdiff_t InstructionOffset(Instruction* instr) const {
+    return reinterpret_cast<byte*>(instr) - buffer_;
+  }

   // Register encoding.
   static Instr Rd(CPURegister rd) {
@@ -2183,6 +2187,11 @@
// not later attempt (likely unsuccessfully) to patch it to branch directly to
   // the label.
   void DeleteUnresolvedBranchInfoForLabel(Label* label);
+ // This function deletes the information related to the label by traversing + // the label chain, and for each PC-relative instruction in the chain checking + // if pending unresolved information exists. Its complexity is proportional to
+  // the length of the label chain.
+  void DeleteUnresolvedBranchInfoForLabelTraverse(Label* label);

  private:
   PositionsRecorder positions_recorder_;
=======================================
--- /branches/bleeding_edge/src/arm64/instructions-arm64.h Mon Apr 7 12:33:03 2014 UTC +++ /branches/bleeding_edge/src/arm64/instructions-arm64.h Mon Apr 14 11:08:14 2014 UTC
@@ -191,6 +191,10 @@
   bool IsTestBranch() const {
     return Mask(TestBranchFMask) == TestBranchFixed;
   }
+
+  bool IsImmBranch() const {
+    return BranchType() != UnknownBranchType;
+  }

   bool IsLdrLiteral() const {
     return Mask(LoadLiteralFMask) == LoadLiteralFixed;

--
--
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