Skip to content

Commit

Permalink
[lldb] Add swift module load times to statistics dump command
Browse files Browse the repository at this point in the history
  • Loading branch information
bulbazord committed Nov 2, 2022
1 parent b673f7c commit 3bbb050
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 0 deletions.
24 changes: 24 additions & 0 deletions lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Statistics.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
Expand Down Expand Up @@ -1044,6 +1045,25 @@ static void printASTValidationError(
LLDB_LOG(log, " -- {0}", ExtraOpt);
}

llvm::Optional<llvm::json::Value> SwiftASTContext::ReportStatistics() {
const auto &load_times = GetSwiftModuleLoadTimes();
llvm::json::Array swift_module_load_times;
StatsDuration swift_module_total_load_time;
for (const auto &entry : load_times) {
llvm::json::Object obj;
obj.try_emplace("name", entry.first().str());
obj.try_emplace("loadTime", entry.second.get().count());
swift_module_total_load_time += entry.second;
swift_module_load_times.emplace_back(std::move(obj));
}

llvm::json::Object obj;
obj.try_emplace("swiftmodules", std::move(swift_module_load_times));
obj.try_emplace("totalLoadTime", swift_module_total_load_time.get().count());
llvm::json::Value ret = std::move(obj);
return ret;
}

void SwiftASTContext::DiagnoseWarnings(Process &process, Module &module) const {
for (const std::string &message : m_module_import_warnings)
process.PrintWarningCantLoadSwiftModule(module, message);
Expand Down Expand Up @@ -3204,6 +3224,10 @@ swift::ModuleDecl *SwiftASTContext::GetModule(const SourceModule &module,
return module_decl;
}

auto &load_time_map = GetSwiftModuleLoadTimes();
StatsDuration &load_time = load_time_map[module.path.front().GetStringRef()];
ElapsedTime elapsed(load_time);

LLDB_SCOPED_TIMER();
swift::ASTContext *ast = GetASTContext();
if (!ast) {
Expand Down
11 changes: 11 additions & 0 deletions lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
#include "swift/Parse/ParseVersion.h"
#include "lldb/Core/SwiftForward.h"
#include "lldb/Core/ThreadSafeDenseSet.h"
#include "lldb/Target/Statistics.h"
#include "lldb/Utility/Either.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/JSON.h"

namespace swift {
enum class IRGenDebugInfoLevel : unsigned;
Expand Down Expand Up @@ -437,6 +439,14 @@ class SwiftASTContext : public TypeSystemSwift {

const SwiftModuleMap &GetModuleCache() { return m_swift_module_cache; }

typedef llvm::StringMap<StatsDuration> SwiftModuleLoadTimeMap;

SwiftModuleLoadTimeMap &GetSwiftModuleLoadTimes() {
return m_swift_module_load_time_map;
}

llvm::Optional<llvm::json::Value> ReportStatistics() override;

void RaiseFatalError(std::string msg) { m_fatal_errors.SetErrorString(msg); }
static bool HasFatalErrors(swift::ASTContext *ast_context);
bool HasFatalErrors() const {
Expand Down Expand Up @@ -865,6 +875,7 @@ class SwiftASTContext : public TypeSystemSwift {
nullptr;
swift::ClangImporter *m_clang_importer = nullptr;
SwiftModuleMap m_swift_module_cache;
SwiftModuleLoadTimeMap m_swift_module_load_time_map;
SwiftTypeFromMangledNameMap m_mangled_name_to_type_map;
SwiftMangledNameFromTypeMap m_type_to_mangled_name_map;
uint32_t m_pointer_byte_size = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1510,6 +1510,13 @@ Status TypeSystemSwiftTypeRef::IsCompatible() {
return {};
}

llvm::Optional<llvm::json::Value> TypeSystemSwiftTypeRef::ReportStatistics() {
if (auto *swift_ast_context = GetSwiftASTContextOrNull()) {
return swift_ast_context->ReportStatistics();
}
return llvm::None;
}

void TypeSystemSwiftTypeRef::DiagnoseWarnings(Process &process,
Module &module) const {
if (auto *swift_ast_context = GetSwiftASTContextOrNull())
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
bool SupportsLanguage(lldb::LanguageType language) override;
Status IsCompatible() override;

llvm::Optional<llvm::json::Value> ReportStatistics() override;

void DiagnoseWarnings(Process &process, Module &module) const override;
DWARFASTParser *GetDWARFParser() override;
// CompilerDecl functions
Expand Down
2 changes: 2 additions & 0 deletions lldb/test/API/commands/statistics/swift/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SWIFT_SOURCES := main.swift
include Makefile.rules
51 changes: 51 additions & 0 deletions lldb/test/API/commands/statistics/swift/TestSwiftStats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import lldb
import json
import os
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil

class TestCase(TestBase):

NO_DEBUG_INFO_TESTCASE = True

def get_stats(self):
"""
Get the output of the "statistics dump" command and return the JSON
as a python dictionary
"""
return_obj = lldb.SBCommandReturnObject()
command = "statistics dump"
self.ci.HandleCommand(command, return_obj, False)
metrics_json = return_obj.GetOutput()
return json.loads(metrics_json)

def force_module_load(self):
"""
Force a module to load with expression evaluation
"""
self.expect("po point", substrs=["{23, 42}"])

@swiftTest
@skipUnlessFoundation
def test_type_system_info(self):
"""
Test 'statistics dump' and the type system info
"""
self.build()
target = self.createTestTarget()
lldbutil.run_to_source_breakpoint(self, "// break here",
lldb.SBFileSpec("main.swift"))
# Do something to cause modules to load
self.force_module_load()

debug_stats = self.get_stats()
self.assertTrue("modules" in debug_stats)
modules_array = debug_stats["modules"]
for module in modules_array:
if "TypeSystemInfo" in module:
type_system_info = module["TypeSystemInfo"]
self.assertTrue("swiftmodules" in type_system_info)
for module_info in type_system_info["swiftmodules"]:
self.assertTrue("loadTime" in module_info)
self.assertTrue("name" in module_info)
8 changes: 8 additions & 0 deletions lldb/test/API/commands/statistics/swift/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Foundation

func main() {
var point = NSMakeRange(23, 42)
print(point) // break here
}

main()

0 comments on commit 3bbb050

Please sign in to comment.