labath created this revision.
labath added reviewers: jasonmolenda, clayborg.

A large chunk of this file was dealing with the caching of unwind plans.
In this patch I create a helper class to encapsulate this behavior and
leave the functions to deal with the actual work, which is to compute
the actual plan.

Since the caching now is handled by a separate class, it is also
possible to optimize it better without hampering readability. The way I
achieve that is by using a special shared_ptr value to mean "not
initialized" which means we can avoid having a special bool flag for
that purpose. This results in a net decrease of the size of the
FuncUnwinders object.


https://reviews.llvm.org/D61779

Files:
  include/lldb/Symbol/FuncUnwinders.h
  source/Symbol/FuncUnwinders.cpp

Index: source/Symbol/FuncUnwinders.cpp
===================================================================
--- source/Symbol/FuncUnwinders.cpp
+++ source/Symbol/FuncUnwinders.cpp
@@ -30,25 +30,25 @@
 using namespace lldb;
 using namespace lldb_private;
 
+/// Return a special value meaning the unwind plan hasn't been computed yet.
+static lldb::UnwindPlanSP GetUncomputedMarkerValue() {
+  static auto value_sp = std::make_shared<UnwindPlan>(eRegisterKindGeneric);
+  return value_sp;
+}
+
+FuncUnwinders::LazyPlan::LazyPlan() : m_plan_sp(GetUncomputedMarkerValue()) {}
+
+lldb::UnwindPlanSP
+FuncUnwinders::LazyPlan::Get(llvm::function_ref<lldb::UnwindPlanSP()> compute) {
+  if (m_plan_sp == GetUncomputedMarkerValue())
+    m_plan_sp = compute();
+  return m_plan_sp;
+}
+
 /// constructor
 
 FuncUnwinders::FuncUnwinders(UnwindTable &unwind_table, AddressRange range)
-    : m_unwind_table(unwind_table), m_range(range), m_mutex(),
-      m_unwind_plan_assembly_sp(), m_unwind_plan_eh_frame_sp(),
-      m_unwind_plan_eh_frame_augmented_sp(), m_unwind_plan_compact_unwind(),
-      m_unwind_plan_arm_unwind_sp(), m_unwind_plan_fast_sp(),
-      m_unwind_plan_arch_default_sp(),
-      m_unwind_plan_arch_default_at_func_entry_sp(),
-      m_tried_unwind_plan_assembly(false), m_tried_unwind_plan_eh_frame(false),
-      m_tried_unwind_plan_debug_frame(false),
-      m_tried_unwind_plan_eh_frame_augmented(false),
-      m_tried_unwind_plan_debug_frame_augmented(false),
-      m_tried_unwind_plan_compact_unwind(false),
-      m_tried_unwind_plan_arm_unwind(false),
-      m_tried_unwind_plan_symbol_file(false), m_tried_unwind_fast(false),
-      m_tried_unwind_arch_default(false),
-      m_tried_unwind_arch_default_at_func_entry(false),
-      m_first_non_prologue_insn() {}
+    : m_unwind_table(unwind_table), m_range(range) {}
 
 /// destructor
 
@@ -71,83 +71,66 @@
 
 UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  if (m_unwind_plan_compact_unwind.size() > 0)
-    return m_unwind_plan_compact_unwind[0]; // FIXME support multiple compact
-                                            // unwind plans for one func
-  if (m_tried_unwind_plan_compact_unwind)
-    return UnwindPlanSP();
 
