xref: /aosp_15_r20/external/perfetto/src/trace_processor/util/annotated_callsites.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SRC_TRACE_PROCESSOR_UTIL_ANNOTATED_CALLSITES_H_
18 #define SRC_TRACE_PROCESSOR_UTIL_ANNOTATED_CALLSITES_H_
19 
20 #include <optional>
21 
22 #include <unordered_map>
23 #include "src/trace_processor/containers/string_pool.h"
24 #include "src/trace_processor/storage/trace_storage.h"
25 
26 namespace perfetto {
27 namespace trace_processor {
28 
29 class TraceProcessorContext;
30 
31 enum class CallsiteAnnotation {
32   kNone,
33   kCommonFrame,
34   kCommonFrameInterp,
35   kArtInterpreted,
36   kArtJit,
37   kArtAot,
38 };
39 
40 // Helper class to augment callsite with (currently Android-specific)
41 // annotations. A given callsite will always have the same annotation. This
42 // class will internally cache already computed annotations. An annotation
43 // depends only of the current callsite and the annotations of its parent
44 // callsites (going to the root).
45 class AnnotatedCallsites {
46  public:
47   explicit AnnotatedCallsites(const TraceProcessorContext* context);
48 
GetAnnotation(const tables::StackProfileCallsiteTable::ConstRowReference & callsite)49   CallsiteAnnotation GetAnnotation(
50       const tables::StackProfileCallsiteTable::ConstRowReference& callsite) {
51     return Get(callsite).second;
52   }
53 
54  private:
55   enum class MapType {
56     kArtInterp,
57     kArtJit,
58     kArtAot,
59     kNativeLibart,
60     kNativeOther,
61     kOther
62   };
63 
64   // Annotation FSM states:
65   // * kInitial: default, native-only callstacks never leave this state.
66   // * kEraseLibart: we've seen a managed frame, and will now "erase" (i.e. tag
67   //                 as a common-frame) frames belonging to the ART runtime.
68   // * kKeepNext: we've seen a special JNI trampoline for managed->native
69   //              transition, keep the immediate child (even if it is in ART),
70   //              and then go back to kEraseLibart.
71   // Regardless of the state, managed frames get annotated with their execution
72   // mode, based on the mapping.
73   enum class State { kInitial, kEraseLibart, kKeepNext };
74 
75   State GetState(std::optional<CallsiteId> id);
76 
77   std::pair<State, CallsiteAnnotation> Get(
78       const tables::StackProfileCallsiteTable::ConstRowReference& callsite);
79 
80   MapType GetMapType(MappingId id);
81   MapType ClassifyMap(NullTermStringView map);
82 
83   const TraceProcessorContext& context_;
84   const std::optional<StringPool::Id> art_jni_trampoline_;
85 
86   std::unordered_map<MappingId, MapType> map_types_;
87   std::unordered_map<CallsiteId, State> states_;
88 };
89 
90 }  // namespace trace_processor
91 }  // namespace perfetto
92 
93 #endif  // SRC_TRACE_PROCESSOR_UTIL_ANNOTATED_CALLSITES_H_
94