Add an "experimental" setting to disable injecting local variables into expressions.

This feature was added to solve a lookup problem in expressions when local variables
shadow ivars.  That solution requires fully realizing all local variables to evaluate
any expression, and can cause significant performance problems when evaluating 
expressions in frames that have many complex locals.

Until we get a better solution, this setting mitigates the problem when you don't
have local variables that shadow ivars.

<rdar://problem/27226122>

llvm-svn: 274783
This commit is contained in:
Jim Ingham 2016-07-07 18:25:48 +00:00
parent f39977112a
commit bed6779c7a
5 changed files with 90 additions and 9 deletions

View File

@ -63,6 +63,12 @@ typedef enum LoadCWDlldbinitFile
//----------------------------------------------------------------------
// TargetProperties
//----------------------------------------------------------------------
class TargetExperimentalProperties : public Properties
{
public:
TargetExperimentalProperties();
};
class TargetProperties : public Properties
{
public:
@ -237,6 +243,12 @@ public:
void
SetProcessLaunchInfo(const ProcessLaunchInfo &launch_info);
bool
GetInjectLocalVariables(ExecutionContext *exe_ctx) const;
void
SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b);
private:
//------------------------------------------------------------------
@ -257,6 +269,7 @@ private:
// Member variables.
//------------------------------------------------------------------
ProcessLaunchInfo m_launch_info;
std::unique_ptr<TargetExperimentalProperties> m_experimental_properties_up;
};
class EvaluateExpressionOptions

View File

@ -121,7 +121,7 @@ Properties::IsSettingExperimental(const char *setting)
return false;
const char *experimental = GetExperimentalSettingsName();
auto dot_pos = strchr(setting, '.');
const char *dot_pos = strchr(setting, '.');
if (dot_pos == nullptr)
return strcmp(experimental, setting) == 0;
else

View File

@ -200,7 +200,8 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
const char *target_specific_defines = "typedef signed char BOOL;\n";
std::string module_macros;
if (Target *target = exe_ctx.GetTargetPtr())
Target *target = exe_ctx.GetTargetPtr();
if (target)
{
if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64)
{
@ -278,8 +279,11 @@ bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrappi
ConstString object_name;
if (Language::LanguageIsCPlusPlus(frame->GetLanguage()))
{
lldb::VariableListSP var_list_sp = frame->GetInScopeVariableList(false, true);
AddLocalVariableDecls(var_list_sp, lldb_local_var_decls);
if (target->GetInjectLocalVariables(&exe_ctx))
{
lldb::VariableListSP var_list_sp = frame->GetInScopeVariableList(false, true);
AddLocalVariableDecls(var_list_sp, lldb_local_var_decls);
}
}
}

View File

@ -371,8 +371,8 @@ ASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body,
return false;
ExprResult address_of_expr = m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr);
m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true, false);
if (address_of_expr.get())
m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true, false);
}
else
{

View File

@ -3520,7 +3520,8 @@ enum
ePropertyDisplayExpressionsInCrashlogs,
ePropertyTrapHandlerNames,
ePropertyDisplayRuntimeSupportValues,
ePropertyNonStopModeEnabled
ePropertyNonStopModeEnabled,
ePropertyExperimental
};
class TargetOptionValueProperties : public OptionValueProperties
@ -3628,6 +3629,38 @@ protected:
mutable bool m_got_host_env;
};
//----------------------------------------------------------------------
// TargetProperties
//----------------------------------------------------------------------
static PropertyDefinition
g_experimental_properties[]
{
{ "inject-local-vars", OptionValue::eTypeBoolean , true, true, nullptr, nullptr, "If true, inject local variables explicitly into the expression text. "
"This will fix symbol resolution when there are name collisions between ivars and local variables. "
"But it can make expressions run much more slowly." },
{ nullptr, OptionValue::eTypeInvalid , true, 0 , nullptr, nullptr, nullptr }
};
enum
{
ePropertyInjectLocalVars = 0
};
class TargetExperimentalOptionValueProperties : public OptionValueProperties
{
public:
TargetExperimentalOptionValueProperties () :
OptionValueProperties (ConstString(Properties::GetExperimentalSettingsName()))
{
}
};
TargetExperimentalProperties::TargetExperimentalProperties() :
Properties(OptionValuePropertiesSP(new TargetExperimentalOptionValueProperties()))
{
m_collection_sp->Initialize(g_experimental_properties);
}
//----------------------------------------------------------------------
// TargetProperties
//----------------------------------------------------------------------
@ -3649,7 +3682,13 @@ TargetProperties::TargetProperties (Target *target) :
m_collection_sp->SetValueChangedCallback(ePropertyDetachOnError, TargetProperties::DetachOnErrorValueChangedCallback, this);
m_collection_sp->SetValueChangedCallback(ePropertyDisableASLR, TargetProperties::DisableASLRValueChangedCallback, this);
m_collection_sp->SetValueChangedCallback(ePropertyDisableSTDIO, TargetProperties::DisableSTDIOValueChangedCallback, this);
m_experimental_properties_up.reset(new TargetExperimentalProperties());
m_collection_sp->AppendProperty (ConstString(Properties::GetExperimentalSettingsName()),
ConstString("Experimental settings - setting these won't produce errors if the setting is not present."),
true,
m_experimental_properties_up->GetValueProperties());
// Update m_launch_info once it was created
Arg0ValueChangedCallback(this, nullptr);
RunArgsValueChangedCallback(this, nullptr);
@ -3665,8 +3704,13 @@ TargetProperties::TargetProperties (Target *target) :
{
m_collection_sp.reset (new TargetOptionValueProperties(ConstString("target")));
m_collection_sp->Initialize(g_properties);
m_experimental_properties_up.reset(new TargetExperimentalProperties());
m_collection_sp->AppendProperty (ConstString(Properties::GetExperimentalSettingsName()),
ConstString("Experimental settings - setting these won't produce errors if the setting is not present."),
true,
m_experimental_properties_up->GetValueProperties());
m_collection_sp->AppendProperty(ConstString("process"),
ConstString("Settings specify to processes."),
ConstString("Settings specific to processes."),
true,
Process::GetGlobalProperties()->GetValueProperties());
}
@ -3674,6 +3718,26 @@ TargetProperties::TargetProperties (Target *target) :
TargetProperties::~TargetProperties() = default;
bool
TargetProperties::GetInjectLocalVariables(ExecutionContext *exe_ctx) const
{
const Property *exp_property = m_collection_sp->GetPropertyAtIndex(exe_ctx, false, ePropertyExperimental);
OptionValueProperties *exp_values = exp_property->GetValue()->GetAsProperties();
if (exp_values)
return exp_values->GetPropertyAtIndexAsBoolean(exe_ctx, ePropertyInjectLocalVars, true);
else
return true;
}
void
TargetProperties::SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b)
{
const Property *exp_property = m_collection_sp->GetPropertyAtIndex(exe_ctx, true, ePropertyExperimental);
OptionValueProperties *exp_values = exp_property->GetValue()->GetAsProperties();
if (exp_values)
exp_values->SetPropertyAtIndexAsBoolean(exe_ctx, ePropertyInjectLocalVars, true);
}
ArchSpec
TargetProperties::GetDefaultArchitecture () const
{