<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:
Enrico Granata 2012-10-29 21:18:03 +00:00
parent 8f4d7eb518
commit b588726ec9
7 changed files with 123 additions and 31 deletions

View File

@ -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:

View File

@ -365,7 +365,7 @@ public:
GetOptionArgumentPosition (const char *in_string);
ScriptInterpreter *
GetScriptInterpreter ();
GetScriptInterpreter (bool can_create = true);
void
SkipLLDBInitFiles (bool skip_lldbinit_files)

View File

@ -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&) ;

View File

@ -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

View File

@ -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,

View File

@ -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)

View File

@ -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 ()