Bug 1073336 part 5 - Add AnimationPlayerCollection::PlayerUpdated; r=dbaron
[gecko.git] / tools / profiler / LulCommonExt.h
blob67f08d631a93c3154fb4807b4430f1c993a13291
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
4 // Copyright (c) 2006, 2010, 2012, 2013 Google Inc.
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
9 // met:
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
35 // module.h: Define google_breakpad::Module. A Module holds debugging
36 // information, and can write that information out as a Breakpad
37 // symbol file.
40 // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
41 // Copyright (c) 2001, 2002 Peter Dimov
43 // Permission to copy, use, modify, sell and distribute this software
44 // is granted provided this copyright notice appears in all copies.
45 // This software is provided "as is" without express or implied
46 // warranty, and with no claim as to its suitability for any purpose.
48 // See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
52 // This file is derived from the following files in
53 // toolkit/crashreporter/google-breakpad:
54 // src/common/unique_string.h
55 // src/common/scoped_ptr.h
56 // src/common/module.h
58 // External interface for the "Common" component of LUL.
60 #ifndef LulCommonExt_h
61 #define LulCommonExt_h
63 #include <stdlib.h>
64 #include <stdio.h>
65 #include <stdint.h>
67 #include <string>
68 #include <map>
69 #include <vector>
70 #include <cstddef> // for std::ptrdiff_t
72 #include "mozilla/Assertions.h"
73 #include "mozilla/NullPtr.h"
75 namespace lul {
77 ////////////////////////////////////////////////////////////////
78 // UniqueString
81 // Abstract type
82 class UniqueString;
84 // Unique-ify a string. |ToUniqueString| can never return nullptr.
85 const UniqueString* ToUniqueString(std::string);
87 // Get the contained C string (debugging only)
88 const char* const FromUniqueString(const UniqueString*);
90 // Some handy pre-uniqified strings. Z is an escape character:
91 // ZS '$'
92 // ZD '.'
93 // Zeq '='
94 // Zplus '+'
95 // Zstar '*'
96 // Zslash '/'
97 // Zpercent '%'
98 // Zat '@'
99 // Zcaret '^'
101 // Note that ustr__empty and (UniqueString*)nullptr are considered
102 // to be different.
104 // Unfortunately these have to be written as functions so as to
105 // make them safe to use in static initialisers.
107 // ""
108 inline static const UniqueString* ustr__empty() {
109 static const UniqueString* us = nullptr;
110 if (!us) us = ToUniqueString("");
111 return us;
114 // ".cfa"
115 inline static const UniqueString* ustr__ZDcfa() {
116 static const UniqueString* us = nullptr;
117 if (!us) us = ToUniqueString(".cfa");
118 return us;
121 // ".ra"
122 inline static const UniqueString* ustr__ZDra() {
123 static const UniqueString* us = nullptr;
124 if (!us) us = ToUniqueString(".ra");
125 return us;
129 ////////////////////////////////////////////////////////////////
130 // GUID
133 typedef struct {
134 uint32_t data1;
135 uint16_t data2;
136 uint16_t data3;
137 uint8_t data4[8];
138 } MDGUID; // GUID
140 typedef MDGUID GUID;
143 ////////////////////////////////////////////////////////////////
144 // scoped_ptr
147 // scoped_ptr mimics a built-in pointer except that it guarantees deletion
148 // of the object pointed to, either on destruction of the scoped_ptr or via
149 // an explicit reset(). scoped_ptr is a simple solution for simple needs;
150 // use shared_ptr or std::auto_ptr if your needs are more complex.
152 // *** NOTE ***
153 // If your scoped_ptr is a class member of class FOO pointing to a
154 // forward declared type BAR (as shown below), then you MUST use a non-inlined
155 // version of the destructor. The destructor of a scoped_ptr (called from
156 // FOO's destructor) must have a complete definition of BAR in order to
157 // destroy it. Example:
159 // -- foo.h --
160 // class BAR;
162 // class FOO {
163 // public:
164 // FOO();
165 // ~FOO(); // Required for sources that instantiate class FOO to compile!
167 // private:
168 // scoped_ptr<BAR> bar_;
169 // };
171 // -- foo.cc --
172 // #include "foo.h"
173 // FOO::~FOO() {} // Empty, but must be non-inlined to FOO's class definition.
175 // scoped_ptr_malloc added by Google
176 // When one of these goes out of scope, instead of doing a delete or
177 // delete[], it calls free(). scoped_ptr_malloc<char> is likely to see
178 // much more use than any other specializations.
180 // release() added by Google
181 // Use this to conditionally transfer ownership of a heap-allocated object
182 // to the caller, usually on method success.
184 template <typename T>
185 class scoped_ptr {
186 private:
188 T* ptr;
190 scoped_ptr(scoped_ptr const &);
191 scoped_ptr & operator=(scoped_ptr const &);
193 public:
195 typedef T element_type;
197 explicit scoped_ptr(T* p = 0): ptr(p) {}
199 ~scoped_ptr() {
200 delete ptr;
203 void reset(T* p = 0) {
204 if (ptr != p) {
205 delete ptr;
206 ptr = p;
210 T& operator*() const {
211 MOZ_ASSERT(ptr != 0);
212 return *ptr;
215 T* operator->() const {
216 MOZ_ASSERT(ptr != 0);
217 return ptr;
220 bool operator==(T* p) const {
221 return ptr == p;
224 bool operator!=(T* p) const {
225 return ptr != p;
228 T* get() const {
229 return ptr;
232 void swap(scoped_ptr & b) {
233 T* tmp = b.ptr;
234 b.ptr = ptr;
235 ptr = tmp;
238 T* release() {
239 T* tmp = ptr;
240 ptr = 0;
241 return tmp;
244 private:
246 // no reason to use these: each scoped_ptr should have its own object
247 template <typename U> bool operator==(scoped_ptr<U> const& p) const;
248 template <typename U> bool operator!=(scoped_ptr<U> const& p) const;
251 template<typename T> inline
252 void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {
253 a.swap(b);
256 template<typename T> inline
257 bool operator==(T* p, const scoped_ptr<T>& b) {
258 return p == b.get();
261 template<typename T> inline
262 bool operator!=(T* p, const scoped_ptr<T>& b) {
263 return p != b.get();
266 // scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
267 // is guaranteed, either on destruction of the scoped_array or via an explicit
268 // reset(). Use shared_array or std::vector if your needs are more complex.
270 template<typename T>
271 class scoped_array {
272 private:
274 T* ptr;
276 scoped_array(scoped_array const &);
277 scoped_array & operator=(scoped_array const &);
279 public:
281 typedef T element_type;
283 explicit scoped_array(T* p = 0) : ptr(p) {}
285 ~scoped_array() {
286 delete[] ptr;
289 void reset(T* p = 0) {
290 if (ptr != p) {
291 delete [] ptr;
292 ptr = p;
296 T& operator[](std::ptrdiff_t i) const {
297 MOZ_ASSERT(ptr != 0);
298 MOZ_ASSERT(i >= 0);
299 return ptr[i];
302 bool operator==(T* p) const {
303 return ptr == p;
306 bool operator!=(T* p) const {
307 return ptr != p;
310 T* get() const {
311 return ptr;
314 void swap(scoped_array & b) {
315 T* tmp = b.ptr;
316 b.ptr = ptr;
317 ptr = tmp;
320 T* release() {
321 T* tmp = ptr;
322 ptr = 0;
323 return tmp;
326 private:
328 // no reason to use these: each scoped_array should have its own object
329 template <typename U> bool operator==(scoped_array<U> const& p) const;
330 template <typename U> bool operator!=(scoped_array<U> const& p) const;
333 template<class T> inline
334 void swap(scoped_array<T>& a, scoped_array<T>& b) {
335 a.swap(b);
338 template<typename T> inline
339 bool operator==(T* p, const scoped_array<T>& b) {
340 return p == b.get();
343 template<typename T> inline
344 bool operator!=(T* p, const scoped_array<T>& b) {
345 return p != b.get();
349 // This class wraps the c library function free() in a class that can be
350 // passed as a template argument to scoped_ptr_malloc below.
351 class ScopedPtrMallocFree {
352 public:
353 inline void operator()(void* x) const {
354 free(x);
358 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
359 // second template argument, the functor used to free the object.
361 template<typename T, typename FreeProc = ScopedPtrMallocFree>
362 class scoped_ptr_malloc {
363 private:
365 T* ptr;
367 scoped_ptr_malloc(scoped_ptr_malloc const &);
368 scoped_ptr_malloc & operator=(scoped_ptr_malloc const &);
370 public:
372 typedef T element_type;
374 explicit scoped_ptr_malloc(T* p = 0): ptr(p) {}
376 ~scoped_ptr_malloc() {
377 free_((void*) ptr);
380 void reset(T* p = 0) {
381 if (ptr != p) {
382 free_((void*) ptr);
383 ptr = p;
387 T& operator*() const {
388 MOZ_ASSERT(ptr != 0);
389 return *ptr;
392 T* operator->() const {
393 MOZ_ASSERT(ptr != 0);
394 return ptr;
397 bool operator==(T* p) const {
398 return ptr == p;
401 bool operator!=(T* p) const {
402 return ptr != p;
405 T* get() const {
406 return ptr;
409 void swap(scoped_ptr_malloc & b) {
410 T* tmp = b.ptr;
411 b.ptr = ptr;
412 ptr = tmp;
415 T* release() {
416 T* tmp = ptr;
417 ptr = 0;
418 return tmp;
421 private:
423 // no reason to use these: each scoped_ptr_malloc should have its own object
424 template <typename U, typename GP>
425 bool operator==(scoped_ptr_malloc<U, GP> const& p) const;
426 template <typename U, typename GP>
427 bool operator!=(scoped_ptr_malloc<U, GP> const& p) const;
429 static FreeProc const free_;
432 template<typename T, typename FP>
433 FP const scoped_ptr_malloc<T,FP>::free_ = FP();
435 template<typename T, typename FP> inline
436 void swap(scoped_ptr_malloc<T,FP>& a, scoped_ptr_malloc<T,FP>& b) {
437 a.swap(b);
440 template<typename T, typename FP> inline
441 bool operator==(T* p, const scoped_ptr_malloc<T,FP>& b) {
442 return p == b.get();
445 template<typename T, typename FP> inline
446 bool operator!=(T* p, const scoped_ptr_malloc<T,FP>& b) {
447 return p != b.get();
451 ////////////////////////////////////////////////////////////////
452 // Module
455 // A Module represents the contents of a module, and supports methods
456 // for adding information produced by parsing STABS or DWARF data
457 // --- possibly both from the same file --- and then writing out the
458 // unified contents as a Breakpad-format symbol file.
459 class Module {
460 public:
461 // The type of addresses and sizes in a symbol table.
462 typedef uint64_t Address;
464 // Representation of an expression. This can either be a postfix
465 // expression, in which case it is stored as a string, or a simple
466 // expression of the form (identifier + imm) or *(identifier + imm).
467 // It can also be invalid (denoting "no value").
468 enum ExprHow {
469 kExprInvalid = 1,
470 kExprPostfix,
471 kExprSimple,
472 kExprSimpleMem
475 struct Expr {
476 // Construct a simple-form expression
477 Expr(const UniqueString* ident, long offset, bool deref) {
478 if (ident == ustr__empty()) {
479 Expr();
480 } else {
481 postfix_ = "";
482 ident_ = ident;
483 offset_ = offset;
484 how_ = deref ? kExprSimpleMem : kExprSimple;
488 // Construct an invalid expression
489 Expr() {
490 postfix_ = "";
491 ident_ = nullptr;
492 offset_ = 0;
493 how_ = kExprInvalid;
496 // Return the postfix expression string, either directly,
497 // if this is a postfix expression, or by synthesising it
498 // for a simple expression.
499 std::string getExprPostfix() const {
500 switch (how_) {
501 case kExprPostfix:
502 return postfix_;
503 case kExprSimple:
504 case kExprSimpleMem: {
505 char buf[40];
506 sprintf(buf, " %ld %c%s", labs(offset_), offset_ < 0 ? '-' : '+',
507 how_ == kExprSimple ? "" : " ^");
508 return std::string(FromUniqueString(ident_)) + std::string(buf);
510 case kExprInvalid:
511 default:
512 MOZ_ASSERT(0 && "getExprPostfix: invalid Module::Expr type");
513 return "Expr::genExprPostfix: kExprInvalid";
517 // The identifier that gives the starting value for simple expressions.
518 const UniqueString* ident_;
519 // The offset to add for simple expressions.
520 long offset_;
521 // The Postfix expression string to evaluate for non-simple expressions.
522 std::string postfix_;
523 // The operation expressed by this expression.
524 ExprHow how_;
527 // A map from register names to expressions that recover
528 // their values. This can represent a complete set of rules to
529 // follow at some address, or a set of changes to be applied to an
530 // extant set of rules.
531 // NOTE! there are two completely different types called RuleMap. This
532 // is one of them.
533 typedef std::map<const UniqueString*, Expr> RuleMap;
535 // A map from addresses to RuleMaps, representing changes that take
536 // effect at given addresses.
537 typedef std::map<Address, RuleMap> RuleChangeMap;
539 // A range of 'STACK CFI' stack walking information. An instance of
540 // this structure corresponds to a 'STACK CFI INIT' record and the
541 // subsequent 'STACK CFI' records that fall within its range.
542 struct StackFrameEntry {
543 // The starting address and number of bytes of machine code this
544 // entry covers.
545 Address address, size;
547 // The initial register recovery rules, in force at the starting
548 // address.
549 RuleMap initial_rules;
551 // A map from addresses to rule changes. To find the rules in
552 // force at a given address, start with initial_rules, and then
553 // apply the changes given in this map for all addresses up to and
554 // including the address you're interested in.
555 RuleChangeMap rule_changes;
558 // Create a new module with the given name, operating system,
559 // architecture, and ID string.
560 Module(const std::string &name, const std::string &os,
561 const std::string &architecture, const std::string &id);
562 ~Module();
564 private:
566 // Module header entries.
567 std::string name_, os_, architecture_, id_;
571 } // namespace lul
573 #endif // LulCommonExt_h