-  m_tried_unwind_plan_compact_unwind = true;
-  if (m_range.GetBaseAddress().IsValid()) {
-    Address current_pc(m_range.GetBaseAddress());
-    CompactUnwindInfo *compact_unwind = m_unwind_table.GetCompactUnwindInfo();
-    if (compact_unwind) {
-      UnwindPlanSP unwind_plan_sp(new UnwindPlan(lldb::eRegisterKindGeneric));
-      if (compact_unwind->GetUnwindPlan(target, current_pc, *unwind_plan_sp)) {
-        m_unwind_plan_compact_unwind.push_back(unwind_plan_sp);
-        return m_unwind_plan_compact_unwind[0]; // FIXME support multiple
-                                                // compact unwind plans for one
-                                                // func
+  // FIXME support multiple compact unwind plans for one func
+  return m_unwind_plan_compact_unwind.Get([&] {
+    if (m_range.GetBaseAddress().IsValid()) {
+      Address current_pc(m_range.GetBaseAddress());
+      CompactUnwindInfo *compact_unwind = m_unwind_table.GetCompactUnwindInfo();
+      if (compact_unwind) {
+        UnwindPlanSP unwind_plan_sp(new UnwindPlan(lldb::eRegisterKindGeneric));
+        if (compact_unwind->GetUnwindPlan(target, current_pc,
+                                          *unwind_plan_sp)) {
+          return unwind_plan_sp;
+        }
       }
     }
-  }
-  return UnwindPlanSP();
+    return UnwindPlanSP();
+  });
 }
 
 UnwindPlanSP FuncUnwinders::GetEHFrameUnwindPlan(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  if (m_unwind_plan_eh_frame_sp.get() || m_tried_unwind_plan_eh_frame)
-    return m_unwind_plan_eh_frame_sp;
-
-  m_tried_unwind_plan_eh_frame = true;
-  if (m_range.GetBaseAddress().IsValid()) {
-    DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo();
-    if (eh_frame) {
-      m_unwind_plan_eh_frame_sp =
-          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-      if (!eh_frame->GetUnwindPlan(m_range, *m_unwind_plan_eh_frame_sp))
-        m_unwind_plan_eh_frame_sp.reset();
+  return m_unwind_plan_eh_frame.Get([&] {
+    if (m_range.GetBaseAddress().IsValid()) {
+      if (DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo()) {
+        auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+        if (eh_frame->GetUnwindPlan(m_range, *plan_sp))
+          return plan_sp;
+      }
     }
-  }
-  return m_unwind_plan_eh_frame_sp;
+    return UnwindPlanSP();
+  });
 }
 
 UnwindPlanSP FuncUnwinders::GetDebugFrameUnwindPlan(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  if (m_unwind_plan_debug_frame_sp || m_tried_unwind_plan_debug_frame)
-    return m_unwind_plan_debug_frame_sp;
-
-  m_tried_unwind_plan_debug_frame = true;
-  if (m_range.GetBaseAddress().IsValid()) {
-    DWARFCallFrameInfo *debug_frame = m_unwind_table.GetDebugFrameInfo();
-    if (debug_frame) {
-      m_unwind_plan_debug_frame_sp =
-          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-      if (!debug_frame->GetUnwindPlan(m_range, *m_unwind_plan_debug_frame_sp))
-        m_unwind_plan_debug_frame_sp.reset();
+  return m_unwind_plan_debug_frame.Get([&] {
+    if (m_range.GetBaseAddress().IsValid()) {
+      if (DWARFCallFrameInfo *debug_frame =
+              m_unwind_table.GetDebugFrameInfo()) {
+        auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+        if (debug_frame->GetUnwindPlan(m_range, *plan_sp))
+          return plan_sp;
+      }
     }
-  }
-  return m_unwind_plan_debug_frame_sp;
+    return UnwindPlanSP();
+  });
 }
 
 UnwindPlanSP FuncUnwinders::GetArmUnwindUnwindPlan(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  if (m_unwind_plan_arm_unwind_sp.get() || m_tried_unwind_plan_arm_unwind)
-    return m_unwind_plan_arm_unwind_sp;
-
-  m_tried_unwind_plan_arm_unwind = true;
-  if (m_range.GetBaseAddress().IsValid()) {
-    Address current_pc(m_range.GetBaseAddress());
-    ArmUnwindInfo *arm_unwind_info = m_unwind_table.GetArmUnwindInfo();
-    if (arm_unwind_info) {
-      m_unwind_plan_arm_unwind_sp =
-          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-      if (!arm_unwind_info->GetUnwindPlan(target, current_pc,
-                                          *m_unwind_plan_arm_unwind_sp))
-        m_unwind_plan_arm_unwind_sp.reset();
+  return m_unwind_plan_arm_unwind.Get([&] {
+    if (m_range.GetBaseAddress().IsValid()) {
+      Address current_pc(m_range.GetBaseAddress());
+      if (ArmUnwindInfo *arm_unwind_info = m_unwind_table.GetArmUnwindInfo()) {
+        auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+        if (arm_unwind_info->GetUnwindPlan(target, current_pc, *plan_sp))
+          return plan_sp;
+      }
     }
-  }
-  return m_unwind_plan_arm_unwind_sp;
+    return UnwindPlanSP();
+  });
 }
 
 namespace {
@@ -170,120 +153,98 @@
 
 UnwindPlanSP FuncUnwinders::GetSymbolFileUnwindPlan(Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  if (m_unwind_plan_symbol_file_sp.get() || m_tried_unwind_plan_symbol_file)
-    return m_unwind_plan_symbol_file_sp;
-
-  m_tried_unwind_plan_symbol_file = true;
-  if (SymbolFile *symfile = m_unwind_table.GetSymbolFile()) {
-    m_unwind_plan_symbol_file_sp = symfile->GetUnwindPlan(
-        m_range.GetBaseAddress(),
-        RegisterContextToInfo(*thread.GetRegisterContext()));
-  }
-  return m_unwind_plan_symbol_file_sp;
+  return m_unwind_plan_symbol_file.Get([&] {
+    if (SymbolFile *symfile = m_unwind_table.GetSymbolFile()) {
+      return symfile->GetUnwindPlan(
+          m_range.GetBaseAddress(),
+          RegisterContextToInfo(*thread.GetRegisterContext()));
+    }
+    return UnwindPlanSP();
+  });
 }
 
 UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target,
                                                           Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  if (m_unwind_plan_eh_frame_augmented_sp.get() ||
-      m_tried_unwind_plan_eh_frame_augmented)
-    return m_unwind_plan_eh_frame_augmented_sp;
-
-  // Only supported on x86 architectures where we get eh_frame from the
-  // compiler that describes the prologue instructions perfectly, and sometimes
-  // the epilogue instructions too.
-  if (target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_32_i386 &&
-      target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64 &&
-      target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64h) {
-    m_tried_unwind_plan_eh_frame_augmented = true;
-    return m_unwind_plan_eh_frame_augmented_sp;
-  }
-
-  m_tried_unwind_plan_eh_frame_augmented = true;
-
-  UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan(target);
-  if (!eh_frame_plan)
-    return m_unwind_plan_eh_frame_augmented_sp;
+  return m_unwind_plan_eh_frame_augmented.Get([&] {
+    // Only supported on x86 architectures where we get eh_frame from the
+    // compiler that describes the prologue instructions perfectly, and
+    // sometimes the epilogue instructions too.
+    if (target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_32_i386 &&
+        target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64 &&
+        target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64h) {
+      return UnwindPlanSP();
+    }
 
-  m_unwind_plan_eh_frame_augmented_sp =
-      std::make_shared<UnwindPlan>(*eh_frame_plan);
+    UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan(target);
+    if (!eh_frame_plan)
+      return UnwindPlanSP();
 
-  // Augment the eh_frame instructions with epilogue descriptions if necessary
-  // so the UnwindPlan can be used at any instruction in the function.
+    // Augment the eh_frame instructions with epilogue descriptions if necessary
+    // so the UnwindPlan can be used at any instruction in the function.
 
-  UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
-  if (assembly_profiler_sp) {
-    if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite(
-            m_range, thread, *m_unwind_plan_eh_frame_augmented_sp)) {
-      m_unwind_plan_eh_frame_augmented_sp.reset();
+    UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
+    if (assembly_profiler_sp) {
+      auto plan_sp = std::make_shared<UnwindPlan>(*eh_frame_plan);
+      if (assembly_profiler_sp->AugmentUnwindPlanFromCallSite(m_range, thread,
+                                                              *plan_sp)) {
+        return plan_sp;
+      }
     }
-  } else {
-    m_unwind_plan_eh_frame_augmented_sp.reset();
-  }
-  return m_unwind_plan_eh_frame_augmented_sp;
+    return UnwindPlanSP();
+  });
 }
 
 UnwindPlanSP FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target,
                                                              Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  if (m_unwind_plan_debug_frame_augmented_sp.get() ||
-      m_tried_unwind_plan_debug_frame_augmented)
-    return m_unwind_plan_debug_frame_augmented_sp;
-
-  // Only supported on x86 architectures where we get debug_frame from the
-  // compiler that describes the prologue instructions perfectly, and sometimes
-  // the epilogue instructions too.
-  if (target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_32_i386 &&
-      target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64 &&
-      target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64h) {
-    m_tried_unwind_plan_debug_frame_augmented = true;
-    return m_unwind_plan_debug_frame_augmented_sp;
-  }
-
-  m_tried_unwind_plan_debug_frame_augmented = true;
-
-  UnwindPlanSP debug_frame_plan = GetDebugFrameUnwindPlan(target);
-  if (!debug_frame_plan)
-    return m_unwind_plan_debug_frame_augmented_sp;
+  return m_unwind_plan_debug_frame.Get([&] {
+    // Only supported on x86 architectures where we get debug_frame from the
+    // compiler that describes the prologue instructions perfectly, and
+    // sometimes the epilogue instructions too.
+    if (target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_32_i386 &&
+        target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64 &&
+        target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64h) {
+      return UnwindPlanSP();
+    }
 
-  m_unwind_plan_debug_frame_augmented_sp =
-      std::make_shared<UnwindPlan>(*debug_frame_plan);
+    UnwindPlanSP debug_frame_plan = GetDebugFrameUnwindPlan(target);
+    if (!debug_frame_plan)
+      return UnwindPlanSP();
 
-  // Augment the debug_frame instructions with epilogue descriptions if
-  // necessary so the UnwindPlan can be used at any instruction in the
-  // function.
+    // Augment the debug_frame instructions with epilogue descriptions if
+    // necessary so the UnwindPlan can be used at any instruction in the
+    // function.
 
-  UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
-  if (assembly_profiler_sp) {
-    if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite(
-            m_range, thread, *m_unwind_plan_debug_frame_augmented_sp)) {
-      m_unwind_plan_debug_frame_augmented_sp.reset();
+    UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
+    if (assembly_profiler_sp) {
+      auto plan_sp = std::make_shared<UnwindPlan>(*debug_frame_plan);
+      if (assembly_profiler_sp->AugmentUnwindPlanFromCallSite(m_range, thread,
+                                                              *plan_sp)) {
+        return plan_sp;
+      }
     }
-  } else
-    m_unwind_plan_debug_frame_augmented_sp.reset();
-  return m_unwind_plan_debug_frame_augmented_sp;
+    return UnwindPlanSP();
+  });
 }
 
 UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target &target,
                                                   Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  if (m_unwind_plan_assembly_sp.get() || m_tried_unwind_plan_assembly ||
-      !m_unwind_table.GetAllowAssemblyEmulationUnwindPlans()) {
-    return m_unwind_plan_assembly_sp;
-  }
-
-  m_tried_unwind_plan_assembly = true;
-
-  UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
-  if (assembly_profiler_sp) {
-    m_unwind_plan_assembly_sp =
-        std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-    if (!assembly_profiler_sp->GetNonCallSiteUnwindPlanFromAssembly(
-            m_range, thread, *m_unwind_plan_assembly_sp)) {
-      m_unwind_plan_assembly_sp.reset();
+  return m_unwind_plan_assembly.Get([&] {
+    if (!m_unwind_table.GetAllowAssemblyEmulationUnwindPlans())
+      return UnwindPlanSP();
+
+    UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
+    if (assembly_profiler_sp) {
+      auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+      if (assembly_profiler_sp->GetNonCallSiteUnwindPlanFromAssembly(
+              m_range, thread, *plan_sp)) {
+        return plan_sp;
+      }
     }
-  }
-  return m_unwind_plan_assembly_sp;
+    return lldb::UnwindPlanSP();
+  });
 }
 
 // This method compares the pc unwind rule in the first row of two UnwindPlans.
@@ -368,70 +329,44 @@
 UnwindPlanSP FuncUnwinders::GetUnwindPlanFastUnwind(Target &target,
                                                     Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  if (m_unwind_plan_fast_sp.get() || m_tried_unwind_fast)
-    return m_unwind_plan_fast_sp;
-
-  m_tried_unwind_fast = true;
-
-  UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
-  if (assembly_profiler_sp) {
-    m_unwind_plan_fast_sp =
-        std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-    if (!assembly_profiler_sp->GetFastUnwindPlan(m_range, thread,
-                                                 *m_unwind_plan_fast_sp)) {
-      m_unwind_plan_fast_sp.reset();
+  return m_unwind_plan_fast.Get([&] {
+    UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target));
+    if (assembly_profiler_sp) {
+      auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+      if (assembly_profiler_sp->GetFastUnwindPlan(m_range, thread, *plan_sp))
+        return plan_sp;
     }
-  }
-  return m_unwind_plan_fast_sp;
+    return UnwindPlanSP();
+  });
 }
 
 UnwindPlanSP FuncUnwinders::GetUnwindPlanArchitectureDefault(Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  if (m_unwind_plan_arch_default_sp.get() || m_tried_unwind_arch_default)
-    return m_unwind_plan_arch_default_sp;
-
-  m_tried_unwind_arch_default = true;
-
-  Address current_pc;
-  ProcessSP process_sp(thread.CalculateProcess());
-  if (process_sp) {
-    ABI *abi = process_sp->GetABI().get();
-    if (abi) {
-      m_unwind_plan_arch_default_sp =
-          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-      if (!abi->CreateDefaultUnwindPlan(*m_unwind_plan_arch_default_sp)) {
-        m_unwind_plan_arch_default_sp.reset();
+  return m_unwind_plan_arch_default.Get([&] {
+    if (ProcessSP process_sp = thread.CalculateProcess()) {
+      if (ABI *abi = process_sp->GetABI().get()) {
+        auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+        if (abi->CreateDefaultUnwindPlan(*plan_sp))
+          return plan_sp;
       }
     }
-  }
-
-  return m_unwind_plan_arch_default_sp;
+    return UnwindPlanSP();
+  });
 }
 
 UnwindPlanSP
 FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry(Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
-  if (m_unwind_plan_arch_default_at_func_entry_sp.get() ||
-      m_tried_unwind_arch_default_at_func_entry)
-    return m_unwind_plan_arch_default_at_func_entry_sp;
-
-  m_tried_unwind_arch_default_at_func_entry = true;
-
-  Address current_pc;
-  ProcessSP process_sp(thread.CalculateProcess());
-  if (process_sp) {
-    ABI *abi = process_sp->GetABI().get();
-    if (abi) {
-      m_unwind_plan_arch_default_at_func_entry_sp =
-          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-      if (!abi->CreateFunctionEntryUnwindPlan(
-              *m_unwind_plan_arch_default_at_func_entry_sp)) {
-        m_unwind_plan_arch_default_at_func_entry_sp.reset();
+  return m_unwind_plan_arch_default_at_func_entry.Get([&] {
+    if (ProcessSP process_sp = thread.CalculateProcess()) {
+      if (ABI *abi = process_sp->GetABI().get()) {
+        auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
+        if (abi->CreateFunctionEntryUnwindPlan(*plan_sp))
+          return plan_sp;
       }
     }
-  }
-
-  return m_unwind_plan_arch_default_at_func_entry_sp;
+    return UnwindPlanSP();
+  });
 }
 
 Address &FuncUnwinders::GetFirstNonPrologueInsn(Target &target) {
Index: include/lldb/Symbol/FuncUnwinders.h
===================================================================
--- include/lldb/Symbol/FuncUnwinders.h
+++ include/lldb/Symbol/FuncUnwinders.h
@@ -112,31 +112,32 @@
 
   std::recursive_mutex m_mutex;
 
-  lldb::UnwindPlanSP m_unwind_plan_assembly_sp;
-  lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp;
-  lldb::UnwindPlanSP m_unwind_plan_debug_frame_sp;
+  /// A helper class encapsulating the lazy construction of an unwind plan.
+  class LazyPlan {
+    lldb::UnwindPlanSP m_plan_sp;
+
+  public:
+    LazyPlan();
+
+    /// Return the cached unwind plan or call the provided function to compute
+    /// it if we don't have a cached plan yet (and then return it).
+    lldb::UnwindPlanSP Get(llvm::function_ref<lldb::UnwindPlanSP()> compute);
+  };
+
+  LazyPlan m_unwind_plan_assembly;
+  LazyPlan m_unwind_plan_eh_frame;
+  LazyPlan m_unwind_plan_debug_frame;
 
   // augmented by assembly inspection so it's valid everywhere
-  lldb::UnwindPlanSP m_unwind_plan_eh_frame_augmented_sp;
-  lldb::UnwindPlanSP m_unwind_plan_debug_frame_augmented_sp;
-
-  std::vector<lldb::UnwindPlanSP> m_unwind_plan_compact_unwind;
-  lldb::UnwindPlanSP m_unwind_plan_arm_unwind_sp;
-  lldb::UnwindPlanSP m_unwind_plan_symbol_file_sp;
-  lldb::UnwindPlanSP m_unwind_plan_fast_sp;
-  lldb::UnwindPlanSP m_unwind_plan_arch_default_sp;
-  lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp;
-
-  // Fetching the UnwindPlans can be expensive - if we've already attempted to
-  // get one & failed, don't try again.
-  bool m_tried_unwind_plan_assembly : 1, m_tried_unwind_plan_eh_frame : 1,
-      m_tried_unwind_plan_debug_frame : 1,
-      m_tried_unwind_plan_eh_frame_augmented : 1,
-      m_tried_unwind_plan_debug_frame_augmented : 1,
-      m_tried_unwind_plan_compact_unwind : 1,
-      m_tried_unwind_plan_arm_unwind : 1, m_tried_unwind_plan_symbol_file : 1,
-      m_tried_unwind_fast : 1, m_tried_unwind_arch_default : 1,
-      m_tried_unwind_arch_default_at_func_entry : 1;
+  LazyPlan m_unwind_plan_eh_frame_augmented;
+  LazyPlan m_unwind_plan_debug_frame_augmented;
+
+  LazyPlan m_unwind_plan_compact_unwind;
+  LazyPlan m_unwind_plan_arm_unwind;
+  LazyPlan m_unwind_plan_symbol_file;
+  LazyPlan m_unwind_plan_fast;
+  LazyPlan m_unwind_plan_arch_default;
+  LazyPlan m_unwind_plan_arch_default_at_func_entry;
 
   Address m_first_non_prologue_insn;
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to