comparison clang-tools-extra/clangd/TUScheduler.cpp @ 221:79ff65ed7e25

LLVM12 Original
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 15 Jun 2021 19:15:29 +0900
parents 0572611fdcc8
children 5f17cb93ff66
comparison
equal deleted inserted replaced
220:42394fc6a535 221:79ff65ed7e25
54 #include "Preamble.h" 54 #include "Preamble.h"
55 #include "index/CanonicalIncludes.h" 55 #include "index/CanonicalIncludes.h"
56 #include "support/Cancellation.h" 56 #include "support/Cancellation.h"
57 #include "support/Context.h" 57 #include "support/Context.h"
58 #include "support/Logger.h" 58 #include "support/Logger.h"
59 #include "support/MemoryTree.h"
59 #include "support/Path.h" 60 #include "support/Path.h"
60 #include "support/Threading.h" 61 #include "support/Threading.h"
61 #include "support/Trace.h" 62 #include "support/Trace.h"
62 #include "clang/Frontend/CompilerInvocation.h" 63 #include "clang/Frontend/CompilerInvocation.h"
63 #include "clang/Tooling/CompilationDatabase.h" 64 #include "clang/Tooling/CompilationDatabase.h"
67 #include "llvm/ADT/STLExtras.h" 68 #include "llvm/ADT/STLExtras.h"
68 #include "llvm/ADT/ScopeExit.h" 69 #include "llvm/ADT/ScopeExit.h"
69 #include "llvm/ADT/SmallVector.h" 70 #include "llvm/ADT/SmallVector.h"
70 #include "llvm/ADT/StringExtras.h" 71 #include "llvm/ADT/StringExtras.h"
71 #include "llvm/ADT/StringRef.h" 72 #include "llvm/ADT/StringRef.h"
73 #include "llvm/Support/Allocator.h"
72 #include "llvm/Support/Errc.h" 74 #include "llvm/Support/Errc.h"
73 #include "llvm/Support/ErrorHandling.h" 75 #include "llvm/Support/ErrorHandling.h"
74 #include "llvm/Support/FormatVariadic.h" 76 #include "llvm/Support/FormatVariadic.h"
75 #include "llvm/Support/Path.h" 77 #include "llvm/Support/Path.h"
76 #include "llvm/Support/Threading.h" 78 #include "llvm/Support/Threading.h"
77 #include <algorithm> 79 #include <algorithm>
80 #include <atomic>
78 #include <chrono> 81 #include <chrono>
82 #include <condition_variable>
79 #include <functional> 83 #include <functional>
80 #include <memory> 84 #include <memory>
81 #include <mutex> 85 #include <mutex>
82 #include <queue> 86 #include <queue>
83 #include <string> 87 #include <string>
175 /// Items sorted in LRU order, i.e. first item is the most recently accessed 179 /// Items sorted in LRU order, i.e. first item is the most recently accessed
176 /// one. 180 /// one.
177 std::vector<KVPair> LRU; /* GUARDED_BY(Mut) */ 181 std::vector<KVPair> LRU; /* GUARDED_BY(Mut) */
178 }; 182 };
179 183
184 /// A map from header files to an opened "proxy" file that includes them.
185 /// If you open the header, the compile command from the proxy file is used.
186 ///
187 /// This inclusion information could also naturally live in the index, but there
188 /// are advantages to using open files instead:
189 /// - it's easier to achieve a *stable* choice of proxy, which is important
190 /// to avoid invalidating the preamble
191 /// - context-sensitive flags for libraries with multiple configurations
192 /// (e.g. C++ stdlib sensitivity to -std version)
193 /// - predictable behavior, e.g. guarantees that go-to-def landing on a header
194 /// will have a suitable command available
195 /// - fewer scaling problems to solve (project include graphs are big!)
196 ///
197 /// Implementation details:
198 /// - We only record this for mainfiles where the command was trustworthy
199 /// (i.e. not inferred). This avoids a bad inference "infecting" other files.
200 /// - Once we've picked a proxy file for a header, we stick with it until the
201 /// proxy file is invalidated *and* a new candidate proxy file is built.
202 /// Switching proxies is expensive, as the compile flags will (probably)
203 /// change and therefore we'll end up rebuilding the header's preamble.
204 /// - We don't capture the actual compile command, but just the filename we
205 /// should query to get it. This avoids getting out of sync with the CDB.
206 ///
207 /// All methods are threadsafe. In practice, update() comes from preamble
208 /// threads, remove()s mostly from the main thread, and get() from ASTWorker.
209 /// Writes are rare and reads are cheap, so we don't expect much contention.
210 class TUScheduler::HeaderIncluderCache {
211 // We should be be a little careful how we store the include graph of open
212 // files, as each can have a large number of transitive headers.
213 // This representation is O(unique transitive source files).
214 llvm::BumpPtrAllocator Arena;
215 struct Association {
216 llvm::StringRef MainFile;
217 // Circular-linked-list of associations with the same mainFile.
218 // Null indicates that the mainfile was removed.
219 Association *Next;
220 };
221 llvm::StringMap<Association, llvm::BumpPtrAllocator &> HeaderToMain;
222 llvm::StringMap<Association *, llvm::BumpPtrAllocator &> MainToFirst;
223 std::atomic<size_t> UsedBytes; // Updated after writes.
224 mutable std::mutex Mu;
225
226 void invalidate(Association *First) {
227 Association *Current = First;
228 do {
229 Association *Next = Current->Next;
230 Current->Next = nullptr;
231 Current = Next;
232 } while (Current != First);
233 }
234
235 // Create the circular list and return the head of it.
236 Association *associate(llvm::StringRef MainFile,
237 llvm::ArrayRef<std::string> Headers) {
238 Association *First = nullptr, *Prev = nullptr;
239 for (const std::string &Header : Headers) {
240 auto &Assoc = HeaderToMain[Header];
241 if (Assoc.Next)
242 continue; // Already has a valid association.
243
244 Assoc.MainFile = MainFile;
245 Assoc.Next = Prev;
246 Prev = &Assoc;
247 if (!First)
248 First = &Assoc;
249 }
250 if (First)
251 First->Next = Prev;
252 return First;
253 }
254
255 void updateMemoryUsage() {
256 auto StringMapHeap = [](const auto &Map) {
257 // StringMap stores the hashtable on the heap.
258 // It contains pointers to the entries, and a hashcode for each.
259 return Map.getNumBuckets() * (sizeof(void *) + sizeof(unsigned));
260 };
261 size_t Usage = Arena.getTotalMemory() + StringMapHeap(MainToFirst) +
262 StringMapHeap(HeaderToMain) + sizeof(*this);
263 UsedBytes.store(Usage, std::memory_order_release);
264 }
265
266 public:
267 HeaderIncluderCache() : HeaderToMain(Arena), MainToFirst(Arena) {
268 updateMemoryUsage();
269 }
270
271 // Associate each header with MainFile (unless already associated).
272 // Headers not in the list will have their associations removed.
273 void update(PathRef MainFile, llvm::ArrayRef<std::string> Headers) {
274 std::lock_guard<std::mutex> Lock(Mu);
275 auto It = MainToFirst.try_emplace(MainFile, nullptr);
276 Association *&First = It.first->second;
277 if (First)
278 invalidate(First);
279 First = associate(It.first->first(), Headers);
280 updateMemoryUsage();
281 }
282
283 // Mark MainFile as gone.
284 // This will *not* disassociate headers with MainFile immediately, but they
285 // will be eligible for association with other files that get update()d.
286 void remove(PathRef MainFile) {
287 std::lock_guard<std::mutex> Lock(Mu);
288 Association *&First = MainToFirst[MainFile];
289 if (First)
290 invalidate(First);
291 }
292
293 /// Get the mainfile associated with Header, or the empty string if none.
294 std::string get(PathRef Header) const {
295 std::lock_guard<std::mutex> Lock(Mu);
296 return HeaderToMain.lookup(Header).MainFile.str();
297 }
298
299 size_t getUsedBytes() const {
300 return UsedBytes.load(std::memory_order_acquire);
301 }
302 };
303
180 namespace { 304 namespace {
305
306 bool isReliable(const tooling::CompileCommand &Cmd) {
307 return Cmd.Heuristic.empty();
308 }
309
181 /// Threadsafe manager for updating a TUStatus and emitting it after each 310 /// Threadsafe manager for updating a TUStatus and emitting it after each
182 /// update. 311 /// update.
183 class SynchronizedTUStatus { 312 class SynchronizedTUStatus {
184 public: 313 public:
185 SynchronizedTUStatus(PathRef FileName, ParsingCallbacks &Callbacks) 314 SynchronizedTUStatus(PathRef FileName, ParsingCallbacks &Callbacks)
217 /// instead. 346 /// instead.
218 class PreambleThread { 347 class PreambleThread {
219 public: 348 public:
220 PreambleThread(llvm::StringRef FileName, ParsingCallbacks &Callbacks, 349 PreambleThread(llvm::StringRef FileName, ParsingCallbacks &Callbacks,
221 bool StorePreambleInMemory, bool RunSync, 350 bool StorePreambleInMemory, bool RunSync,
222 SynchronizedTUStatus &Status, ASTWorker &AW) 351 SynchronizedTUStatus &Status,
352 TUScheduler::HeaderIncluderCache &HeaderIncluders,
353 ASTWorker &AW)
223 : FileName(FileName), Callbacks(Callbacks), 354 : FileName(FileName), Callbacks(Callbacks),
224 StoreInMemory(StorePreambleInMemory), RunSync(RunSync), Status(Status), 355 StoreInMemory(StorePreambleInMemory), RunSync(RunSync), Status(Status),
225 ASTPeer(AW) {} 356 ASTPeer(AW), HeaderIncluders(HeaderIncluders) {}
226 357
227 /// It isn't guaranteed that each requested version will be built. If there 358 /// It isn't guaranteed that each requested version will be built. If there
228 /// are multiple update requests while building a preamble, only the last one 359 /// are multiple update requests while building a preamble, only the last one
229 /// will be built. 360 /// will be built.
230 void update(std::unique_ptr<CompilerInvocation> CI, ParseInputs PI, 361 void update(std::unique_ptr<CompilerInvocation> CI, ParseInputs PI,
237 Status.PreambleActivity = PreambleAction::Idle; 368 Status.PreambleActivity = PreambleAction::Idle;
238 }); 369 });
239 return; 370 return;
240 } 371 }
241 { 372 {
242 std::lock_guard<std::mutex> Lock(Mutex); 373 std::unique_lock<std::mutex> Lock(Mutex);
243 // If shutdown is issued, don't bother building. 374 // If NextReq was requested with WantDiagnostics::Yes we cannot just drop
244 if (Done) 375 // that on the floor. Block until we start building it. This won't
245 return; 376 // dead-lock as we are blocking the caller thread, while builds continue
377 // on preamble thread.
378 ReqCV.wait(Lock, [this] {
379 return !NextReq || NextReq->WantDiags != WantDiagnostics::Yes;
380 });
246 NextReq = std::move(Req); 381 NextReq = std::move(Req);
247 } 382 }
248 // Let the worker thread know there's a request, notify_one is safe as there 383 // Let the worker thread know there's a request, notify_one is safe as there
249 // should be a single worker thread waiting on it. 384 // should be a single worker thread waiting on it.
250 ReqCV.notify_all(); 385 ReqCV.notify_all();
263 NextReq.reset(); 398 NextReq.reset();
264 } 399 }
265 400
266 { 401 {
267 WithContext Guard(std::move(CurrentReq->Ctx)); 402 WithContext Guard(std::move(CurrentReq->Ctx));
403 // Note that we don't make use of the ContextProvider here.
404 // Preamble tasks are always scheduled by ASTWorker tasks, and we
405 // reuse the context/config that was created at that level.
406
268 // Build the preamble and let the waiters know about it. 407 // Build the preamble and let the waiters know about it.
269 build(std::move(*CurrentReq)); 408 build(std::move(*CurrentReq));
270 } 409 }
271 bool IsEmpty = false; 410 bool IsEmpty = false;
272 { 411 {
339 const bool StoreInMemory; 478 const bool StoreInMemory;
340 const bool RunSync; 479 const bool RunSync;
341 480
342 SynchronizedTUStatus &Status; 481 SynchronizedTUStatus &Status;
343 ASTWorker &ASTPeer; 482 ASTWorker &ASTPeer;
483 TUScheduler::HeaderIncluderCache &HeaderIncluders;
344 }; 484 };
345 485
346 class ASTWorkerHandle; 486 class ASTWorkerHandle;
347 487
348 /// Owns one instance of the AST, schedules updates and reads of it. 488 /// Owns one instance of the AST, schedules updates and reads of it.
356 /// signals the worker to exit its run loop and gives up shared ownership of the 496 /// signals the worker to exit its run loop and gives up shared ownership of the
357 /// worker. 497 /// worker.
358 class ASTWorker { 498 class ASTWorker {
359 friend class ASTWorkerHandle; 499 friend class ASTWorkerHandle;
360 ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB, 500 ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB,
361 TUScheduler::ASTCache &LRUCache, Semaphore &Barrier, bool RunSync, 501 TUScheduler::ASTCache &LRUCache,
362 DebouncePolicy UpdateDebounce, bool StorePreamblesInMemory, 502 TUScheduler::HeaderIncluderCache &HeaderIncluders,
503 Semaphore &Barrier, bool RunSync, const TUScheduler::Options &Opts,
363 ParsingCallbacks &Callbacks); 504 ParsingCallbacks &Callbacks);
364 505
365 public: 506 public:
366 /// Create a new ASTWorker and return a handle to it. 507 /// Create a new ASTWorker and return a handle to it.
367 /// The processing thread is spawned using \p Tasks. However, when \p Tasks 508 /// The processing thread is spawned using \p Tasks. However, when \p Tasks
368 /// is null, all requests will be processed on the calling thread 509 /// is null, all requests will be processed on the calling thread
369 /// synchronously instead. \p Barrier is acquired when processing each 510 /// synchronously instead. \p Barrier is acquired when processing each
370 /// request, it is used to limit the number of actively running threads. 511 /// request, it is used to limit the number of actively running threads.
371 static ASTWorkerHandle 512 static ASTWorkerHandle
372 create(PathRef FileName, const GlobalCompilationDatabase &CDB, 513 create(PathRef FileName, const GlobalCompilationDatabase &CDB,
373 TUScheduler::ASTCache &IdleASTs, AsyncTaskRunner *Tasks, 514 TUScheduler::ASTCache &IdleASTs,
374 Semaphore &Barrier, DebouncePolicy UpdateDebounce, 515 TUScheduler::HeaderIncluderCache &HeaderIncluders,
375 bool StorePreamblesInMemory, ParsingCallbacks &Callbacks); 516 AsyncTaskRunner *Tasks, Semaphore &Barrier,
517 const TUScheduler::Options &Opts, ParsingCallbacks &Callbacks);
376 ~ASTWorker(); 518 ~ASTWorker();
377 519
378 void update(ParseInputs Inputs, WantDiagnostics); 520 void update(ParseInputs Inputs, WantDiagnostics, bool ContentChanged);
379 void 521 void
380 runWithAST(llvm::StringRef Name, 522 runWithAST(llvm::StringRef Name,
381 llvm::unique_function<void(llvm::Expected<InputsAndAST>)> Action, 523 llvm::unique_function<void(llvm::Expected<InputsAndAST>)> Action,
382 TUScheduler::ASTActionInvalidation); 524 TUScheduler::ASTActionInvalidation);
383 bool blockUntilIdle(Deadline Timeout) const; 525 bool blockUntilIdle(Deadline Timeout) const;
384 526
385 std::shared_ptr<const PreambleData> getPossiblyStalePreamble() const; 527 std::shared_ptr<const PreambleData> getPossiblyStalePreamble(
528 std::shared_ptr<const ASTSignals> *ASTSignals = nullptr) const;
386 529
387 /// Used to inform ASTWorker about a new preamble build by PreambleThread. 530 /// Used to inform ASTWorker about a new preamble build by PreambleThread.
388 /// Diagnostics are only published through this callback. This ensures they 531 /// Diagnostics are only published through this callback. This ensures they
389 /// are always for newer versions of the file, as the callback gets called in 532 /// are always for newer versions of the file, as the callback gets called in
390 /// the same order as update requests. 533 /// the same order as update requests.
407 550
408 TUScheduler::FileStats stats() const; 551 TUScheduler::FileStats stats() const;
409 bool isASTCached() const; 552 bool isASTCached() const;
410 553
411 private: 554 private:
555 // Details of an update request that are relevant to scheduling.
556 struct UpdateType {
557 // Do we want diagnostics from this version?
558 // If Yes, we must always build this version.
559 // If No, we only need to build this version if it's read.
560 // If Auto, we build if it's read or if the debounce expires.
561 WantDiagnostics Diagnostics;
562 // Did the main-file content of the document change?
563 // If so, we're allowed to cancel certain invalidated preceding reads.
564 bool ContentChanged;
565 };
566
412 /// Publishes diagnostics for \p Inputs. It will build an AST or reuse the 567 /// Publishes diagnostics for \p Inputs. It will build an AST or reuse the
413 /// cached one if applicable. Assumes LatestPreamble is compatible for \p 568 /// cached one if applicable. Assumes LatestPreamble is compatible for \p
414 /// Inputs. 569 /// Inputs.
415 void generateDiagnostics(std::unique_ptr<CompilerInvocation> Invocation, 570 void generateDiagnostics(std::unique_ptr<CompilerInvocation> Invocation,
416 ParseInputs Inputs, std::vector<Diag> CIDiags); 571 ParseInputs Inputs, std::vector<Diag> CIDiags);
572
573 void updateASTSignals(ParsedAST &AST);
417 574
418 // Must be called exactly once on processing thread. Will return after 575 // Must be called exactly once on processing thread. Will return after
419 // stop() is called on a separate thread and all pending requests are 576 // stop() is called on a separate thread and all pending requests are
420 // processed. 577 // processed.
421 void run(); 578 void run();
422 /// Signal that run() should finish processing pending requests and exit. 579 /// Signal that run() should finish processing pending requests and exit.
423 void stop(); 580 void stop();
581
424 /// Adds a new task to the end of the request queue. 582 /// Adds a new task to the end of the request queue.
425 void startTask(llvm::StringRef Name, llvm::unique_function<void()> Task, 583 void startTask(llvm::StringRef Name, llvm::unique_function<void()> Task,
426 llvm::Optional<WantDiagnostics> UpdateType, 584 llvm::Optional<UpdateType> Update,
427 TUScheduler::ASTActionInvalidation); 585 TUScheduler::ASTActionInvalidation);
428 586
429 /// Determines the next action to perform. 587 /// Determines the next action to perform.
430 /// All actions that should never run are discarded. 588 /// All actions that should never run are discarded.
431 /// Returns a deadline for the next action. If it's expired, run now. 589 /// Returns a deadline for the next action. If it's expired, run now.
437 struct Request { 595 struct Request {
438 llvm::unique_function<void()> Action; 596 llvm::unique_function<void()> Action;
439 std::string Name; 597 std::string Name;
440 steady_clock::time_point AddTime; 598 steady_clock::time_point AddTime;
441 Context Ctx; 599 Context Ctx;
442 llvm::Optional<WantDiagnostics> UpdateType; 600 llvm::Optional<Context> QueueCtx;
601 llvm::Optional<UpdateType> Update;
443 TUScheduler::ASTActionInvalidation InvalidationPolicy; 602 TUScheduler::ASTActionInvalidation InvalidationPolicy;
444 Canceler Invalidate; 603 Canceler Invalidate;
445 }; 604 };
446 605
447 /// Handles retention of ASTs. 606 /// Handles retention of ASTs.
448 TUScheduler::ASTCache &IdleASTs; 607 TUScheduler::ASTCache &IdleASTs;
608 TUScheduler::HeaderIncluderCache &HeaderIncluders;
449 const bool RunSync; 609 const bool RunSync;
450 /// Time to wait after an update to see whether another update obsoletes it. 610 /// Time to wait after an update to see whether another update obsoletes it.
451 const DebouncePolicy UpdateDebounce; 611 const DebouncePolicy UpdateDebounce;
452 /// File that ASTWorker is responsible for. 612 /// File that ASTWorker is responsible for.
453 const Path FileName; 613 const Path FileName;
614 /// Callback to create processing contexts for tasks.
615 const std::function<Context(llvm::StringRef)> ContextProvider;
454 const GlobalCompilationDatabase &CDB; 616 const GlobalCompilationDatabase &CDB;
455 /// Callback invoked when preamble or main file AST is built. 617 /// Callback invoked when preamble or main file AST is built.
456 ParsingCallbacks &Callbacks; 618 ParsingCallbacks &Callbacks;
457 /// Latest build preamble for current TU.
458 std::shared_ptr<const PreambleData> LatestPreamble;
459 Notification BuiltFirstPreamble;
460 619
461 Semaphore &Barrier; 620 Semaphore &Barrier;
462 /// Whether the 'onMainAST' callback ran for the current FileInputs. 621 /// Whether the 'onMainAST' callback ran for the current FileInputs.
463 bool RanASTCallback = false; 622 bool RanASTCallback = false;
464 /// Guards members used by both TUScheduler and the worker thread. 623 /// Guards members used by both TUScheduler and the worker thread.
466 /// File inputs, currently being used by the worker. 625 /// File inputs, currently being used by the worker.
467 /// Writes and reads from unknown threads are locked. Reads from the worker 626 /// Writes and reads from unknown threads are locked. Reads from the worker
468 /// thread are not locked, as it's the only writer. 627 /// thread are not locked, as it's the only writer.
469 ParseInputs FileInputs; /* GUARDED_BY(Mutex) */ 628 ParseInputs FileInputs; /* GUARDED_BY(Mutex) */
470 /// Times of recent AST rebuilds, used for UpdateDebounce computation. 629 /// Times of recent AST rebuilds, used for UpdateDebounce computation.
471 llvm::SmallVector<DebouncePolicy::clock::duration, 8> 630 llvm::SmallVector<DebouncePolicy::clock::duration>
472 RebuildTimes; /* GUARDED_BY(Mutex) */ 631 RebuildTimes; /* GUARDED_BY(Mutex) */
473 /// Set to true to signal run() to finish processing. 632 /// Set to true to signal run() to finish processing.
474 bool Done; /* GUARDED_BY(Mutex) */ 633 bool Done; /* GUARDED_BY(Mutex) */
475 std::deque<Request> Requests; /* GUARDED_BY(Mutex) */ 634 std::deque<Request> Requests; /* GUARDED_BY(Mutex) */
476 std::queue<Request> PreambleRequests; /* GUARDED_BY(Mutex) */
477 llvm::Optional<Request> CurrentRequest; /* GUARDED_BY(Mutex) */ 635 llvm::Optional<Request> CurrentRequest; /* GUARDED_BY(Mutex) */
636 /// Signalled whenever a new request has been scheduled or processing of a
637 /// request has completed.
478 mutable std::condition_variable RequestsCV; 638 mutable std::condition_variable RequestsCV;
639 std::shared_ptr<const ASTSignals> LatestASTSignals; /* GUARDED_BY(Mutex) */
640 /// Latest build preamble for current TU.
641 /// None means no builds yet, null means there was an error while building.
642 /// Only written by ASTWorker's thread.
643 llvm::Optional<std::shared_ptr<const PreambleData>> LatestPreamble;
644 std::deque<Request> PreambleRequests; /* GUARDED_BY(Mutex) */
645 /// Signaled whenever LatestPreamble changes state or there's a new
646 /// PreambleRequest.
647 mutable std::condition_variable PreambleCV;
479 /// Guards the callback that publishes results of AST-related computations 648 /// Guards the callback that publishes results of AST-related computations
480 /// (diagnostics, highlightings) and file statuses. 649 /// (diagnostics) and file statuses.
481 std::mutex PublishMu; 650 std::mutex PublishMu;
482 // Used to prevent remove document + add document races that lead to 651 // Used to prevent remove document + add document races that lead to
483 // out-of-order callbacks for publishing results of onMainAST callback. 652 // out-of-order callbacks for publishing results of onMainAST callback.
484 // 653 //
485 // The lifetime of the old/new ASTWorkers will overlap, but their handles 654 // The lifetime of the old/new ASTWorkers will overlap, but their handles
535 std::shared_ptr<ASTWorker> Worker; 704 std::shared_ptr<ASTWorker> Worker;
536 }; 705 };
537 706
538 ASTWorkerHandle 707 ASTWorkerHandle
539 ASTWorker::create(PathRef FileName, const GlobalCompilationDatabase &CDB, 708 ASTWorker::create(PathRef FileName, const GlobalCompilationDatabase &CDB,
540 TUScheduler::ASTCache &IdleASTs, AsyncTaskRunner *Tasks, 709 TUScheduler::ASTCache &IdleASTs,
541 Semaphore &Barrier, DebouncePolicy UpdateDebounce, 710 TUScheduler::HeaderIncluderCache &HeaderIncluders,
542 bool StorePreamblesInMemory, ParsingCallbacks &Callbacks) { 711 AsyncTaskRunner *Tasks, Semaphore &Barrier,
712 const TUScheduler::Options &Opts,
713 ParsingCallbacks &Callbacks) {
543 std::shared_ptr<ASTWorker> Worker( 714 std::shared_ptr<ASTWorker> Worker(
544 new ASTWorker(FileName, CDB, IdleASTs, Barrier, /*RunSync=*/!Tasks, 715 new ASTWorker(FileName, CDB, IdleASTs, HeaderIncluders, Barrier,
545 UpdateDebounce, StorePreamblesInMemory, Callbacks)); 716 /*RunSync=*/!Tasks, Opts, Callbacks));
546 if (Tasks) { 717 if (Tasks) {
547 Tasks->runAsync("ASTWorker:" + llvm::sys::path::filename(FileName), 718 Tasks->runAsync("ASTWorker:" + llvm::sys::path::filename(FileName),
548 [Worker]() { Worker->run(); }); 719 [Worker]() { Worker->run(); });
549 Tasks->runAsync("PreambleWorker:" + llvm::sys::path::filename(FileName), 720 Tasks->runAsync("PreambleWorker:" + llvm::sys::path::filename(FileName),
550 [Worker]() { Worker->PreamblePeer.run(); }); 721 [Worker]() { Worker->PreamblePeer.run(); });
552 723
553 return ASTWorkerHandle(std::move(Worker)); 724 return ASTWorkerHandle(std::move(Worker));
554 } 725 }
555 726
556 ASTWorker::ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB, 727 ASTWorker::ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB,
557 TUScheduler::ASTCache &LRUCache, Semaphore &Barrier, 728 TUScheduler::ASTCache &LRUCache,
558 bool RunSync, DebouncePolicy UpdateDebounce, 729 TUScheduler::HeaderIncluderCache &HeaderIncluders,
559 bool StorePreamblesInMemory, ParsingCallbacks &Callbacks) 730 Semaphore &Barrier, bool RunSync,
560 : IdleASTs(LRUCache), RunSync(RunSync), UpdateDebounce(UpdateDebounce), 731 const TUScheduler::Options &Opts,
561 FileName(FileName), CDB(CDB), Callbacks(Callbacks), Barrier(Barrier), 732 ParsingCallbacks &Callbacks)
562 Done(false), Status(FileName, Callbacks), 733 : IdleASTs(LRUCache), HeaderIncluders(HeaderIncluders), RunSync(RunSync),
563 PreamblePeer(FileName, Callbacks, StorePreamblesInMemory, 734 UpdateDebounce(Opts.UpdateDebounce), FileName(FileName),
564 // FIXME: Run PreamblePeer asynchronously once ast patching 735 ContextProvider(Opts.ContextProvider), CDB(CDB), Callbacks(Callbacks),
565 // is available. 736 Barrier(Barrier), Done(false), Status(FileName, Callbacks),
566 /*RunSync=*/true, Status, *this) { 737 PreamblePeer(FileName, Callbacks, Opts.StorePreamblesInMemory, RunSync,
738 Status, HeaderIncluders, *this) {
567 // Set a fallback command because compile command can be accessed before 739 // Set a fallback command because compile command can be accessed before
568 // `Inputs` is initialized. Other fields are only used after initialization 740 // `Inputs` is initialized. Other fields are only used after initialization
569 // from client inputs. 741 // from client inputs.
570 FileInputs.CompileCommand = CDB.getFallbackCommand(FileName); 742 FileInputs.CompileCommand = CDB.getFallbackCommand(FileName);
571 } 743 }
579 assert(Requests.empty() && !CurrentRequest && 751 assert(Requests.empty() && !CurrentRequest &&
580 "unprocessed requests when destroying ASTWorker"); 752 "unprocessed requests when destroying ASTWorker");
581 #endif 753 #endif
582 } 754 }
583 755
584 void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags) { 756 void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags,
757 bool ContentChanged) {
585 std::string TaskName = llvm::formatv("Update ({0})", Inputs.Version); 758 std::string TaskName = llvm::formatv("Update ({0})", Inputs.Version);
586 auto Task = [=]() mutable { 759 auto Task = [=]() mutable {
587 // Get the actual command as `Inputs` does not have a command. 760 // Get the actual command as `Inputs` does not have a command.
588 // FIXME: some build systems like Bazel will take time to preparing 761 // FIXME: some build systems like Bazel will take time to preparing
589 // environment to build the file, it would be nice if we could emit a 762 // environment to build the file, it would be nice if we could emit a
590 // "PreparingBuild" status to inform users, it is non-trivial given the 763 // "PreparingBuild" status to inform users, it is non-trivial given the
591 // current implementation. 764 // current implementation.
592 if (auto Cmd = CDB.getCompileCommand(FileName)) 765 auto Cmd = CDB.getCompileCommand(FileName);
593 Inputs.CompileCommand = *Cmd; 766 // If we don't have a reliable command for this file, it may be a header.
767 // Try to find a file that includes it, to borrow its command.
768 if (!Cmd || !isReliable(*Cmd)) {
769 std::string ProxyFile = HeaderIncluders.get(FileName);
770 if (!ProxyFile.empty()) {
771 auto ProxyCmd = CDB.getCompileCommand(ProxyFile);
772 if (!ProxyCmd || !isReliable(*ProxyCmd)) {
773 // This command is supposed to be reliable! It's probably gone.
774 HeaderIncluders.remove(ProxyFile);
775 } else {
776 // We have a reliable command for an including file, use it.
777 Cmd = tooling::transferCompileCommand(std::move(*ProxyCmd), FileName);
778 }
779 }
780 }
781 if (Cmd)
782 Inputs.CompileCommand = std::move(*Cmd);
594 else 783 else
595 // FIXME: consider using old command if it's not a fallback one.
596 Inputs.CompileCommand = CDB.getFallbackCommand(FileName); 784 Inputs.CompileCommand = CDB.getFallbackCommand(FileName);
597 785
598 bool InputsAreTheSame = 786 bool InputsAreTheSame =
599 std::tie(FileInputs.CompileCommand, FileInputs.Contents) == 787 std::tie(FileInputs.CompileCommand, FileInputs.Contents) ==
600 std::tie(Inputs.CompileCommand, Inputs.Contents); 788 std::tie(Inputs.CompileCommand, Inputs.Contents);
611 } 799 }
612 800
613 log("ASTWorker building file {0} version {1} with command {2}\n[{3}]\n{4}", 801 log("ASTWorker building file {0} version {1} with command {2}\n[{3}]\n{4}",
614 FileName, Inputs.Version, Inputs.CompileCommand.Heuristic, 802 FileName, Inputs.Version, Inputs.CompileCommand.Heuristic,
615 Inputs.CompileCommand.Directory, 803 Inputs.CompileCommand.Directory,
616 llvm::join(Inputs.CompileCommand.CommandLine, " ")); 804 printArgv(Inputs.CompileCommand.CommandLine));
617 805
618 StoreDiags CompilerInvocationDiagConsumer; 806 StoreDiags CompilerInvocationDiagConsumer;
619 std::vector<std::string> CC1Args; 807 std::vector<std::string> CC1Args;
620 std::unique_ptr<CompilerInvocation> Invocation = buildCompilerInvocation( 808 std::unique_ptr<CompilerInvocation> Invocation = buildCompilerInvocation(
621 Inputs, CompilerInvocationDiagConsumer, &CC1Args); 809 Inputs, CompilerInvocationDiagConsumer, &CC1Args);
622 // Log cc1 args even (especially!) if creating invocation failed. 810 // Log cc1 args even (especially!) if creating invocation failed.
623 if (!CC1Args.empty()) 811 if (!CC1Args.empty())
624 vlog("Driver produced command: cc1 {0}", llvm::join(CC1Args, " ")); 812 vlog("Driver produced command: cc1 {0}", printArgv(CC1Args));
625 std::vector<Diag> CompilerInvocationDiags = 813 std::vector<Diag> CompilerInvocationDiags =
626 CompilerInvocationDiagConsumer.take(); 814 CompilerInvocationDiagConsumer.take();
627 if (!Invocation) { 815 if (!Invocation) {
628 elog("Could not build CompilerInvocation for file {0}", FileName); 816 elog("Could not build CompilerInvocation for file {0}", FileName);
629 // Remove the old AST if it's still in cache. 817 // Remove the old AST if it's still in cache.
638 // are not race conditions. 826 // are not race conditions.
639 std::lock_guard<std::mutex> Lock(PublishMu); 827 std::lock_guard<std::mutex> Lock(PublishMu);
640 if (CanPublishResults) 828 if (CanPublishResults)
641 Publish(); 829 Publish();
642 }); 830 });
831 // Note that this might throw away a stale preamble that might still be
832 // useful, but this is how we communicate a build error.
833 LatestPreamble.emplace();
643 // Make sure anyone waiting for the preamble gets notified it could not be 834 // Make sure anyone waiting for the preamble gets notified it could not be
644 // built. 835 // built.
645 BuiltFirstPreamble.notify(); 836 PreambleCV.notify_all();
646 return; 837 return;
647 } 838 }
648 839
649 PreamblePeer.update(std::move(Invocation), std::move(Inputs), 840 PreamblePeer.update(std::move(Invocation), std::move(Inputs),
650 std::move(CompilerInvocationDiags), WantDiags); 841 std::move(CompilerInvocationDiags), WantDiags);
842 std::unique_lock<std::mutex> Lock(Mutex);
843 PreambleCV.wait(Lock, [this] {
844 // Block until we reiceve a preamble request, unless a preamble already
845 // exists, as patching an empty preamble would imply rebuilding it from
846 // scratch.
847 // We block here instead of the consumer to prevent any deadlocks. Since
848 // LatestPreamble is only populated by ASTWorker thread.
849 return LatestPreamble || !PreambleRequests.empty() || Done;
850 });
651 return; 851 return;
652 }; 852 };
653 startTask(TaskName, std::move(Task), WantDiags, TUScheduler::NoInvalidation); 853 startTask(TaskName, std::move(Task), UpdateType{WantDiags, ContentChanged},
854 TUScheduler::NoInvalidation);
654 } 855 }
655 856
656 void ASTWorker::runWithAST( 857 void ASTWorker::runWithAST(
657 llvm::StringRef Name, 858 llvm::StringRef Name,
658 llvm::unique_function<void(llvm::Expected<InputsAndAST>)> Action, 859 llvm::unique_function<void(llvm::Expected<InputsAndAST>)> Action,
687 // Make sure we put the AST back into the LRU cache. 888 // Make sure we put the AST back into the LRU cache.
688 auto _ = llvm::make_scope_exit( 889 auto _ = llvm::make_scope_exit(
689 [&AST, this]() { IdleASTs.put(this, std::move(*AST)); }); 890 [&AST, this]() { IdleASTs.put(this, std::move(*AST)); });
690 // Run the user-provided action. 891 // Run the user-provided action.
691 if (!*AST) 892 if (!*AST)
692 return Action(llvm::make_error<llvm::StringError>( 893 return Action(error(llvm::errc::invalid_argument, "invalid AST"));
693 "invalid AST", llvm::errc::invalid_argument));
694 vlog("ASTWorker running {0} on version {2} of {1}", Name, FileName, 894 vlog("ASTWorker running {0} on version {2} of {1}", Name, FileName,
695 FileInputs.Version); 895 FileInputs.Version);
696 Action(InputsAndAST{FileInputs, **AST}); 896 Action(InputsAndAST{FileInputs, **AST});
697 }; 897 };
698 startTask(Name, std::move(Task), /*UpdateType=*/None, Invalidation); 898 startTask(Name, std::move(Task), /*Update=*/None, Invalidation);
699 } 899 }
700 900
701 void PreambleThread::build(Request Req) { 901 void PreambleThread::build(Request Req) {
702 assert(Req.CI && "Got preamble request with null compiler invocation"); 902 assert(Req.CI && "Got preamble request with null compiler invocation");
703 const ParseInputs &Inputs = Req.Inputs; 903 const ParseInputs &Inputs = Req.Inputs;
707 }); 907 });
708 auto _ = llvm::make_scope_exit([this, &Req] { 908 auto _ = llvm::make_scope_exit([this, &Req] {
709 ASTPeer.updatePreamble(std::move(Req.CI), std::move(Req.Inputs), 909 ASTPeer.updatePreamble(std::move(Req.CI), std::move(Req.Inputs),
710 LatestBuild, std::move(Req.CIDiags), 910 LatestBuild, std::move(Req.CIDiags),
711 std::move(Req.WantDiags)); 911 std::move(Req.WantDiags));
912 Callbacks.onPreamblePublished(FileName);
712 }); 913 });
713 914
714 if (!LatestBuild || Inputs.ForceRebuild) { 915 if (!LatestBuild || Inputs.ForceRebuild) {
715 vlog("Building first preamble for {0} version {1}", FileName, 916 vlog("Building first preamble for {0} version {1}", FileName,
716 Inputs.Version); 917 Inputs.Version);
730 std::shared_ptr<clang::Preprocessor> PP, 931 std::shared_ptr<clang::Preprocessor> PP,
731 const CanonicalIncludes &CanonIncludes) { 932 const CanonicalIncludes &CanonIncludes) {
732 Callbacks.onPreambleAST(FileName, Version, Ctx, std::move(PP), 933 Callbacks.onPreambleAST(FileName, Version, Ctx, std::move(PP),
733 CanonIncludes); 934 CanonIncludes);
734 }); 935 });
936 if (LatestBuild && isReliable(LatestBuild->CompileCommand))
937 HeaderIncluders.update(FileName, LatestBuild->Includes.allHeaders());
735 } 938 }
736 939
737 void ASTWorker::updatePreamble(std::unique_ptr<CompilerInvocation> CI, 940 void ASTWorker::updatePreamble(std::unique_ptr<CompilerInvocation> CI,
738 ParseInputs PI, 941 ParseInputs PI,
739 std::shared_ptr<const PreambleData> Preamble, 942 std::shared_ptr<const PreambleData> Preamble,
745 PI = std::move(PI), CIDiags = std::move(CIDiags), 948 PI = std::move(PI), CIDiags = std::move(CIDiags),
746 WantDiags = std::move(WantDiags)]() mutable { 949 WantDiags = std::move(WantDiags)]() mutable {
747 // Update the preamble inside ASTWorker queue to ensure atomicity. As a task 950 // Update the preamble inside ASTWorker queue to ensure atomicity. As a task
748 // running inside ASTWorker assumes internals won't change until it 951 // running inside ASTWorker assumes internals won't change until it
749 // finishes. 952 // finishes.
750 if (Preamble != LatestPreamble) { 953 if (!LatestPreamble || Preamble != *LatestPreamble) {
751 ++PreambleBuildCount; 954 ++PreambleBuildCount;
752 // Cached AST is no longer valid. 955 // Cached AST is no longer valid.
753 IdleASTs.take(this); 956 IdleASTs.take(this);
754 RanASTCallback = false; 957 RanASTCallback = false;
755 std::lock_guard<std::mutex> Lock(Mutex); 958 std::lock_guard<std::mutex> Lock(Mutex);
756 // LatestPreamble might be the last reference to old preamble, do not 959 // LatestPreamble might be the last reference to old preamble, do not
757 // trigger destructor while holding the lock. 960 // trigger destructor while holding the lock.
758 std::swap(LatestPreamble, Preamble); 961 if (LatestPreamble)
759 } 962 std::swap(*LatestPreamble, Preamble);
963 else
964 LatestPreamble = std::move(Preamble);
965 }
966 // Notify anyone waiting for a preamble.
967 PreambleCV.notify_all();
760 // Give up our ownership to old preamble before starting expensive AST 968 // Give up our ownership to old preamble before starting expensive AST
761 // build. 969 // build.
762 Preamble.reset(); 970 Preamble.reset();
763 BuiltFirstPreamble.notify();
764 // We only need to build the AST if diagnostics were requested. 971 // We only need to build the AST if diagnostics were requested.
765 if (WantDiags == WantDiagnostics::No) 972 if (WantDiags == WantDiagnostics::No)
766 return; 973 return;
767 // Report diagnostics with the new preamble to ensure progress. Otherwise 974 // Report diagnostics with the new preamble to ensure progress. Otherwise
768 // diagnostics might get stale indefinitely if user keeps invalidating the 975 // diagnostics might get stale indefinitely if user keeps invalidating the
773 Task(); 980 Task();
774 return; 981 return;
775 } 982 }
776 { 983 {
777 std::lock_guard<std::mutex> Lock(Mutex); 984 std::lock_guard<std::mutex> Lock(Mutex);
778 PreambleRequests.push({std::move(Task), std::move(TaskName), 985 PreambleRequests.push_back({std::move(Task), std::move(TaskName),
779 steady_clock::now(), Context::current().clone(), 986 steady_clock::now(), Context::current().clone(),
780 llvm::None, TUScheduler::NoInvalidation, nullptr}); 987 llvm::None, llvm::None,
781 } 988 TUScheduler::NoInvalidation, nullptr});
989 }
990 PreambleCV.notify_all();
782 RequestsCV.notify_all(); 991 RequestsCV.notify_all();
992 }
993
994 void ASTWorker::updateASTSignals(ParsedAST &AST) {
995 auto Signals = std::make_shared<const ASTSignals>(ASTSignals::derive(AST));
996 // Existing readers of ASTSignals will have their copy preserved until the
997 // read is completed. The last reader deletes the old ASTSignals.
998 {
999 std::lock_guard<std::mutex> Lock(Mutex);
1000 std::swap(LatestASTSignals, Signals);
1001 }
783 } 1002 }
784 1003
785 void ASTWorker::generateDiagnostics( 1004 void ASTWorker::generateDiagnostics(
786 std::unique_ptr<CompilerInvocation> Invocation, ParseInputs Inputs, 1005 std::unique_ptr<CompilerInvocation> Invocation, ParseInputs Inputs,
787 std::vector<Diag> CIDiags) { 1006 std::vector<Diag> CIDiags) {
788 // Tracks ast cache accesses for publishing diags. 1007 // Tracks ast cache accesses for publishing diags.
789 static constexpr trace::Metric ASTAccessForDiag( 1008 static constexpr trace::Metric ASTAccessForDiag(
790 "ast_access_diag", trace::Metric::Counter, "result"); 1009 "ast_access_diag", trace::Metric::Counter, "result");
791 assert(Invocation); 1010 assert(Invocation);
1011 assert(LatestPreamble);
792 // No need to rebuild the AST if we won't send the diagnostics. 1012 // No need to rebuild the AST if we won't send the diagnostics.
793 { 1013 {
794 std::lock_guard<std::mutex> Lock(PublishMu); 1014 std::lock_guard<std::mutex> Lock(PublishMu);
795 if (!CanPublishResults) 1015 if (!CanPublishResults)
796 return; 1016 return;
819 llvm::Optional<std::unique_ptr<ParsedAST>> AST = 1039 llvm::Optional<std::unique_ptr<ParsedAST>> AST =
820 IdleASTs.take(this, &ASTAccessForDiag); 1040 IdleASTs.take(this, &ASTAccessForDiag);
821 if (!AST || !InputsAreLatest) { 1041 if (!AST || !InputsAreLatest) {
822 auto RebuildStartTime = DebouncePolicy::clock::now(); 1042 auto RebuildStartTime = DebouncePolicy::clock::now();
823 llvm::Optional<ParsedAST> NewAST = ParsedAST::build( 1043 llvm::Optional<ParsedAST> NewAST = ParsedAST::build(
824 FileName, Inputs, std::move(Invocation), CIDiags, LatestPreamble); 1044 FileName, Inputs, std::move(Invocation), CIDiags, *LatestPreamble);
825 auto RebuildDuration = DebouncePolicy::clock::now() - RebuildStartTime; 1045 auto RebuildDuration = DebouncePolicy::clock::now() - RebuildStartTime;
826 ++ASTBuildCount; 1046 ++ASTBuildCount;
827 // Try to record the AST-build time, to inform future update debouncing. 1047 // Try to record the AST-build time, to inform future update debouncing.
828 // This is best-effort only: if the lock is held, don't bother. 1048 // This is best-effort only: if the lock is held, don't bother.
829 std::unique_lock<std::mutex> Lock(Mutex, std::try_to_lock); 1049 std::unique_lock<std::mutex> Lock(Mutex, std::try_to_lock);
857 Publish(); 1077 Publish();
858 }; 1078 };
859 if (*AST) { 1079 if (*AST) {
860 trace::Span Span("Running main AST callback"); 1080 trace::Span Span("Running main AST callback");
861 Callbacks.onMainAST(FileName, **AST, RunPublish); 1081 Callbacks.onMainAST(FileName, **AST, RunPublish);
1082 updateASTSignals(**AST);
862 } else { 1083 } else {
863 // Failed to build the AST, at least report diagnostics from the 1084 // Failed to build the AST, at least report diagnostics from the
864 // command line if there were any. 1085 // command line if there were any.
865 // FIXME: we might have got more errors while trying to build the 1086 // FIXME: we might have got more errors while trying to build the
866 // AST, surface them too. 1087 // AST, surface them too.
874 RanASTCallback = *AST != nullptr; 1095 RanASTCallback = *AST != nullptr;
875 IdleASTs.put(this, std::move(*AST)); 1096 IdleASTs.put(this, std::move(*AST));
876 } 1097 }
877 } 1098 }
878 1099
879 std::shared_ptr<const PreambleData> 1100 std::shared_ptr<const PreambleData> ASTWorker::getPossiblyStalePreamble(
880 ASTWorker::getPossiblyStalePreamble() const { 1101 std::shared_ptr<const ASTSignals> *ASTSignals) const {
881 std::lock_guard<std::mutex> Lock(Mutex); 1102 std::lock_guard<std::mutex> Lock(Mutex);
882 return LatestPreamble; 1103 if (ASTSignals)
883 } 1104 *ASTSignals = LatestASTSignals;
884 1105 return LatestPreamble ? *LatestPreamble : nullptr;
885 void ASTWorker::waitForFirstPreamble() const { BuiltFirstPreamble.wait(); } 1106 }
1107
1108 void ASTWorker::waitForFirstPreamble() const {
1109 std::unique_lock<std::mutex> Lock(Mutex);
1110 PreambleCV.wait(Lock, [this] { return LatestPreamble.hasValue() || Done; });
1111 }
886 1112
887 tooling::CompileCommand ASTWorker::getCurrentCompileCommand() const { 1113 tooling::CompileCommand ASTWorker::getCurrentCompileCommand() const {
888 std::unique_lock<std::mutex> Lock(Mutex); 1114 std::unique_lock<std::mutex> Lock(Mutex);
889 return FileInputs.CompileCommand; 1115 return FileInputs.CompileCommand;
890 } 1116 }
894 Result.ASTBuilds = ASTBuildCount; 1120 Result.ASTBuilds = ASTBuildCount;
895 Result.PreambleBuilds = PreambleBuildCount; 1121 Result.PreambleBuilds = PreambleBuildCount;
896 // Note that we don't report the size of ASTs currently used for processing 1122 // Note that we don't report the size of ASTs currently used for processing
897 // the in-flight requests. We used this information for debugging purposes 1123 // the in-flight requests. We used this information for debugging purposes
898 // only, so this should be fine. 1124 // only, so this should be fine.
899 Result.UsedBytes = IdleASTs.getUsedBytes(this); 1125 Result.UsedBytesAST = IdleASTs.getUsedBytes(this);
900 if (auto Preamble = getPossiblyStalePreamble()) 1126 if (auto Preamble = getPossiblyStalePreamble())
901 Result.UsedBytes += Preamble->Preamble.getSize(); 1127 Result.UsedBytesPreamble = Preamble->Preamble.getSize();
902 return Result; 1128 return Result;
903 } 1129 }
904 1130
905 bool ASTWorker::isASTCached() const { return IdleASTs.getUsedBytes(this) != 0; } 1131 bool ASTWorker::isASTCached() const { return IdleASTs.getUsedBytes(this) != 0; }
906 1132
912 { 1138 {
913 std::lock_guard<std::mutex> Lock(Mutex); 1139 std::lock_guard<std::mutex> Lock(Mutex);
914 assert(!Done && "stop() called twice"); 1140 assert(!Done && "stop() called twice");
915 Done = true; 1141 Done = true;
916 } 1142 }
1143 PreamblePeer.stop();
917 // We are no longer going to build any preambles, let the waiters know that. 1144 // We are no longer going to build any preambles, let the waiters know that.
918 BuiltFirstPreamble.notify(); 1145 PreambleCV.notify_all();
919 PreamblePeer.stop();
920 Status.stop(); 1146 Status.stop();
921 RequestsCV.notify_all(); 1147 RequestsCV.notify_all();
922 } 1148 }
923 1149
924 void ASTWorker::startTask(llvm::StringRef Name, 1150 void ASTWorker::startTask(llvm::StringRef Name,
925 llvm::unique_function<void()> Task, 1151 llvm::unique_function<void()> Task,
926 llvm::Optional<WantDiagnostics> UpdateType, 1152 llvm::Optional<UpdateType> Update,
927 TUScheduler::ASTActionInvalidation Invalidation) { 1153 TUScheduler::ASTActionInvalidation Invalidation) {
928 if (RunSync) { 1154 if (RunSync) {
929 assert(!Done && "running a task after stop()"); 1155 assert(!Done && "running a task after stop()");
930 trace::Span Tracer(Name + ":" + llvm::sys::path::filename(FileName)); 1156 trace::Span Tracer(Name + ":" + llvm::sys::path::filename(FileName));
1157 WithContext WithProvidedContext(ContextProvider(FileName));
931 Task(); 1158 Task();
932 return; 1159 return;
933 } 1160 }
934 1161
935 { 1162 {
936 std::lock_guard<std::mutex> Lock(Mutex); 1163 std::lock_guard<std::mutex> Lock(Mutex);
937 assert(!Done && "running a task after stop()"); 1164 assert(!Done && "running a task after stop()");
938 // Cancel any requests invalidated by this request. 1165 // Cancel any requests invalidated by this request.
939 if (UpdateType) { 1166 if (Update && Update->ContentChanged) {
940 for (auto &R : llvm::reverse(Requests)) { 1167 for (auto &R : llvm::reverse(Requests)) {
941 if (R.InvalidationPolicy == TUScheduler::InvalidateOnUpdate) 1168 if (R.InvalidationPolicy == TUScheduler::InvalidateOnUpdate)
942 R.Invalidate(); 1169 R.Invalidate();
943 if (R.UpdateType) 1170 if (R.Update && R.Update->ContentChanged)
944 break; // Older requests were already invalidated by the older update. 1171 break; // Older requests were already invalidated by the older update.
945 } 1172 }
946 } 1173 }
947 1174
948 // Allow this request to be cancelled if invalidated. 1175 // Allow this request to be cancelled if invalidated.
951 if (Invalidation) { 1178 if (Invalidation) {
952 WithContext WC(std::move(Ctx)); 1179 WithContext WC(std::move(Ctx));
953 std::tie(Ctx, Invalidate) = cancelableTask( 1180 std::tie(Ctx, Invalidate) = cancelableTask(
954 /*Reason=*/static_cast<int>(ErrorCode::ContentModified)); 1181 /*Reason=*/static_cast<int>(ErrorCode::ContentModified));
955 } 1182 }
1183 // Trace the time the request spends in the queue, and the requests that
1184 // it's going to wait for.
1185 llvm::Optional<Context> QueueCtx;
1186 if (trace::enabled()) {
1187 // Tracers that follow threads and need strict nesting will see a tiny
1188 // instantaneous event "we're enqueueing", and sometime later it runs.
1189 WithContext WC(Ctx.clone());
1190 trace::Span Tracer("Queued:" + Name);
1191 if (Tracer.Args) {
1192 if (CurrentRequest)
1193 SPAN_ATTACH(Tracer, "CurrentRequest", CurrentRequest->Name);
1194 llvm::json::Array PreambleRequestsNames;
1195 for (const auto &Req : PreambleRequests)
1196 PreambleRequestsNames.push_back(Req.Name);
1197 SPAN_ATTACH(Tracer, "PreambleRequestsNames",
1198 std::move(PreambleRequestsNames));
1199 llvm::json::Array RequestsNames;
1200 for (const auto &Req : Requests)
1201 RequestsNames.push_back(Req.Name);
1202 SPAN_ATTACH(Tracer, "RequestsNames", std::move(RequestsNames));
1203 }
1204 // For tracers that follow contexts, keep the trace span's context alive
1205 // until we dequeue the request, so they see the full duration.
1206 QueueCtx = Context::current().clone();
1207 }
956 Requests.push_back({std::move(Task), std::string(Name), steady_clock::now(), 1208 Requests.push_back({std::move(Task), std::string(Name), steady_clock::now(),
957 std::move(Ctx), UpdateType, Invalidation, 1209 std::move(Ctx), std::move(QueueCtx), Update,
958 std::move(Invalidate)}); 1210 Invalidation, std::move(Invalidate)});
959 } 1211 }
960 RequestsCV.notify_all(); 1212 RequestsCV.notify_all();
961 } 1213 }
962 1214
963 void ASTWorker::run() { 1215 void ASTWorker::run() {
999 } 1251 }
1000 // Any request in ReceivedPreambles is at least as old as the 1252 // Any request in ReceivedPreambles is at least as old as the
1001 // Requests.front(), so prefer them first to preserve LSP order. 1253 // Requests.front(), so prefer them first to preserve LSP order.
1002 if (!PreambleRequests.empty()) { 1254 if (!PreambleRequests.empty()) {
1003 CurrentRequest = std::move(PreambleRequests.front()); 1255 CurrentRequest = std::move(PreambleRequests.front());
1004 PreambleRequests.pop(); 1256 PreambleRequests.pop_front();
1005 } else { 1257 } else {
1006 CurrentRequest = std::move(Requests.front()); 1258 CurrentRequest = std::move(Requests.front());
1007 Requests.pop_front(); 1259 Requests.pop_front();
1008 } 1260 }
1009 } // unlock Mutex 1261 } // unlock Mutex
1262
1263 // Inform tracing that the request was dequeued.
1264 CurrentRequest->QueueCtx.reset();
1010 1265
1011 // It is safe to perform reads to CurrentRequest without holding the lock as 1266 // It is safe to perform reads to CurrentRequest without holding the lock as
1012 // only writer is also this thread. 1267 // only writer is also this thread.
1013 { 1268 {
1014 std::unique_lock<Semaphore> Lock(Barrier, std::try_to_lock); 1269 std::unique_lock<Semaphore> Lock(Barrier, std::try_to_lock);
1023 trace::Span Tracer(CurrentRequest->Name); 1278 trace::Span Tracer(CurrentRequest->Name);
1024 Status.update([&](TUStatus &Status) { 1279 Status.update([&](TUStatus &Status) {
1025 Status.ASTActivity.K = ASTAction::RunningAction; 1280 Status.ASTActivity.K = ASTAction::RunningAction;
1026 Status.ASTActivity.Name = CurrentRequest->Name; 1281 Status.ASTActivity.Name = CurrentRequest->Name;
1027 }); 1282 });
1283 WithContext WithProvidedContext(ContextProvider(FileName));
1028 CurrentRequest->Action(); 1284 CurrentRequest->Action();
1029 } 1285 }
1030 1286
1031 bool IsEmpty = false; 1287 bool IsEmpty = false;
1032 { 1288 {
1052 return Deadline::infinity(); // Wait for new requests. 1308 return Deadline::infinity(); // Wait for new requests.
1053 // Handle cancelled requests first so the rest of the scheduler doesn't. 1309 // Handle cancelled requests first so the rest of the scheduler doesn't.
1054 for (auto I = Requests.begin(), E = Requests.end(); I != E; ++I) { 1310 for (auto I = Requests.begin(), E = Requests.end(); I != E; ++I) {
1055 if (!isCancelled(I->Ctx)) { 1311 if (!isCancelled(I->Ctx)) {
1056 // Cancellations after the first read don't affect current scheduling. 1312 // Cancellations after the first read don't affect current scheduling.
1057 if (I->UpdateType == None) 1313 if (I->Update == None)
1058 break; 1314 break;
1059 continue; 1315 continue;
1060 } 1316 }
1061 // Cancelled reads are moved to the front of the queue and run immediately. 1317 // Cancelled reads are moved to the front of the queue and run immediately.
1062 if (I->UpdateType == None) { 1318 if (I->Update == None) {
1063 Request R = std::move(*I); 1319 Request R = std::move(*I);
1064 Requests.erase(I); 1320 Requests.erase(I);
1065 Requests.push_front(std::move(R)); 1321 Requests.push_front(std::move(R));
1066 return Deadline::zero(); 1322 return Deadline::zero();
1067 } 1323 }
1068 // Cancelled updates are downgraded to auto-diagnostics, and may be elided. 1324 // Cancelled updates are downgraded to auto-diagnostics, and may be elided.
1069 if (I->UpdateType == WantDiagnostics::Yes) 1325 if (I->Update->Diagnostics == WantDiagnostics::Yes)
1070 I->UpdateType = WantDiagnostics::Auto; 1326 I->Update->Diagnostics = WantDiagnostics::Auto;
1071 } 1327 }
1072 1328
1073 while (shouldSkipHeadLocked()) { 1329 while (shouldSkipHeadLocked()) {
1074 vlog("ASTWorker skipping {0} for {1}", Requests.front().Name, FileName); 1330 vlog("ASTWorker skipping {0} for {1}", Requests.front().Name, FileName);
1075 Requests.pop_front(); 1331 Requests.pop_front();
1078 // Some updates aren't dead yet, but never end up being used. 1334 // Some updates aren't dead yet, but never end up being used.
1079 // e.g. the first keystroke is live until obsoleted by the second. 1335 // e.g. the first keystroke is live until obsoleted by the second.
1080 // We debounce "maybe-unused" writes, sleeping in case they become dead. 1336 // We debounce "maybe-unused" writes, sleeping in case they become dead.
1081 // But don't delay reads (including updates where diagnostics are needed). 1337 // But don't delay reads (including updates where diagnostics are needed).
1082 for (const auto &R : Requests) 1338 for (const auto &R : Requests)
1083 if (R.UpdateType == None || R.UpdateType == WantDiagnostics::Yes) 1339 if (R.Update == None || R.Update->Diagnostics == WantDiagnostics::Yes)
1084 return Deadline::zero(); 1340 return Deadline::zero();
1085 // Front request needs to be debounced, so determine when we're ready. 1341 // Front request needs to be debounced, so determine when we're ready.
1086 Deadline D(Requests.front().AddTime + UpdateDebounce.compute(RebuildTimes)); 1342 Deadline D(Requests.front().AddTime + UpdateDebounce.compute(RebuildTimes));
1087 return D; 1343 return D;
1088 } 1344 }
1089 1345
1090 // Returns true if Requests.front() is a dead update that can be skipped. 1346 // Returns true if Requests.front() is a dead update that can be skipped.
1091 bool ASTWorker::shouldSkipHeadLocked() const { 1347 bool ASTWorker::shouldSkipHeadLocked() const {
1092 assert(!Requests.empty()); 1348 assert(!Requests.empty());
1093 auto Next = Requests.begin(); 1349 auto Next = Requests.begin();
1094 auto UpdateType = Next->UpdateType; 1350 auto Update = Next->Update;
1095 if (!UpdateType) // Only skip updates. 1351 if (!Update) // Only skip updates.
1096 return false; 1352 return false;
1097 ++Next; 1353 ++Next;
1098 // An update is live if its AST might still be read. 1354 // An update is live if its AST might still be read.
1099 // That is, if it's not immediately followed by another update. 1355 // That is, if it's not immediately followed by another update.
1100 if (Next == Requests.end() || !Next->UpdateType) 1356 if (Next == Requests.end() || !Next->Update)
1101 return false; 1357 return false;
1102 // The other way an update can be live is if its diagnostics might be used. 1358 // The other way an update can be live is if its diagnostics might be used.
1103 switch (*UpdateType) { 1359 switch (Update->Diagnostics) {
1104 case WantDiagnostics::Yes: 1360 case WantDiagnostics::Yes:
1105 return false; // Always used. 1361 return false; // Always used.
1106 case WantDiagnostics::No: 1362 case WantDiagnostics::No:
1107 return true; // Always dead. 1363 return true; // Always dead.
1108 case WantDiagnostics::Auto: 1364 case WantDiagnostics::Auto:
1109 // Used unless followed by an update that generates diagnostics. 1365 // Used unless followed by an update that generates diagnostics.
1110 for (; Next != Requests.end(); ++Next) 1366 for (; Next != Requests.end(); ++Next)
1111 if (Next->UpdateType == WantDiagnostics::Yes || 1367 if (Next->Update && Next->Update->Diagnostics != WantDiagnostics::No)
1112 Next->UpdateType == WantDiagnostics::Auto)
1113 return true; // Prefer later diagnostics. 1368 return true; // Prefer later diagnostics.
1114 return false; 1369 return false;
1115 } 1370 }
1116 llvm_unreachable("Unknown WantDiagnostics"); 1371 llvm_unreachable("Unknown WantDiagnostics");
1117 } 1372 }
1118 1373
1119 bool ASTWorker::blockUntilIdle(Deadline Timeout) const { 1374 bool ASTWorker::blockUntilIdle(Deadline Timeout) const {
1120 std::unique_lock<std::mutex> Lock(Mutex); 1375 auto WaitUntilASTWorkerIsIdle = [&] {
1121 return wait(Lock, RequestsCV, Timeout, [&] { 1376 std::unique_lock<std::mutex> Lock(Mutex);
1122 return PreambleRequests.empty() && Requests.empty() && !CurrentRequest; 1377 return wait(Lock, RequestsCV, Timeout, [&] {
1123 }); 1378 return PreambleRequests.empty() && Requests.empty() && !CurrentRequest;
1379 });
1380 };
1381 // Make sure ASTWorker has processed all requests, which might issue new
1382 // updates to PreamblePeer.
1383 WaitUntilASTWorkerIsIdle();
1384 // Now that ASTWorker processed all requests, ensure PreamblePeer has served
1385 // all update requests. This might create new PreambleRequests for the
1386 // ASTWorker.
1387 PreamblePeer.blockUntilIdle(Timeout);
1388 assert(Requests.empty() &&
1389 "No new normal tasks can be scheduled concurrently with "
1390 "blockUntilIdle(): ASTWorker isn't threadsafe");
1391 // Finally make sure ASTWorker has processed all of the preamble updates.
1392 return WaitUntilASTWorkerIsIdle();
1124 } 1393 }
1125 1394
1126 // Render a TUAction to a user-facing string representation. 1395 // Render a TUAction to a user-facing string representation.
1127 // TUAction represents clangd-internal states, we don't intend to expose them 1396 // TUAction represents clangd-internal states, we don't intend to expose them
1128 // to users (say C++ programmers) directly to avoid confusion, we use terms that 1397 // to users (say C++ programmers) directly to avoid confusion, we use terms that
1151 // We handle idle specially below. 1420 // We handle idle specially below.
1152 break; 1421 break;
1153 } 1422 }
1154 if (Result.empty()) 1423 if (Result.empty())
1155 return "idle"; 1424 return "idle";
1156 return llvm::join(Result, ","); 1425 return llvm::join(Result, ", ");
1157 } 1426 }
1158 1427
1159 } // namespace 1428 } // namespace
1160 1429
1161 unsigned getDefaultAsyncThreadsCount() { 1430 unsigned getDefaultAsyncThreadsCount() {
1176 }; 1445 };
1177 1446
1178 TUScheduler::TUScheduler(const GlobalCompilationDatabase &CDB, 1447 TUScheduler::TUScheduler(const GlobalCompilationDatabase &CDB,
1179 const Options &Opts, 1448 const Options &Opts,
1180 std::unique_ptr<ParsingCallbacks> Callbacks) 1449 std::unique_ptr<ParsingCallbacks> Callbacks)
1181 : CDB(CDB), StorePreamblesInMemory(Opts.StorePreamblesInMemory), 1450 : CDB(CDB), Opts(Opts),
1182 Callbacks(Callbacks ? move(Callbacks) 1451 Callbacks(Callbacks ? move(Callbacks)
1183 : std::make_unique<ParsingCallbacks>()), 1452 : std::make_unique<ParsingCallbacks>()),
1184 Barrier(Opts.AsyncThreadsCount), 1453 Barrier(Opts.AsyncThreadsCount), QuickRunBarrier(Opts.AsyncThreadsCount),
1185 IdleASTs( 1454 IdleASTs(
1186 std::make_unique<ASTCache>(Opts.RetentionPolicy.MaxRetainedASTs)), 1455 std::make_unique<ASTCache>(Opts.RetentionPolicy.MaxRetainedASTs)),
1187 UpdateDebounce(Opts.UpdateDebounce) { 1456 HeaderIncluders(std::make_unique<HeaderIncluderCache>()) {
1457 // Avoid null checks everywhere.
1458 if (!Opts.ContextProvider) {
1459 this->Opts.ContextProvider = [](llvm::StringRef) {
1460 return Context::current().clone();
1461 };
1462 }
1188 if (0 < Opts.AsyncThreadsCount) { 1463 if (0 < Opts.AsyncThreadsCount) {
1189 PreambleTasks.emplace(); 1464 PreambleTasks.emplace();
1190 WorkerThreads.emplace(); 1465 WorkerThreads.emplace();
1191 } 1466 }
1192 } 1467 }
1214 1489
1215 bool TUScheduler::update(PathRef File, ParseInputs Inputs, 1490 bool TUScheduler::update(PathRef File, ParseInputs Inputs,
1216 WantDiagnostics WantDiags) { 1491 WantDiagnostics WantDiags) {
1217 std::unique_ptr<FileData> &FD = Files[File]; 1492 std::unique_ptr<FileData> &FD = Files[File];
1218 bool NewFile = FD == nullptr; 1493 bool NewFile = FD == nullptr;
1494 bool ContentChanged = false;
1219 if (!FD) { 1495 if (!FD) {
1220 // Create a new worker to process the AST-related tasks. 1496 // Create a new worker to process the AST-related tasks.
1221 ASTWorkerHandle Worker = ASTWorker::create( 1497 ASTWorkerHandle Worker =
1222 File, CDB, *IdleASTs, 1498 ASTWorker::create(File, CDB, *IdleASTs, *HeaderIncluders,
1223 WorkerThreads ? WorkerThreads.getPointer() : nullptr, Barrier, 1499 WorkerThreads ? WorkerThreads.getPointer() : nullptr,
1224 UpdateDebounce, StorePreamblesInMemory, *Callbacks); 1500 Barrier, Opts, *Callbacks);
1225 FD = std::unique_ptr<FileData>( 1501 FD = std::unique_ptr<FileData>(
1226 new FileData{Inputs.Contents, std::move(Worker)}); 1502 new FileData{Inputs.Contents, std::move(Worker)});
1227 } else { 1503 ContentChanged = true;
1504 } else if (FD->Contents != Inputs.Contents) {
1505 ContentChanged = true;
1228 FD->Contents = Inputs.Contents; 1506 FD->Contents = Inputs.Contents;
1229 } 1507 }
1230 FD->Worker->update(std::move(Inputs), WantDiags); 1508 FD->Worker->update(std::move(Inputs), WantDiags, ContentChanged);
1509 // There might be synthetic update requests, don't change the LastActiveFile
1510 // in such cases.
1511 if (ContentChanged)
1512 LastActiveFile = File.str();
1231 return NewFile; 1513 return NewFile;
1232 } 1514 }
1233 1515
1234 void TUScheduler::remove(PathRef File) { 1516 void TUScheduler::remove(PathRef File) {
1235 bool Removed = Files.erase(File); 1517 bool Removed = Files.erase(File);
1236 if (!Removed) 1518 if (!Removed)
1237 elog("Trying to remove file from TUScheduler that is not tracked: {0}", 1519 elog("Trying to remove file from TUScheduler that is not tracked: {0}",
1238 File); 1520 File);
1239 } 1521 // We don't call HeaderIncluders.remove(File) here.
1240 1522 // If we did, we'd avoid potentially stale header/mainfile associations.
1241 llvm::StringMap<std::string> TUScheduler::getAllFileContents() const { 1523 // However, it would mean that closing a mainfile could invalidate the
1242 llvm::StringMap<std::string> Results; 1524 // preamble of several open headers.
1243 for (auto &It : Files) 1525 }
1244 Results.try_emplace(It.getKey(), It.getValue()->Contents); 1526
1245 return Results; 1527 void TUScheduler::run(llvm::StringRef Name, llvm::StringRef Path,
1246 }
1247
1248 void TUScheduler::run(llvm::StringRef Name,
1249 llvm::unique_function<void()> Action) { 1528 llvm::unique_function<void()> Action) {
1250 if (!PreambleTasks) 1529 runWithSemaphore(Name, Path, std::move(Action), Barrier);
1530 }
1531
1532 void TUScheduler::runQuick(llvm::StringRef Name, llvm::StringRef Path,
1533 llvm::unique_function<void()> Action) {
1534 // Use QuickRunBarrier to serialize quick tasks: we are ignoring
1535 // the parallelism level set by the user, don't abuse it
1536 runWithSemaphore(Name, Path, std::move(Action), QuickRunBarrier);
1537 }
1538
1539 void TUScheduler::runWithSemaphore(llvm::StringRef Name, llvm::StringRef Path,
1540 llvm::unique_function<void()> Action,
1541 Semaphore &Sem) {
1542 if (Path.empty())
1543 Path = LastActiveFile;
1544 else
1545 LastActiveFile = Path.str();
1546 if (!PreambleTasks) {
1547 WithContext WithProvidedContext(Opts.ContextProvider(Path));
1251 return Action(); 1548 return Action();
1252 PreambleTasks->runAsync(Name, [this, Ctx = Context::current().clone(), 1549 }
1550 PreambleTasks->runAsync(Name, [this, &Sem, Ctx = Context::current().clone(),
1551 Path(Path.str()),
1253 Action = std::move(Action)]() mutable { 1552 Action = std::move(Action)]() mutable {
1254 std::lock_guard<Semaphore> BarrierLock(Barrier); 1553 std::lock_guard<Semaphore> BarrierLock(Sem);
1255 WithContext WC(std::move(Ctx)); 1554 WithContext WC(std::move(Ctx));
1555 WithContext WithProvidedContext(Opts.ContextProvider(Path));
1256 Action(); 1556 Action();
1257 }); 1557 });
1258 } 1558 }
1259 1559
1260 void TUScheduler::runWithAST( 1560 void TUScheduler::runWithAST(
1265 if (It == Files.end()) { 1565 if (It == Files.end()) {
1266 Action(llvm::make_error<LSPError>( 1566 Action(llvm::make_error<LSPError>(
1267 "trying to get AST for non-added document", ErrorCode::InvalidParams)); 1567 "trying to get AST for non-added document", ErrorCode::InvalidParams));
1268 return; 1568 return;
1269 } 1569 }
1570 LastActiveFile = File.str();
1270 1571
1271 It->second->Worker->runWithAST(Name, std::move(Action), Invalidation); 1572 It->second->Worker->runWithAST(Name, std::move(Action), Invalidation);
1272 } 1573 }
1273 1574
1274 void TUScheduler::runWithPreamble(llvm::StringRef Name, PathRef File, 1575 void TUScheduler::runWithPreamble(llvm::StringRef Name, PathRef File,
1279 Action(llvm::make_error<LSPError>( 1580 Action(llvm::make_error<LSPError>(
1280 "trying to get preamble for non-added document", 1581 "trying to get preamble for non-added document",
1281 ErrorCode::InvalidParams)); 1582 ErrorCode::InvalidParams));
1282 return; 1583 return;
1283 } 1584 }
1585 LastActiveFile = File.str();
1284 1586
1285 if (!PreambleTasks) { 1587 if (!PreambleTasks) {
1286 trace::Span Tracer(Name); 1588 trace::Span Tracer(Name);
1287 SPAN_ATTACH(Tracer, "file", File); 1589 SPAN_ATTACH(Tracer, "file", File);
1590 std::shared_ptr<const ASTSignals> Signals;
1288 std::shared_ptr<const PreambleData> Preamble = 1591 std::shared_ptr<const PreambleData> Preamble =
1289 It->second->Worker->getPossiblyStalePreamble(); 1592 It->second->Worker->getPossiblyStalePreamble(&Signals);
1593 WithContext WithProvidedContext(Opts.ContextProvider(File));
1290 Action(InputsAndPreamble{It->second->Contents, 1594 Action(InputsAndPreamble{It->second->Contents,
1291 It->second->Worker->getCurrentCompileCommand(), 1595 It->second->Worker->getCurrentCompileCommand(),
1292 Preamble.get()}); 1596 Preamble.get(), Signals.get()});
1293 return; 1597 return;
1294 } 1598 }
1295 1599
1296 std::shared_ptr<const ASTWorker> Worker = It->second->Worker.lock(); 1600 std::shared_ptr<const ASTWorker> Worker = It->second->Worker.lock();
1297 auto Task = 1601 auto Task = [Worker, Consistency, Name = Name.str(), File = File.str(),
1298 [Worker, Consistency, Name = Name.str(), File = File.str(), 1602 Contents = It->second->Contents,
1299 Contents = It->second->Contents, 1603 Command = Worker->getCurrentCompileCommand(),
1300 Command = Worker->getCurrentCompileCommand(), 1604 Ctx = Context::current().derive(kFileBeingProcessed,
1301 Ctx = Context::current().derive(kFileBeingProcessed, std::string(File)), 1605 std::string(File)),
1302 Action = std::move(Action), this]() mutable { 1606 Action = std::move(Action), this]() mutable {
1303 std::shared_ptr<const PreambleData> Preamble; 1607 std::shared_ptr<const PreambleData> Preamble;
1304 if (Consistency == PreambleConsistency::Stale) { 1608 if (Consistency == PreambleConsistency::Stale) {
1305 // Wait until the preamble is built for the first time, if preamble 1609 // Wait until the preamble is built for the first time, if preamble
1306 // is required. This avoids extra work of processing the preamble 1610 // is required. This avoids extra work of processing the preamble
1307 // headers in parallel multiple times. 1611 // headers in parallel multiple times.
1308 Worker->waitForFirstPreamble(); 1612 Worker->waitForFirstPreamble();
1309 } 1613 }
1310 Preamble = Worker->getPossiblyStalePreamble(); 1614 std::shared_ptr<const ASTSignals> Signals;
1311 1615 Preamble = Worker->getPossiblyStalePreamble(&Signals);
1312 std::lock_guard<Semaphore> BarrierLock(Barrier); 1616
1313 WithContext Guard(std::move(Ctx)); 1617 std::lock_guard<Semaphore> BarrierLock(Barrier);
1314 trace::Span Tracer(Name); 1618 WithContext Guard(std::move(Ctx));
1315 SPAN_ATTACH(Tracer, "file", File); 1619 trace::Span Tracer(Name);
1316 Action(InputsAndPreamble{Contents, Command, Preamble.get()}); 1620 SPAN_ATTACH(Tracer, "file", File);
1317 }; 1621 WithContext WithProvidedContext(Opts.ContextProvider(File));
1622 Action(InputsAndPreamble{Contents, Command, Preamble.get(), Signals.get()});
1623 };
1318 1624
1319 PreambleTasks->runAsync("task:" + llvm::sys::path::filename(File), 1625 PreambleTasks->runAsync("task:" + llvm::sys::path::filename(File),
1320 std::move(Task)); 1626 std::move(Task));
1321 } 1627 }
1322 1628
1364 DebouncePolicy P; 1670 DebouncePolicy P;
1365 P.Min = P.Max = T; 1671 P.Min = P.Max = T;
1366 return P; 1672 return P;
1367 } 1673 }
1368 1674
1675 void TUScheduler::profile(MemoryTree &MT) const {
1676 for (const auto &Elem : fileStats()) {
1677 MT.detail(Elem.first())
1678 .child("preamble")
1679 .addUsage(Opts.StorePreamblesInMemory ? Elem.second.UsedBytesPreamble
1680 : 0);
1681 MT.detail(Elem.first()).child("ast").addUsage(Elem.second.UsedBytesAST);
1682 MT.child("header_includer_cache").addUsage(HeaderIncluders->getUsedBytes());
1683 }
1684 }
1369 } // namespace clangd 1685 } // namespace clangd
1370 } // namespace clang 1686 } // namespace clang