Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(797)

Side by Side Diff: base/callback_internal.h

Issue 1129353003: Devirtualize base::BindState to save ~1% of Chrome's binary size (~1MB) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@20150507-SizesExplorations
Patch Set: This old trap Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/callback.h ('k') | base/callback_internal.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file contains utility functions and classes that help the 5 // This file contains utility functions and classes that help the
6 // implementation, and management of the Callback objects. 6 // implementation, and management of the Callback objects.
7 7
8 #ifndef BASE_CALLBACK_INTERNAL_H_ 8 #ifndef BASE_CALLBACK_INTERNAL_H_
9 #define BASE_CALLBACK_INTERNAL_H_ 9 #define BASE_CALLBACK_INTERNAL_H_
10 10
11 #include <stddef.h> 11 #include "base/atomic_ref_count.h"
12
13 #include "base/base_export.h" 12 #include "base/base_export.h"
14 #include "base/memory/ref_counted.h" 13 #include "base/macros.h"
15 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/ref_counted.h" // TODO(tapted): Remove.
15 #include "base/memory/scoped_ptr.h" // TODO(tapted): Remove.
tapted 2015/05/11 07:17:44 ref_counted and scoped_ptr are no longer needed, b
16 #include "base/template_util.h"
16 17
17 template <typename T> 18 template <typename T>
18 class ScopedVector; 19 class ScopedVector;
19 20
20 namespace base { 21 namespace base {
21 namespace internal { 22 namespace internal {
23 class CallbackBase;
22 24
23 // BindStateBase is used to provide an opaque handle that the Callback 25 // BindStateBase is used to provide an opaque handle that the Callback
24 // class can use to represent a function object with bound arguments. It 26 // class can use to represent a function object with bound arguments. It
25 // behaves as an existential type that is used by a corresponding 27 // behaves as an existential type that is used by a corresponding
26 // DoInvoke function to perform the function execution. This allows 28 // DoInvoke function to perform the function execution. This allows
27 // us to shield the Callback class from the types of the bound argument via 29 // us to shield the Callback class from the types of the bound argument via
28 // "type erasure." 30 // "type erasure."
29 class BindStateBase : public RefCountedThreadSafe<BindStateBase> { 31 // At the base level, the only task is to add reference counting data. Don't use
32 // RefCountedThreadSafe since it requires the destructor to be a virtual method.
33 // Creating a vtable for every BindState template instantiation results in a lot
34 // of bloat. Its only task is to call the destructor which can be done with a
35 // function pointer.
36 class BindStateBase {
30 protected: 37 protected:
31 friend class RefCountedThreadSafe<BindStateBase>; 38 explicit BindStateBase(void (*destructor)(BindStateBase*))
32 virtual ~BindStateBase() {} 39 : ref_count_(0), destructor_(destructor) {}
40 ~BindStateBase() = default;
41
42 private:
43 // Only CallbackBase ever calls AddRef/Release.
44 friend class CallbackBase;
45
46 void AddRef();
47 void Release();
48
49 AtomicRefCount ref_count_;
50
51 // Pointer to a function that will properly destroy |this|. Use a regular
52 // function pointer, since their representation is often simpler/smaller than
53 // member function pointer types and it's not possible to take the address of
54 // a class destructor anyway.
55 void (*destructor_)(BindStateBase*);
56
57 DISALLOW_COPY_AND_ASSIGN(BindStateBase);
33 }; 58 };
34 59
35 // Holds the Callback methods that don't require specialization to reduce 60 // Holds the Callback methods that don't require specialization to reduce
36 // template bloat. 61 // template bloat.
37 class BASE_EXPORT CallbackBase { 62 class BASE_EXPORT CallbackBase {
38 public: 63 public:
39 CallbackBase(const CallbackBase& c);
40 CallbackBase& operator=(const CallbackBase& c);
41
42 // Returns true if Callback is null (doesn't refer to anything). 64 // Returns true if Callback is null (doesn't refer to anything).
43 bool is_null() const { return bind_state_.get() == NULL; } 65 bool is_null() const { return bind_state_ == nullptr; }
44 66
45 // Returns the Callback into an uninitialized state. 67 // Returns the Callback into an uninitialized state.
46 void Reset(); 68 void Reset();
47 69
48 protected: 70 protected:
49 // In C++, it is safe to cast function pointers to function pointers of 71 // In C++, it is safe to cast function pointers to function pointers of
50 // another type. It is not okay to use void*. We create a InvokeFuncStorage 72 // another type. It is not okay to use void*. We create a InvokeFuncStorage
51 // that that can store our function pointer, and then cast it back to 73 // that that can store our function pointer, and then cast it back to
52 // the original type on usage. 74 // the original type on usage.
53 typedef void(*InvokeFuncStorage)(void); 75 typedef void(*InvokeFuncStorage)(void);
54 76
55 // Returns true if this callback equals |other|. |other| may be null. 77 // Returns true if this callback equals |other|. |other| may be null.
56 bool Equals(const CallbackBase& other) const; 78 bool Equals(const CallbackBase& other) const;
57 79
58 // Allow initializing of |bind_state_| via the constructor to avoid default 80 // The default constructor is only used by Callback's default constructor.
59 // initialization of the scoped_refptr. We do not also initialize 81 CallbackBase();
60 // |polymorphic_invoke_| here because doing a normal assignment in the 82
61 // derived Callback templates makes for much nicer compiler errors. 83 // Allow initializing of |bind_state_| via the constructor. We do not also
84 // initialize |polymorphic_invoke_| here because doing a normal assignment in
85 // the derived Callback templates makes for much nicer compiler errors.
62 explicit CallbackBase(BindStateBase* bind_state); 86 explicit CallbackBase(BindStateBase* bind_state);
63 87
88 CallbackBase(const CallbackBase& c);
89 CallbackBase& operator=(const CallbackBase& c);
90
64 // Force the destructor to be instantiated inside this translation unit so 91 // Force the destructor to be instantiated inside this translation unit so
65 // that our subclasses will not get inlined versions. Avoids more template 92 // that our subclasses will not get inlined versions. Avoids more template
66 // bloat. 93 // bloat.
67 ~CallbackBase(); 94 ~CallbackBase();
68 95
69 scoped_refptr<BindStateBase> bind_state_; 96 BindStateBase* bind_state_;
70 InvokeFuncStorage polymorphic_invoke_; 97 InvokeFuncStorage polymorphic_invoke_;
71 }; 98 };
72 99
73 // A helper template to determine if given type is non-const move-only-type, 100 // A helper template to determine if given type is non-const move-only-type,
74 // i.e. if a value of the given type should be passed via .Pass() in a 101 // i.e. if a value of the given type should be passed via .Pass() in a
75 // destructive way. 102 // destructive way.
76 template <typename T> struct IsMoveOnlyType { 103 template <typename T> struct IsMoveOnlyType {
77 template <typename U> 104 template <typename U>
78 static YesType Test(const typename U::MoveOnlyTypeForCPP03*); 105 static YesType Test(const typename U::MoveOnlyTypeForCPP03*);
79 106
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 228
202 template <typename T> 229 template <typename T>
203 typename enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward(T& t) { 230 typename enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward(T& t) {
204 return t.Pass(); 231 return t.Pass();
205 } 232 }
206 233
207 } // namespace internal 234 } // namespace internal
208 } // namespace base 235 } // namespace base
209 236
210 #endif // BASE_CALLBACK_INTERNAL_H_ 237 #endif // BASE_CALLBACK_INTERNAL_H_
OLDNEW
« no previous file with comments | « base/callback.h ('k') | base/callback_internal.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698