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 : #include "base/basictypes.h"
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*, 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 id() const { return id_; }
87 E : int32 move_count() const { return base::subtle::Acquire_Load(&move_count_); }
88 E : const void* address() const { return address_; }
89 : // @}
90 :
91 : protected:
92 : friend class SymbolMap;
93 :
94 : // Invalidate this symbol.
95 : void Invalidate();
96 : // Move this symbol.
97 : void Move(const void* address);
98 :
99 : std::string name_;
100 :
101 : // Incremented each time the symbol moves.
102 : base::subtle::Atomic32 move_count_;
103 :
104 : // Non-zero after first call to EnsureHasId.
105 : base::subtle::Atomic32 id_;
106 :
107 : // The current address of this symbol.
108 : const void* address_;
109 :
110 : private:
111 : friend class base::RefCountedThreadSafe<Symbol>;
112 E : ~Symbol() {}
113 :
114 : static base::subtle::Atomic32 next_symbol_id_;
115 :
116 : private:
117 : DISALLOW_COPY_AND_ASSIGN(Symbol);
118 : };
119 :
120 : } // namespace profiler
121 : } // namespace agent
122 :
123 : #endif // SYZYGY_AGENT_PROFILER_SYMBOL_MAP_H_
|