- add sources.
[platform/framework/web/crosswalk.git] / src / third_party / tcmalloc / vendor / src / windows / auto_testing_hook.h
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 //    * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //    * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 //    * Neither the name of Google Inc. nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 // Utility for using SideStep with unit tests.
30
31 #ifndef CEEE_TESTING_SIDESTEP_AUTO_TESTING_HOOK_H_
32 #define CEEE_TESTING_SIDESTEP_AUTO_TESTING_HOOK_H_
33
34 #include "base/basictypes.h"
35 #include "base/logging.h"
36 #include "preamble_patcher.h"
37
38 #define SIDESTEP_CHK(x)  CHECK(x)
39 #define SIDESTEP_EXPECT_TRUE(x)  SIDESTEP_CHK(x)
40
41 namespace sidestep {
42
43 // Same trick as common/scope_cleanup.h ScopeGuardImplBase
44 class AutoTestingHookBase {
45  public:
46   virtual ~AutoTestingHookBase() {}
47 };
48
49 // This is the typedef you normally use for the class, e.g.
50 //
51 // AutoTestingHook hook = MakeTestingHook(TargetFunc, HookTargetFunc);
52 //
53 // The 'hook' variable will then be destroyed when it goes out of scope.
54 //
55 // NOTE: You must not hold this type as a member of another class.  Its
56 // destructor will not get called.
57 typedef const AutoTestingHookBase& AutoTestingHook;
58
59 // This is the class you must use when holding a hook as a member of another
60 // class, e.g.
61 //
62 // public:
63 //  AutoTestingHookHolder holder_;
64 //  MyClass() : my_hook_holder(MakeTestingHookHolder(Target, Hook)) {}
65 class AutoTestingHookHolder {
66  public:
67   explicit AutoTestingHookHolder(AutoTestingHookBase* hook) : hook_(hook) {}
68   ~AutoTestingHookHolder() { delete hook_; }
69  private:
70   AutoTestingHookHolder() {}  // disallow
71   AutoTestingHookBase* hook_;
72 };
73
74 // This class helps patch a function, then unpatch it when the object exits
75 // scope, and also maintains the pointer to the original function stub.
76 //
77 // To enable use of the class without having to explicitly provide the
78 // type of the function pointers (and instead only providing it
79 // implicitly) we use the same trick as ScopeGuard (see
80 // common/scope_cleanup.h) uses, so to create a hook you use the MakeHook
81 // function rather than a constructor.
82 //
83 // NOTE:  This function is only safe for e.g. unit tests and _not_ for
84 // production code.  See PreamblePatcher class for details.
85 template <typename T>
86 class AutoTestingHookImpl : public AutoTestingHookBase {
87  public:
88   static AutoTestingHookImpl<T> MakeTestingHook(T target_function,
89                                                 T replacement_function,
90                                                 bool do_it) {
91     return AutoTestingHookImpl<T>(target_function, replacement_function, do_it);
92   }
93
94   static AutoTestingHookImpl<T>* MakeTestingHookHolder(T target_function,
95                                                        T replacement_function,
96                                                        bool do_it) {
97     return new AutoTestingHookImpl<T>(target_function,
98                                       replacement_function, do_it);
99   }
100
101   ~AutoTestingHookImpl() {
102     if (did_it_) {
103       SIDESTEP_CHK(SIDESTEP_SUCCESS == PreamblePatcher::Unpatch(
104           (void*)target_function_, (void*)replacement_function_,
105           (void*)original_function_));
106     }
107   }
108
109   // Returns a pointer to the original function.  To use this method you will
110   // have to explicitly create an AutoTestingHookImpl of the specific
111   // function pointer type (i.e. not use the AutoTestingHook typedef).
112   T original_function() {
113     return original_function_;
114   }
115
116  private:
117   AutoTestingHookImpl(T target_function, T replacement_function, bool do_it)
118       : target_function_(target_function),
119         original_function_(NULL),
120         replacement_function_(replacement_function),
121         did_it_(do_it) {
122     if (do_it) {
123       SIDESTEP_CHK(SIDESTEP_SUCCESS == PreamblePatcher::Patch(target_function,
124                                                      replacement_function,
125                                                      &original_function_));
126     }
127   }
128
129   T target_function_;  // always valid
130   T original_function_;  // always valid
131   T replacement_function_;  // always valid
132   bool did_it_;  // Remember if we did it or not...
133 };
134
135 template <typename T>
136 inline AutoTestingHookImpl<T> MakeTestingHook(T target,
137                                               T replacement,
138                                               bool do_it) {
139   return AutoTestingHookImpl<T>::MakeTestingHook(target, replacement, do_it);
140 }
141
142 template <typename T>
143 inline AutoTestingHookImpl<T> MakeTestingHook(T target, T replacement) {
144   return AutoTestingHookImpl<T>::MakeTestingHook(target, replacement, true);
145 }
146
147 template <typename T>
148 inline AutoTestingHookImpl<T>* MakeTestingHookHolder(T target, T replacement) {
149   return AutoTestingHookImpl<T>::MakeTestingHookHolder(target, replacement,
150                                                        true);
151 }
152
153 };  // namespace sidestep
154
155 #endif  // CEEE_TESTING_SIDESTEP_AUTO_TESTING_HOOK_H_