1 : // Copyright 2013 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #ifndef SYZYGY_AGENT_PROFILER_SYMBOL_MAP_H_
16 : #define SYZYGY_AGENT_PROFILER_SYMBOL_MAP_H_
17 :
18 : #include "base/atomicops.h"
19 :
20 : #include "base/memory/ref_counted.h"
21 : #include "base/strings/string_piece.h"
22 : #include "base/synchronization/lock.h"
23 : #include "syzygy/core/address_space.h"
24 :
25 : namespace agent {
26 : namespace profiler {
27 :
28 : // The symbol map maintains a map from address range to "symbol" to allow
29 : // resolving addresses of dynamically generated, garbage collected code, to
30 : // names in a profiler. This is geared to allow entry/exit processing in a
31 : // profiler to execute as quickly as possible.
32 : class SymbolMap {
33 : public:
34 : class Symbol;
35 :
36 : SymbolMap();
37 : ~SymbolMap();
38 :
39 : // Adds a new symbol to the symbol map.
40 : // @param start_addr the starting address of the new symbol.
41 : // @param length the length of the new symbol.
42 : // @param name the name of the new symbol.
43 : void AddSymbol(const void* start_addr,
44 : size_t length,
45 : const base::StringPiece& name);
46 :
47 : // Move an existing symbol.
48 : // @param old_addr the previous address of the symbol.
49 : // @param new_addr the new address of the symbol.
50 : void MoveSymbol(const void* old_addr, const void* new_addr);
51 :
52 : // Find the symbol covering @p addr, if any.
53 : // @param addr an address to query.
54 : // @returns the symbol covering @p addr, if any, or NULL otherwise.
55 : scoped_refptr<Symbol> FindSymbol(const void* addr);
56 :
57 : protected:
58 : typedef core::AddressSpace<const uint8_t*, size_t, scoped_refptr<Symbol>>
59 : SymbolAddressSpace;
60 : typedef SymbolAddressSpace::Range Range;
61 :
62 : // Retire any symbols overlapping @p range.
63 : void RetireRangeUnlocked(const Range& range);
64 :
65 : base::Lock lock_;
66 : SymbolAddressSpace addr_space_; // Under lock_.
67 :
68 : private:
69 : DISALLOW_COPY_AND_ASSIGN(SymbolMap);
70 : };
71 :
72 : class SymbolMap::Symbol : public base::RefCountedThreadSafe<Symbol> {
73 : public:
74 : class AutoLock;
75 :
76 : explicit Symbol(const base::StringPiece& name, const void* address);
77 :
78 : // Name this symbol by assigning it an id, if it doesn't already have one.
79 : // @returns true iff the symbol did not already have an id.
80 : bool EnsureHasId();
81 :
82 : // @name Accessors.
83 : // @{
84 E : const std::string& name() const { return name_; }
85 E : bool invalid() const { return address_ == NULL; }
86 E : int32_t id() const { return id_; }
87 E : int32_t move_count() const {
88 E : return base::subtle::Acquire_Load(&move_count_);
89 E : }
90 E : const void* address() const { return address_; }
91 : // @}
92 :
93 : protected:
94 : friend class SymbolMap;
95 :
96 : // Invalidate this symbol.
97 : void Invalidate();
98 : // Move this symbol.
99 : void Move(const void* address);
100 :
101 : std::string name_;
102 :
103 : // Incremented each time the symbol moves.
104 : base::subtle::Atomic32 move_count_;
105 :
106 : // Non-zero after first call to EnsureHasId.
107 : base::subtle::Atomic32 id_;
108 :
109 : // The current address of this symbol.
110 : const void* address_;
111 :
112 : private:
113 : friend class base::RefCountedThreadSafe<Symbol>;
114 E : ~Symbol() {}
115 :
116 : static base::subtle::Atomic32 next_symbol_id_;
117 :
118 : private:
119 : DISALLOW_COPY_AND_ASSIGN(Symbol);
120 : };
121 :
122 : } // namespace profiler
123 : } // namespace agent
124 :
125 : #endif // SYZYGY_AGENT_PROFILER_SYMBOL_MAP_H_
|