Line data Source code
1 : //===--- Trace.h - Performance tracing facilities ---------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // Supports writing performance traces describing clangd's behavior.
11 : // Traces are consumed by implementations of the EventTracer interface.
12 : //
13 : //
14 : // All APIs are no-ops unless a Session is active (created by ClangdMain).
15 : //
16 : //===----------------------------------------------------------------------===//
17 :
18 : #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
19 : #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
20 :
21 : #include "Context.h"
22 : #include "Function.h"
23 : #include "JSONExpr.h"
24 : #include "llvm/ADT/Twine.h"
25 : #include "llvm/Support/raw_ostream.h"
26 :
27 : namespace clang {
28 : namespace clangd {
29 : namespace trace {
30 :
31 : /// A consumer of trace events. The events are produced by Spans and trace::log.
32 : /// Implmentations of this interface must be thread-safe.
33 : class EventTracer {
34 : public:
35 : virtual ~EventTracer() = default;
36 :
37 : /// Called when event that has a duration starts. \p Name describes the event.
38 : /// Returns a derived context that will be destroyed when the event ends.
39 : /// Usually implementations will store an object in the returned context
40 : /// whose destructor records the end of the event.
41 : /// The args are *Args, only complete when the event ends.
42 : virtual Context beginSpan(llvm::StringRef Name, json::obj *Args) = 0;
43 :
44 : /// Called for instant events.
45 : virtual void instant(llvm::StringRef Name, json::obj &&Args) = 0;
46 : };
47 :
48 : /// Sets up a global EventTracer that consumes events produced by Span and
49 : /// trace::log. Only one TracingSession can be active at a time and it should be
50 : /// set up before calling any clangd-specific functions.
51 : class Session {
52 : public:
53 : Session(EventTracer &Tracer);
54 : ~Session();
55 : };
56 :
57 : /// Create an instance of EventTracer that produces an output in the Trace Event
58 : /// format supported by Chrome's trace viewer (chrome://tracing).
59 : ///
60 : /// The format is documented here:
61 : /// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
62 : std::unique_ptr<EventTracer> createJSONTracer(llvm::raw_ostream &OS,
63 : bool Pretty = false);
64 :
65 : /// Records a single instant event, associated with the current thread.
66 : void log(const llvm::Twine &Name);
67 :
68 : /// Records an event whose duration is the lifetime of the Span object.
69 : /// This lifetime is extended when the span's context is reused.
70 : ///
71 : /// This is the main public interface for producing tracing events.
72 : ///
73 : /// Arbitrary JSON metadata can be attached while this span is active:
74 : /// SPAN_ATTACH(MySpan, "Payload", SomeJSONExpr);
75 : ///
76 : /// SomeJSONExpr is evaluated and copied only if actually needed.
77 0 : class Span {
78 : public:
79 : Span(llvm::StringRef Name);
80 :
81 : /// Mutable metadata, if this span is interested.
82 : /// Prefer to use SPAN_ATTACH rather than accessing this directly.
83 : json::obj *const Args;
84 :
85 : private:
86 : WithContext RestoreCtx;
87 : };
88 :
89 : /// Returns mutable span metadata if this span is interested.
90 : /// Prefer to use SPAN_ATTACH rather than accessing this directly.
91 : json::obj *spanArgs();
92 :
93 : /// Attach a key-value pair to a Span event.
94 : /// This is not threadsafe when used with the same Span.
95 : #define SPAN_ATTACH(S, Name, Expr) \
96 : do { \
97 : if (auto *Args = (S).Args) \
98 : (*Args)[Name] = Expr; \
99 : } while (0)
100 :
101 : } // namespace trace
102 : } // namespace clangd
103 : } // namespace clang
104 :
105 : #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_TRACE_H_
|