[Lldb-commits] [lldb] r223843 - Add a new 'eRegisterInLiveRegisterContext' RegisterLocation to track

Jason Molenda jmolenda at apple.com
Tue Dec 9 14:28:10 PST 2014


Author: jmolenda
Date: Tue Dec  9 16:28:10 2014
New Revision: 223843

URL: http://llvm.org/viewvc/llvm-project?rev=223843&view=rev
Log:
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> 

Modified:
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
    lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=223843&r1=223842&r2=223843&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Tue Dec  9 16:28:10 2014
@@ -958,6 +958,16 @@ RegisterContextLLDB::ReadRegisterValueFr
 
     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::WriteRegisterValueT
 
     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::SavedLocationForReg
                 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::SavedLocationForReg
         {
             // 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::SavedLocationForReg
             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::SavedLocationForReg
         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::SavedLocationForReg
     {
         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::SavedLocationForReg
         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::SavedLocationForReg
         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.

Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp?rev=223843&r1=223842&r2=223843&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp Tue Dec  9 16:28:10 2014
@@ -384,6 +384,14 @@ UnwindLLDB::SearchForSavedLocationForReg
         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 

Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h?rev=223843&r1=223842&r2=223843&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h Tue Dec  9 16:28:10 2014
@@ -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





More information about the lldb-commits mailing list