forked from OSchip/llvm-project
<rdar://problem/11449953> Change Debugger::SetOutputFileHandle() so that it does not automatically initialize the script interpreter in order to transfer its output file handle to it
This should delay initialization of Python until strictly necessary and speed-up debugger startup Also, convert formatters for SEL and BOOL ObjC data-types from Python to C++, in order to reap more performance benefits from the above changes llvm-svn: 166967
This commit is contained in:
parent
8f4d7eb518
commit
b588726ec9
|
@ -57,6 +57,13 @@ namespace lldb_private {
|
|||
bool
|
||||
NSStringSummaryProvider (ValueObject& valobj, Stream& stream);
|
||||
|
||||
bool
|
||||
ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream);
|
||||
|
||||
template <bool is_sel_ptr>
|
||||
bool
|
||||
ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream);
|
||||
|
||||
bool
|
||||
RuntimeSpecificDescriptionSummaryProvider (ValueObject& valobj, Stream& stream);
|
||||
|
||||
|
@ -72,6 +79,12 @@ namespace lldb_private {
|
|||
extern template bool
|
||||
NSDataSummaryProvider<false> (ValueObject&, Stream&) ;
|
||||
|
||||
extern template bool
|
||||
ObjCSELSummaryProvider<true> (ValueObject&, Stream&);
|
||||
|
||||
extern template bool
|
||||
ObjCSELSummaryProvider<false> (ValueObject&, Stream&);
|
||||
|
||||
class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -365,7 +365,7 @@ public:
|
|||
GetOptionArgumentPosition (const char *in_string);
|
||||
|
||||
ScriptInterpreter *
|
||||
GetScriptInterpreter ();
|
||||
GetScriptInterpreter (bool can_create = true);
|
||||
|
||||
void
|
||||
SkipLLDBInitFiles (bool skip_lldbinit_files)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "lldb/Core/ValueObject.h"
|
||||
#include "lldb/Core/ValueObjectConstResult.h"
|
||||
#include "lldb/Host/Endian.h"
|
||||
#include "lldb/Symbol/ClangASTContext.h"
|
||||
#include "lldb/Target/ObjCLanguageRuntime.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
|
@ -687,6 +688,63 @@ lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider (ValueObject
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
lldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream)
|
||||
{
|
||||
const uint32_t type_info = ClangASTContext::GetTypeInfo(valobj.GetClangType(),
|
||||
valobj.GetClangAST(),
|
||||
NULL);
|
||||
|
||||
ValueObjectSP real_guy_sp = valobj.GetSP();
|
||||
|
||||
if (type_info & ClangASTContext::eTypeIsPointer)
|
||||
{
|
||||
Error err;
|
||||
real_guy_sp = valobj.Dereference(err);
|
||||
if (err.Fail() || !real_guy_sp)
|
||||
return false;
|
||||
}
|
||||
else if (type_info & ClangASTContext::eTypeIsReference)
|
||||
{
|
||||
real_guy_sp = valobj.GetChildAtIndex(0, true);
|
||||
if (!real_guy_sp)
|
||||
return false;
|
||||
}
|
||||
uint64_t value = real_guy_sp->GetValueAsUnsigned(0);
|
||||
if (value == 0)
|
||||
{
|
||||
stream.Printf("NO");
|
||||
return true;
|
||||
}
|
||||
stream.Printf("YES");
|
||||
return true;
|
||||
}
|
||||
|
||||
template <bool is_sel_ptr>
|
||||
bool
|
||||
lldb_private::formatters::ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream)
|
||||
{
|
||||
lldb::addr_t data_address = LLDB_INVALID_ADDRESS;
|
||||
|
||||
if (is_sel_ptr)
|
||||
data_address = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
|
||||
else
|
||||
data_address = valobj.GetAddressOf();
|
||||
|
||||
if (data_address == LLDB_INVALID_ADDRESS)
|
||||
return false;
|
||||
|
||||
ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
|
||||
|
||||
void* char_opaque_type = valobj.GetClangAST()->CharTy.getAsOpaquePtr();
|
||||
ClangASTType charstar(valobj.GetClangAST(),ClangASTType::GetPointerType(valobj.GetClangAST(), char_opaque_type));
|
||||
|
||||
ValueObjectSP valobj_sp(ValueObject::CreateValueObjectFromAddress("text", data_address, exe_ctx, charstar));
|
||||
|
||||
stream.Printf("%s",valobj_sp->GetSummaryAsCString());
|
||||
return true;
|
||||
}
|
||||
|
||||
lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
|
||||
SyntheticChildrenFrontEnd(*valobj_sp.get()),
|
||||
m_exe_ctx_ref(),
|
||||
|
@ -1417,3 +1475,9 @@ lldb_private::formatters::NSDataSummaryProvider<true> (ValueObject&, Stream&) ;
|
|||
|
||||
template bool
|
||||
lldb_private::formatters::NSDataSummaryProvider<false> (ValueObject&, Stream&) ;
|
||||
|
||||
template bool
|
||||
lldb_private::formatters::ObjCSELSummaryProvider<true> (ValueObject&, Stream&) ;
|
||||
|
||||
template bool
|
||||
lldb_private::formatters::ObjCSELSummaryProvider<false> (ValueObject&, Stream&) ;
|
||||
|
|
|
@ -681,7 +681,12 @@ Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
|
|||
if (out_file.IsValid() == false)
|
||||
out_file.SetStream (stdout, false);
|
||||
|
||||
GetCommandInterpreter().GetScriptInterpreter()->ResetOutputFileHandle (fh);
|
||||
// do not create the ScriptInterpreter just for setting the output file handle
|
||||
// as the constructor will know how to do the right thing on its own
|
||||
const bool can_create = false;
|
||||
ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
|
||||
if (script_interpreter)
|
||||
script_interpreter->ResetOutputFileHandle (fh);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -947,35 +947,28 @@ FormatManager::LoadObjCFormatters()
|
|||
|
||||
TypeCategoryImpl::SharedPointer objc_category_sp = GetCategory(m_objc_category_name);
|
||||
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
lldb::TypeSummaryImplSP ObjC_BOOL_summary(new ScriptSummaryFormat(objc_flags,
|
||||
"lldb.formatters.objc.objc.BOOL_SummaryProvider",
|
||||
""));
|
||||
lldb::TypeSummaryImplSP ObjC_BOOL_summary(new CXXFunctionSummaryFormat(objc_flags, lldb_private::formatters::ObjCBOOLSummaryProvider,""));
|
||||
objc_category_sp->GetSummaryNavigator()->Add(ConstString("BOOL"),
|
||||
ObjC_BOOL_summary);
|
||||
|
||||
lldb::TypeSummaryImplSP ObjC_BOOLRef_summary(new ScriptSummaryFormat(objc_flags,
|
||||
"lldb.formatters.objc.objc.BOOLRef_SummaryProvider",
|
||||
""));
|
||||
objc_category_sp->GetSummaryNavigator()->Add(ConstString("BOOL &"),
|
||||
ObjC_BOOLRef_summary);
|
||||
lldb::TypeSummaryImplSP ObjC_BOOLPtr_summary(new ScriptSummaryFormat(objc_flags,
|
||||
"lldb.formatters.objc.objc.BOOLPtr_SummaryProvider",
|
||||
""));
|
||||
ObjC_BOOL_summary);
|
||||
objc_category_sp->GetSummaryNavigator()->Add(ConstString("BOOL *"),
|
||||
ObjC_BOOLPtr_summary);
|
||||
ObjC_BOOL_summary);
|
||||
|
||||
|
||||
|
||||
// we need to skip pointers here since we are special casing a SEL* when retrieving its value
|
||||
objc_flags.SetSkipPointers(true);
|
||||
AddScriptSummary(objc_category_sp, "lldb.formatters.objc.Selector.SEL_Summary", ConstString("SEL"), objc_flags);
|
||||
AddScriptSummary(objc_category_sp, "lldb.formatters.objc.Selector.SEL_Summary", ConstString("struct objc_selector"), objc_flags);
|
||||
AddScriptSummary(objc_category_sp, "lldb.formatters.objc.Selector.SEL_Summary", ConstString("objc_selector"), objc_flags);
|
||||
AddScriptSummary(objc_category_sp, "lldb.formatters.objc.Selector.SELPointer_Summary", ConstString("objc_selector *"), objc_flags);
|
||||
AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary", ConstString("SEL"), objc_flags);
|
||||
AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary", ConstString("struct objc_selector"), objc_flags);
|
||||
AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary", ConstString("objc_selector"), objc_flags);
|
||||
AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, "SEL summary", ConstString("objc_selector *"), objc_flags);
|
||||
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
AddScriptSummary(objc_category_sp, "lldb.formatters.objc.Class.Class_Summary", ConstString("Class"), objc_flags);
|
||||
objc_flags.SetSkipPointers(false);
|
||||
#endif // LLDB_DISABLE_PYTHON
|
||||
|
||||
objc_flags.SetSkipPointers(false);
|
||||
|
||||
TypeCategoryImpl::SharedPointer corefoundation_category_sp = GetCategory(m_corefoundation_category_name);
|
||||
|
||||
AddSummary(corefoundation_category_sp,
|
||||
|
|
|
@ -40,22 +40,27 @@
|
|||
#include "../Commands/CommandObjectVersion.h"
|
||||
#include "../Commands/CommandObjectWatchpoint.h"
|
||||
|
||||
#include "lldb/Interpreter/Args.h"
|
||||
#include "lldb/Interpreter/Options.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/Stream.h"
|
||||
#include "lldb/Core/Timer.h"
|
||||
|
||||
#include "lldb/Host/Host.h"
|
||||
|
||||
#include "lldb/Interpreter/Args.h"
|
||||
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/Options.h"
|
||||
#include "lldb/Interpreter/ScriptInterpreterNone.h"
|
||||
#include "lldb/Interpreter/ScriptInterpreterPython.h"
|
||||
|
||||
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Target/TargetList.h"
|
||||
#include "lldb/Utility/CleanUp.h"
|
||||
|
||||
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/ScriptInterpreterNone.h"
|
||||
#include "lldb/Interpreter/ScriptInterpreterPython.h"
|
||||
#include "lldb/Utility/CleanUp.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
@ -2547,8 +2552,14 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
|
|||
}
|
||||
|
||||
ScriptInterpreter *
|
||||
CommandInterpreter::GetScriptInterpreter ()
|
||||
CommandInterpreter::GetScriptInterpreter (bool can_create)
|
||||
{
|
||||
if (m_script_interpreter_ap.get() != NULL)
|
||||
return m_script_interpreter_ap.get();
|
||||
|
||||
if (!can_create)
|
||||
return NULL;
|
||||
|
||||
// <rdar://problem/11751427>
|
||||
// we need to protect the initialization of the script interpreter
|
||||
// otherwise we could end up with two threads both trying to create
|
||||
|
@ -2559,8 +2570,9 @@ CommandInterpreter::GetScriptInterpreter ()
|
|||
static Mutex g_interpreter_mutex(Mutex::eMutexTypeRecursive);
|
||||
Mutex::Locker interpreter_lock(g_interpreter_mutex);
|
||||
|
||||
if (m_script_interpreter_ap.get() != NULL)
|
||||
return m_script_interpreter_ap.get();
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
|
||||
if (log)
|
||||
log->Printf("Initializing the ScriptInterpreter now\n");
|
||||
|
||||
lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage();
|
||||
switch (script_lang)
|
||||
|
|
|
@ -501,6 +501,11 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete
|
|||
{
|
||||
m_new_sysout = PyFile_FromFile (m_dbg_stdout, (char *) "", (char *) "w", _check_and_flush);
|
||||
}
|
||||
|
||||
// get the output file handle from the debugger (if any)
|
||||
File& out_file = interpreter.GetDebugger().GetOutputFile();
|
||||
if (out_file.IsValid())
|
||||
ResetOutputFileHandle(out_file.GetStream());
|
||||
}
|
||||
|
||||
ScriptInterpreterPython::~ScriptInterpreterPython ()
|
||||
|
|
Loading…
Reference in New Issue