summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2014-12-09 22:28:10 +0000
committerJason Molenda <jmolenda@apple.com>2014-12-09 22:28:10 +0000
commitce19fe3f38c60424a5b1fba67a0b04e6ff1b1037 (patch)
treee37c4dde58396735846bc51cde49a9cba6d1992c
parent00de22f9630e301ec8891e522a12ae36a46c4beb (diff)
downloadbcm5719-llvm-ce19fe3f38c60424a5b1fba67a0b04e6ff1b1037.tar.gz
bcm5719-llvm-ce19fe3f38c60424a5b1fba67a0b04e6ff1b1037.zip
Add a new 'eRegisterInLiveRegisterContext' RegisterLocation to track
a register value that is live in the stack frame 0 register context. Fixes a problem where retrieving a register value on stack frame #n would involved O(n!) stack frame checks. This could be very slow on a deep stack when retrieving register values that had not been modified/saved by any of the stack frames. Not common, but annoying when it was hit. <rdar://problem/19010211> llvm-svn: 223843
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp42
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp8
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.h3
3 files changed, 44 insertions, 9 deletions
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 955567e8ff3..4535df44518 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -958,6 +958,16 @@ RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (lldb_private::Unwind
switch (regloc.type)
{
+ case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext:
+ {
+ const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
+
+ if (!other_reg_info)
+ return false;
+
+ success = m_thread.GetRegisterContext()->ReadRegister (other_reg_info, value);
+ }
+ break;
case UnwindLLDB::RegisterLocation::eRegisterInRegister:
{
const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
@@ -1012,6 +1022,12 @@ RegisterContextLLDB::WriteRegisterValueToRegisterLocation (lldb_private::UnwindL
switch (regloc.type)
{
+ case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext:
+ {
+ const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
+ success = m_thread.GetRegisterContext()->WriteRegister (other_reg_info, value);
+ }
+ break;
case UnwindLLDB::RegisterLocation::eRegisterInRegister:
{
const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
@@ -1232,7 +1248,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
if (return_address_reg.GetAsKind (eRegisterKindLLDB) != LLDB_INVALID_REGNUM)
{
lldb_private::UnwindLLDB::RegisterLocation new_regloc;
- new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
+ new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
new_regloc.location.register_number = return_address_reg.GetAsKind (eRegisterKindLLDB);
m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
regloc = new_regloc;
@@ -1334,7 +1350,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
{
// This is frame 0 - we should return the actual live register context value
lldb_private::UnwindLLDB::RegisterLocation new_regloc;
- new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
+ new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
new_regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB);
m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
regloc = new_regloc;
@@ -1343,8 +1359,18 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
else
- UnwindLogMsg ("could not supply caller's %s (%d) location",
- regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
+ {
+ std::string unwindplan_name ("");
+ if (m_full_unwind_plan_sp)
+ {
+ unwindplan_name += "via '";
+ unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString();
+ unwindplan_name += "'";
+ }
+ UnwindLogMsg ("no save location for %s (%d) %s",
+ regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
+ unwindplan_name.c_str());
+ }
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
@@ -1354,7 +1380,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
lldb_private::UnwindLLDB::RegisterLocation new_regloc;
new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
- UnwindLogMsg ("could not supply caller's %s (%d) location",
+ UnwindLogMsg ("save location for %s (%d) is unspecified, continue searching",
regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
@@ -1363,7 +1389,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
{
if (IsFrameZero ())
{
- UnwindLogMsg ("could not supply caller's %s (%d) location",
+ UnwindLogMsg ("could not supply caller's %s (%d) location, IsSame",
regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
@@ -1403,7 +1429,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
RegisterNumber row_regnum (m_thread, unwindplan_registerkind, unwindplan_regnum);
if (row_regnum.GetAsKind (eRegisterKindLLDB) == LLDB_INVALID_REGNUM)
{
- UnwindLogMsg ("could not supply caller's %s (%d) location",
+ UnwindLogMsg ("could not supply caller's %s (%d) location - was saved in another reg but couldn't convert that regnum",
regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
@@ -1454,7 +1480,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
- UnwindLogMsg ("could not supply caller's %s (%d) location",
+ UnwindLogMsg ("no save location for %s (%d) in this stack frame",
regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
// FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are unsupported.
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 92c2f9304c7..fc592e60d86 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -384,6 +384,14 @@ UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
UnwindLLDB::RegisterSearchResult result;
result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
+ // We descended down to the live register context aka stack frame 0 and are reading the value
+ // out of a live register.
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound
+ && regloc.type == UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext)
+ {
+ return true;
+ }
+
// If we have unwind instructions saying that register N is saved in register M in the middle of
// the stack (and N can equal M here, meaning the register was not used in this function), then
// change the register number we're looking for to M and keep looking for a concrete location
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
index eb5400389df..35d85e2e3d2 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -48,7 +48,8 @@ protected:
eRegisterSavedAtMemoryLocation, // register is saved at a specific word of target mem (target_memory_location)
eRegisterInRegister, // register is available in a (possible other) register (register_number)
eRegisterSavedAtHostMemoryLocation, // register is saved at a word in lldb's address space
- eRegisterValueInferred // register val was computed (and is in inferred_value)
+ eRegisterValueInferred, // register val was computed (and is in inferred_value)
+ eRegisterInLiveRegisterContext // register value is in a live (stack frame #0) register
};
int type;
union
OpenPOWER on IntegriCloud