Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Unified Diff: src/arm64/assembler-arm64.cc

Issue 227043010: ARM64: Avoid iterating through all unresolved branch infos when many are pending. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm64/assembler-arm64.h ('k') | src/arm64/instructions-arm64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm64/assembler-arm64.cc
diff --git a/src/arm64/assembler-arm64.cc b/src/arm64/assembler-arm64.cc
index 5695623afd54e033ca6ec9ebfb349cef159b14c4..43bea9f160f8e0e32ed151fda5517e42be164dd5 100644
--- a/src/arm64/assembler-arm64.cc
+++ b/src/arm64/assembler-arm64.cc
@@ -545,6 +545,53 @@ int Assembler::LinkAndGetByteOffsetTo(Label* label) {
}
+void Assembler::DeleteUnresolvedBranchInfoForLabelIterate(Label* label) {
+ 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);
+ }
+ }
+}
+
+
+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) {
if (unresolved_branches_.empty()) {
ASSERT(next_veneer_pool_check_ == kMaxInt);
@@ -552,15 +599,17 @@ void Assembler::DeleteUnresolvedBranchInfoForLabel(Label* label) {
}
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.
+
+ // If there are too many unresolved branches pending, avoid iterating
+ // through all of them to find the information to delete.
+ static const int kMaxNInfoIterate = 128;
+
+ if (unresolved_branches_.size() < kMaxNInfoIterate) {
+ DeleteUnresolvedBranchInfoForLabelIterate(label);
+ } else {
+ DeleteUnresolvedBranchInfoForLabelTraverse(label);
ulan 2014/04/07 13:24:41 Ignoring ADR instructions, chain length <= unresol
Alexandre Rames 2014/04/09 13:22:06 Yes.
}
}
if (unresolved_branches_.empty()) {
« no previous file with comments | « src/arm64/assembler-arm64.h ('k') | src/arm64/instructions-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698