From 3dea9486b946151938348d3442c7503274aa3df4 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 23 Sep 2018 12:10:40 -0700 Subject: [PATCH] Misc Move using below #include to make preamble happy textDocument/references: if no references, first line or last line => list where this file is included malloc_trim() only if files have been indexed in last cycle Intern: use CachedHashStringRef --- src/clang_complete.cc | 4 ++- src/indexer.cc | 10 +++---- src/indexer.h | 1 - src/main.cc | 7 +++-- src/message_handler.h | 1 - src/messages/ccls_call.cc | 3 +- src/messages/ccls_member.cc | 5 ++-- src/messages/ccls_reload.cc | 7 ++--- src/messages/initialize.cc | 6 ++-- src/messages/textDocument_completion.cc | 12 +++----- src/messages/textDocument_definition.cc | 5 ++-- src/messages/textDocument_didClose.cc | 3 +- src/messages/textDocument_didOpen.cc | 3 +- src/messages/textDocument_didSave.cc | 3 +- src/messages/textDocument_references.cc | 15 ++++++---- src/messages/textDocument_signatureHelp.cc | 5 ++-- src/messages/workspace_symbol.cc | 3 +- src/pipeline.cc | 10 +++++-- src/platform_posix.cc | 2 +- src/project.cc | 12 ++++---- src/serializer.cc | 33 +++++++++++++--------- src/serializer.h | 8 +++++- 22 files changed, 87 insertions(+), 71 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index e3f814e8..41b855bc 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -163,7 +163,9 @@ std::unique_ptr BuildCompilerInstance( CompletionSession &session, std::unique_ptr CI, DiagnosticConsumer &DC, const WorkingFiles::Snapshot &snapshot, std::vector> &Bufs) { - std::string main = ResolveIfRelative(session.file.directory, CI->getFrontendOpts().Inputs[0].getFile()); + std::string main = ResolveIfRelative( + session.file.directory, + sys::path::convert_to_slash(CI->getFrontendOpts().Inputs[0].getFile())); for (auto &file : snapshot.files) { Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content)); if (file.filename == main) diff --git a/src/indexer.cc b/src/indexer.cc index fbf9007c..84303b9b 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -10,7 +10,6 @@ #include "pipeline.hh" #include "platform.h" #include "serializer.h" -using namespace ccls; #include #include @@ -21,16 +20,15 @@ using namespace ccls; #include #include #include -#include -using namespace clang; -using llvm::Timer; #include #include -#include #include #include +using namespace ccls; +using namespace clang; + namespace { constexpr int kInitializerMaxLines = 3; @@ -494,7 +492,7 @@ public: def.short_name_offset = Str.size() + qualified.size() - short_name.size(); def.short_name_size = short_name.size(); Str += StringRef(qualified.data(), qualified.size()); - def.detailed_name = Intern(Str.str()); + def.detailed_name = Intern(Str); } else { SetName(D, short_name, qualified, def); } diff --git a/src/indexer.h b/src/indexer.h index b9056114..6d274166 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -18,7 +18,6 @@ #include #include -#include #include #include #include diff --git a/src/main.cc b/src/main.cc index cb9eb9cb..669968ea 100644 --- a/src/main.cc +++ b/src/main.cc @@ -8,15 +8,12 @@ #include "serializers/json.h" #include "test.h" #include "working_files.h" -using namespace ccls; #include #include #include #include #include -using namespace llvm; -using namespace llvm::cl; #include @@ -26,6 +23,10 @@ using namespace llvm::cl; #include #include +using namespace ccls; +using namespace llvm; +using namespace llvm::cl; + std::string g_init_options; namespace { diff --git a/src/message_handler.h b/src/message_handler.h index e4e51c9c..8c9e5b5f 100644 --- a/src/message_handler.h +++ b/src/message_handler.h @@ -75,7 +75,6 @@ MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, jsonrpc, method, struct MessageHandler { DB *db = nullptr; - MultiQueueWaiter *waiter = nullptr; Project *project = nullptr; VFS *vfs = nullptr; SemanticHighlight *highlight = nullptr; diff --git a/src/messages/ccls_call.cc b/src/messages/ccls_call.cc index 432be592..b5653d4c 100644 --- a/src/messages/ccls_call.cc +++ b/src/messages/ccls_call.cc @@ -5,10 +5,11 @@ #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; #include +using namespace ccls; + namespace { MethodType kMethodType = "$ccls/call"; diff --git a/src/messages/ccls_member.cc b/src/messages/ccls_member.cc index 1b46f362..2c13b19d 100644 --- a/src/messages/ccls_member.cc +++ b/src/messages/ccls_member.cc @@ -5,14 +5,15 @@ #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; #include #include -using namespace clang; #include +using namespace ccls; +using namespace clang; + namespace { MethodType kMethodType = "$ccls/member"; diff --git a/src/messages/ccls_reload.cc b/src/messages/ccls_reload.cc index 4f2f35d0..2c5f3bed 100644 --- a/src/messages/ccls_reload.cc +++ b/src/messages/ccls_reload.cc @@ -5,14 +5,14 @@ #include "match.h" #include "message_handler.h" #include "pipeline.hh" -#include "platform.h" #include "project.h" #include "working_files.h" -using namespace ccls; #include #include +using namespace ccls; + namespace { MethodType kMethodType = "$ccls/reload"; @@ -22,8 +22,7 @@ struct In_CclsReload : public NotificationInMessage { bool dependencies = true; std::vector whitelist; std::vector blacklist; - }; - Params params; + } params; }; MAKE_REFLECT_STRUCT(In_CclsReload::Params, dependencies, whitelist, blacklist); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 7b9a91f5..ca8f7006 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -11,16 +11,16 @@ #include "project.h" #include "serializers/json.h" #include "working_files.h" -using namespace ccls; #include #include -using namespace llvm; -#include #include #include +using namespace ccls; +using namespace llvm; + // TODO Cleanup global variables extern std::string g_init_options; diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index c40c4a58..2b62af70 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -8,16 +8,16 @@ #include "message_handler.h" #include "pipeline.hh" #include "working_files.h" -using namespace ccls; #include #include -#include -using namespace clang; -using namespace llvm; #include +using namespace ccls; +using namespace clang; +using namespace llvm; + namespace { MethodType kMethodType = "textDocument/completion"; @@ -167,10 +167,6 @@ void FilterAndSortCompletionResponse( const std::string &complete_text, bool has_open_paren) { if (!g_config->completion.filterAndSort) return; - - static Timer timer("FilterAndSortCompletionResponse", ""); - TimeRegion region(timer); - auto &items = complete_response->result.items; auto finalize = [&]() { diff --git a/src/messages/textDocument_definition.cc b/src/messages/textDocument_definition.cc index 9546725b..d5ed12f4 100644 --- a/src/messages/textDocument_definition.cc +++ b/src/messages/textDocument_definition.cc @@ -4,11 +4,12 @@ #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; -#include #include #include +#include + +using namespace ccls; namespace { MethodType kMethodType = "textDocument/definition"; diff --git a/src/messages/textDocument_didClose.cc b/src/messages/textDocument_didClose.cc index 62645c88..4baa8cda 100644 --- a/src/messages/textDocument_didClose.cc +++ b/src/messages/textDocument_didClose.cc @@ -14,8 +14,7 @@ struct In_TextDocumentDidClose : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } struct Params { lsTextDocumentIdentifier textDocument; - }; - Params params; + } params; }; MAKE_REFLECT_STRUCT(In_TextDocumentDidClose::Params, textDocument); MAKE_REFLECT_STRUCT(In_TextDocumentDidClose, params); diff --git a/src/messages/textDocument_didOpen.cc b/src/messages/textDocument_didOpen.cc index f67c9008..26872d1a 100644 --- a/src/messages/textDocument_didOpen.cc +++ b/src/messages/textDocument_didOpen.cc @@ -12,7 +12,6 @@ using namespace ccls; namespace { MethodType kMethodType = "textDocument/didOpen"; -// Open, view, change, close file struct In_TextDocumentDidOpen : public NotificationInMessage { MethodType GetMethodType() const override { return kMethodType; } @@ -37,7 +36,7 @@ struct Handler_TextDocumentDidOpen // NOTE: This function blocks code lens. If it starts taking a long time // we will need to find a way to unblock the code lens request. const auto ¶ms = request->params; - std::string path = params.textDocument.uri.GetPath(); + const std::string &path = params.textDocument.uri.GetPath(); WorkingFile *working_file = working_files->OnOpen(params.textDocument); if (std::optional cached_file_contents = diff --git a/src/messages/textDocument_didSave.cc b/src/messages/textDocument_didSave.cc index d4d89de3..1846e047 100644 --- a/src/messages/textDocument_didSave.cc +++ b/src/messages/textDocument_didSave.cc @@ -4,7 +4,6 @@ #include "clang_complete.hh" #include "message_handler.h" #include "pipeline.hh" -#include "project.h" using namespace ccls; namespace { @@ -32,7 +31,7 @@ struct Handler_TextDocumentDidSave void Run(In_TextDocumentDidSave *request) override { const auto ¶ms = request->params; - std::string path = params.textDocument.uri.GetPath(); + const std::string &path = params.textDocument.uri.GetPath(); pipeline::Index(path, {}, IndexMode::Normal); clang_complete->NotifySave(path); } diff --git a/src/messages/textDocument_references.cc b/src/messages/textDocument_references.cc index 069de51a..7b34b10c 100644 --- a/src/messages/textDocument_references.cc +++ b/src/messages/textDocument_references.cc @@ -4,10 +4,11 @@ #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; #include +using namespace ccls; + namespace { MethodType kMethodType = "textDocument/references"; @@ -54,13 +55,17 @@ struct Handler_TextDocumentReferences if (!FindFileOrFail(db, project, request->id, params.textDocument.uri.GetPath(), &file)) return; - - WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); - Out_TextDocumentReferences out; out.id = request->id; + WorkingFile *wfile = working_files->GetFileByFilename(file->def->path); + if (!file) { + pipeline::WriteStdout(kMethodType, out); + return; + } + bool container = g_config->xref.container; std::unordered_set seen_uses; + int line = params.position.line; for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) { // Found symbol. Return references. @@ -115,7 +120,7 @@ struct Handler_TextDocumentReferences // = 0, // use the current filename. std::string path; - if (params.position.line == 0) + if (line == 0 || line >= (int)wfile->buffer_lines.size() - 1) path = file->def->path; for (const IndexInclude &include : file->def->includes) if (include.line == params.position.line) { diff --git a/src/messages/textDocument_signatureHelp.cc b/src/messages/textDocument_signatureHelp.cc index c904082a..6c414ca9 100644 --- a/src/messages/textDocument_signatureHelp.cc +++ b/src/messages/textDocument_signatureHelp.cc @@ -4,12 +4,11 @@ #include "clang_complete.hh" #include "message_handler.h" #include "pipeline.hh" -using namespace ccls; #include -using namespace clang; -#include +using namespace ccls; +using namespace clang; namespace { MethodType kMethodType = "textDocument/signatureHelp"; diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 00c0aa27..db0ddb34 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -5,13 +5,14 @@ #include "message_handler.h" #include "pipeline.hh" #include "query_utils.h" -using namespace ccls; #include #include #include #include +using namespace ccls; + namespace { MethodType kMethodType = "workspace/symbol"; diff --git a/src/pipeline.cc b/src/pipeline.cc index f31eb03d..f811d840 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -478,7 +478,6 @@ void MainLoop() { // Setup shared references. for (MessageHandler *handler : *MessageHandler::message_handlers) { handler->db = &db; - handler->waiter = indexer_waiter; handler->project = &project; handler->vfs = &vfs; handler->highlight = &highlight; @@ -487,6 +486,7 @@ void MainLoop() { handler->include_complete = &include_complete; } + bool last_indexed = false; while (true) { std::vector> messages = on_request->DequeueAll(); bool did_work = messages.size(); @@ -503,18 +503,22 @@ void MainLoop() { LOG_S(ERROR) << "No handler for " << message->GetMethodType(); } - for (int i = 80; i--;) { + bool indexed = false; + for (int i = 20; i--;) { std::optional update = on_indexed->TryPopFront(); if (!update) break; did_work = true; + indexed = true; Main_OnIndexed(&db, &highlight, &working_files, &*update); } if (!did_work) { - FreeUnusedMemory(); + if (last_indexed) + FreeUnusedMemory(); main_waiter->Wait(on_indexed, on_request); } + last_indexed = indexed; } } diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 638e7a82..7119aa3d 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -101,7 +101,7 @@ std::string NormalizePath(const std::string &path) { void FreeUnusedMemory() { #ifdef __GLIBC__ - malloc_trim(0); + malloc_trim(4 * 1024 * 1024); #endif } diff --git a/src/project.cc b/src/project.cc index 681e8d97..2c0fcf6e 100644 --- a/src/project.cc +++ b/src/project.cc @@ -13,18 +13,14 @@ #include "serializers/json.h" #include "utils.h" #include "working_files.h" -using namespace ccls; #include #include #include #include -#include #include #include #include -using namespace clang; -using namespace llvm; #include @@ -32,10 +28,14 @@ using namespace llvm; #include #endif -#include +#include #include #include +using namespace ccls; +using namespace clang; +using namespace llvm; + namespace { enum class ProjectMode { CompileCommandsJson, DotCcls, ExternalCommand }; @@ -387,7 +387,7 @@ Project::FindCompilationEntryForFile(const std::string &filename) { // We couldn't find the file. Try to infer it. // TODO: Cache inferred file in a separate array (using a lock or similar) Entry *best_entry = nullptr; - int best_score = std::numeric_limits::min(); + int best_score = INT_MIN; for (Entry &entry : entries) { int score = ComputeGuessScore(filename, entry.filename); if (score > best_score) { diff --git a/src/serializer.cc b/src/serializer.cc index c64d2461..b7cc64ca 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -154,12 +154,11 @@ void Reflect(Reader &vis, DenseMap &v) { if (vis.Format() == SerializeFormat::Json) { auto &vis1 = static_cast(vis); for (auto it = vis1.m().MemberBegin(); it != vis1.m().MemberEnd(); ++it) - v[CachedHashStringRef(Intern(it->name.GetString()))] = - it->value.GetInt64(); + v[InternH(it->name.GetString())] = it->value.GetInt64(); } else { vis.IterArray([&](Reader &entry) { Reflect(entry, name); - Reflect(entry, v[CachedHashStringRef(Intern(name))]); + Reflect(entry, v[InternH(name)]); }); } } @@ -344,18 +343,26 @@ void Reflect(Writer &visitor, SerializeFormat &value) { namespace ccls { static BumpPtrAllocator Alloc; -static DenseSet Strings; +static DenseSet Strings; static std::mutex AllocMutex; -const char *Intern(const std::string &str) { - if (str.empty()) - return ""; - StringRef Str(str.data(), str.size() + 1); +CachedHashStringRef InternH(StringRef S) { + if (S.empty()) + S = ""; + CachedHashString HS(S); std::lock_guard lock(AllocMutex); - auto R = Strings.insert(Str); - if (R.second) - *R.first = Str.copy(Alloc); - return R.first->data(); + auto R = Strings.insert(HS); + if (R.second) { + char *P = Alloc.Allocate(S.size() + 1); + memcpy(P, S.data(), S.size()); + P[S.size()] = '\0'; + *R.first = CachedHashStringRef(StringRef(P, S.size()), HS.hash()); + } + return *R.first; +} + +const char *Intern(StringRef S) { + return InternH(S).val().data(); } std::string Serialize(SerializeFormat format, IndexFile &file) { @@ -470,7 +477,7 @@ Deserialize(SerializeFormat format, const std::string &path, for (auto &it : file->dependencies) { std::string path = it.first.val().str(); DoPathMapping(path); - dependencies[CachedHashStringRef(Intern(path))] = it.second; + dependencies[InternH(path)] = it.second; } file->dependencies = std::move(dependencies); } diff --git a/src/serializer.h b/src/serializer.h index c3ebca61..9bbd00af 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -18,6 +18,11 @@ #include #include +namespace llvm { +class CachedHashStringRef; +class StringRef; +} + enum class SerializeFormat { Binary, Json }; struct JsonNull {}; @@ -308,7 +313,8 @@ template void ReflectMember(Writer &vis, const char *name, T &v) { // API namespace ccls { -const char *Intern(const std::string &str); +const char *Intern(llvm::StringRef str); +llvm::CachedHashStringRef InternH(llvm::StringRef str); std::string Serialize(SerializeFormat format, IndexFile &file); std::unique_ptr Deserialize(SerializeFormat format, const std::string &path,