From a83b4e65c7ea43af3cd29a41295f573443070339 Mon Sep 17 00:00:00 2001 From: whh8b <whh8b@git.zephyr-software.com> Date: Mon, 14 Dec 2015 05:19:43 +0000 Subject: [PATCH] Add UpdateAllTargets() and fix bugs in UpdateTargets --- include/zipr_dollop_man.h | 3 ++- src/zipr_dollop_man.cpp | 54 +++++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/include/zipr_dollop_man.h b/include/zipr_dollop_man.h index 7e2fe5f..e93b24e 100644 --- a/include/zipr_dollop_man.h +++ b/include/zipr_dollop_man.h @@ -54,7 +54,8 @@ class ZiprDollopManager_t { return m_patches_to_dollops.at(target); } void PrintDollopPatches(const std::ostream &); - void UpdateTargets(Dollop_t *); + bool UpdateTargets(Dollop_t *); + void UpdateAllTargets(); friend std::ostream &operator<<(std::ostream &out, const ZiprDollopManager_t &dollop_man); private: std::list<Dollop_t*> m_dollops; diff --git a/src/zipr_dollop_man.cpp b/src/zipr_dollop_man.cpp index 78cb5b2..51abb32 100644 --- a/src/zipr_dollop_man.cpp +++ b/src/zipr_dollop_man.cpp @@ -11,6 +11,7 @@ namespace zipr { Dollop_t *ZiprDollopManager_t::AddNewDollop(Instruction_t *start) { Dollop_t *new_dollop = NULL; Dollop_t *existing_dollop = GetContainingDollop(start); + /* * This is the target dollop *only* * if the target instruction is the first instruction. @@ -80,19 +81,52 @@ namespace zipr { m_dollops.push_back(dollop); } - void ZiprDollopManager_t::UpdateTargets(Dollop_t *dollop) { + bool ZiprDollopManager_t::UpdateTargets(Dollop_t *dollop) { list<DollopEntry_t*>::iterator it, it_end; - for (it = dollop->begin(), it_end = dollop->end(); - it != it_end; - it++) { - DollopEntry_t *entry = *it; - if (entry->Instruction() && - entry->Instruction()->GetTarget()) { + bool changed = false; + bool local_changed = false; + do { + local_changed = false; + for (it = dollop->begin(), it_end = dollop->end(); + it != it_end; + /* nop */) { + DollopEntry_t *entry = *it; + it++; + if (entry->Instruction() && + entry->Instruction()->GetTarget()) { + Dollop_t *new_target=AddNewDollop(entry->Instruction()->GetTarget()); - entry->TargetDollop(AddNewDollop(entry->Instruction()->GetTarget())); + /* + * In the case there is a change, we have to restart. + * The dollop that we are updating could itself have + * contained the target and the call would have + * split this dollop. That makes the iterator go + * haywire. + */ + if (new_target != entry->TargetDollop()) { + entry->TargetDollop(new_target); + changed = local_changed = true; + break; + } + } } - } - return; + } while (local_changed); + return changed; + } + + void ZiprDollopManager_t::UpdateAllTargets(void) { + std::list<Dollop_t *>::const_iterator it, it_end; + bool changed = false; + do { + changed = false; + for (it = m_dollops.begin(), it_end = m_dollops.end(); + it != m_dollops.end(); + /* nop */) { + Dollop_t *entry = *it; + it++; + changed |= UpdateTargets(entry); + } + } while (changed); } std::ostream &operator<<(std::ostream &out, const ZiprDollopManager_t &dollop_man) { -- GitLab