forked from OSchip/llvm-project
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
This commit is contained in:
parent
00de22f963
commit
ce19fe3f38
|
@ -958,6 +958,16 @@ RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (lldb_private::Unwind
|
||||||
|
|
||||||
switch (regloc.type)
|
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:
|
case UnwindLLDB::RegisterLocation::eRegisterInRegister:
|
||||||
{
|
{
|
||||||
const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
|
const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
|
||||||
|
@ -1012,6 +1022,12 @@ RegisterContextLLDB::WriteRegisterValueToRegisterLocation (lldb_private::UnwindL
|
||||||
|
|
||||||
switch (regloc.type)
|
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:
|
case UnwindLLDB::RegisterLocation::eRegisterInRegister:
|
||||||
{
|
{
|
||||||
const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
|
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)
|
if (return_address_reg.GetAsKind (eRegisterKindLLDB) != LLDB_INVALID_REGNUM)
|
||||||
{
|
{
|
||||||
lldb_private::UnwindLLDB::RegisterLocation new_regloc;
|
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);
|
new_regloc.location.register_number = return_address_reg.GetAsKind (eRegisterKindLLDB);
|
||||||
m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
|
m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
|
||||||
regloc = 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
|
// This is frame 0 - we should return the actual live register context value
|
||||||
lldb_private::UnwindLLDB::RegisterLocation new_regloc;
|
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);
|
new_regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB);
|
||||||
m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
|
m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
|
||||||
regloc = new_regloc;
|
regloc = new_regloc;
|
||||||
|
@ -1343,8 +1359,18 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
|
||||||
return UnwindLLDB::RegisterSearchResult::eRegisterFound;
|
return UnwindLLDB::RegisterSearchResult::eRegisterFound;
|
||||||
}
|
}
|
||||||
else
|
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;
|
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1354,7 +1380,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
|
||||||
lldb_private::UnwindLLDB::RegisterLocation new_regloc;
|
lldb_private::UnwindLLDB::RegisterLocation new_regloc;
|
||||||
new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
|
new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
|
||||||
m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
|
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));
|
regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
|
||||||
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
|
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
|
||||||
}
|
}
|
||||||
|
@ -1363,7 +1389,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
|
||||||
{
|
{
|
||||||
if (IsFrameZero ())
|
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));
|
regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
|
||||||
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
|
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);
|
RegisterNumber row_regnum (m_thread, unwindplan_registerkind, unwindplan_regnum);
|
||||||
if (row_regnum.GetAsKind (eRegisterKindLLDB) == LLDB_INVALID_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));
|
regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
|
||||||
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
|
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
|
||||||
}
|
}
|
||||||
|
@ -1454,7 +1480,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
|
||||||
return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
|
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));
|
regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
|
||||||
|
|
||||||
// FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are unsupported.
|
// FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are unsupported.
|
||||||
|
|
|
@ -384,6 +384,14 @@ UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
|
||||||
UnwindLLDB::RegisterSearchResult result;
|
UnwindLLDB::RegisterSearchResult result;
|
||||||
result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
|
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
|
// 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
|
// 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
|
// change the register number we're looking for to M and keep looking for a concrete location
|
||||||
|
|
|
@ -48,7 +48,8 @@ protected:
|
||||||
eRegisterSavedAtMemoryLocation, // register is saved at a specific word of target mem (target_memory_location)
|
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)
|
eRegisterInRegister, // register is available in a (possible other) register (register_number)
|
||||||
eRegisterSavedAtHostMemoryLocation, // register is saved at a word in lldb's address space
|
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;
|
int type;
|
||||||
union
|
union
|
||||||
|
|
Loading…
Reference in New Issue