OLD | NEW |
1 /* | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 * Copyright (C) 2009 Apple Inc. All rights reserved. | 2 // Use of this source code is governed by a BSD-style license that can be |
3 * Copyright (C) 2013 Google Inc. All rights reserved. | 3 // found in the LICENSE file. |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions | |
7 * are met: | |
8 * 1. Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * 2. Redistributions in binary form must reproduce the above copyright | |
11 * notice, this list of conditions and the following disclaimer in the | |
12 * documentation and/or other materials provided with the distribution. | |
13 * | |
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | |
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
25 */ | |
26 | 4 |
27 #ifndef ArrayBufferContents_h | 5 #include "platform/wtf/typed_arrays/ArrayBufferContents.h" |
28 #define ArrayBufferContents_h | |
29 | 6 |
30 #include "wtf/Allocator.h" | 7 // The contents of this header was moved to platform/wtf as part of |
31 #include "wtf/Assertions.h" | 8 // WTF migration project. See the following post for details: |
32 #include "wtf/Noncopyable.h" | 9 // https://groups.google.com/a/chromium.org/d/msg/blink-dev/tLdAZCTlcAA/bYXVT8gY
CAAJ |
33 #include "wtf/RefPtr.h" | |
34 #include "wtf/ThreadSafeRefCounted.h" | |
35 #include "wtf/WTF.h" | |
36 #include "wtf/WTFExport.h" | |
37 | |
38 namespace WTF { | |
39 | |
40 class WTF_EXPORT ArrayBufferContents { | |
41 WTF_MAKE_NONCOPYABLE(ArrayBufferContents); | |
42 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); | |
43 | |
44 public: | |
45 using AdjustAmountOfExternalAllocatedMemoryFunction = void (*)(int64_t diff); | |
46 // Types that need to be used when injecting external memory. | |
47 // DataHandle allows specifying a deleter which will be invoked when | |
48 // DataHandle instance goes out of scope. If the data memory is allocated | |
49 // using ArrayBufferContents::allocateMemoryOrNull, it is necessary to | |
50 // specify ArrayBufferContents::freeMemory as the DataDeleter. | |
51 // Most clients would want to use ArrayBufferContents::createData, which | |
52 // allocates memory and specifies the correct deleter. | |
53 using DataDeleter = void (*)(void* data); | |
54 using DataHandle = std::unique_ptr<void, DataDeleter>; | |
55 | |
56 enum InitializationPolicy { ZeroInitialize, DontInitialize }; | |
57 | |
58 enum SharingType { | |
59 NotShared, | |
60 Shared, | |
61 }; | |
62 | |
63 ArrayBufferContents(); | |
64 ArrayBufferContents(unsigned numElements, | |
65 unsigned elementByteSize, | |
66 SharingType isShared, | |
67 InitializationPolicy); | |
68 ArrayBufferContents(DataHandle, unsigned sizeInBytes, SharingType isShared); | |
69 | |
70 ~ArrayBufferContents(); | |
71 | |
72 void neuter(); | |
73 | |
74 void* data() const { | |
75 DCHECK(!isShared()); | |
76 return dataMaybeShared(); | |
77 } | |
78 void* dataShared() const { | |
79 DCHECK(isShared()); | |
80 return dataMaybeShared(); | |
81 } | |
82 void* dataMaybeShared() const { | |
83 return m_holder ? m_holder->data() : nullptr; | |
84 } | |
85 unsigned sizeInBytes() const { | |
86 return m_holder ? m_holder->sizeInBytes() : 0; | |
87 } | |
88 bool isShared() const { return m_holder ? m_holder->isShared() : false; } | |
89 | |
90 void transfer(ArrayBufferContents& other); | |
91 void shareWith(ArrayBufferContents& other); | |
92 void copyTo(ArrayBufferContents& other); | |
93 | |
94 static void* allocateMemoryOrNull(size_t, InitializationPolicy); | |
95 static void freeMemory(void*); | |
96 static DataHandle createDataHandle(size_t, InitializationPolicy); | |
97 static void initialize( | |
98 AdjustAmountOfExternalAllocatedMemoryFunction function) { | |
99 DCHECK(isMainThread()); | |
100 DCHECK_EQ(s_adjustAmountOfExternalAllocatedMemoryFunction, | |
101 defaultAdjustAmountOfExternalAllocatedMemoryFunction); | |
102 s_adjustAmountOfExternalAllocatedMemoryFunction = function; | |
103 } | |
104 | |
105 void registerExternalAllocationWithCurrentContext() { | |
106 if (m_holder) | |
107 m_holder->registerExternalAllocationWithCurrentContext(); | |
108 } | |
109 | |
110 void unregisterExternalAllocationWithCurrentContext() { | |
111 if (m_holder) | |
112 m_holder->unregisterExternalAllocationWithCurrentContext(); | |
113 } | |
114 | |
115 private: | |
116 static void* allocateMemoryWithFlags(size_t, InitializationPolicy, int); | |
117 | |
118 static void defaultAdjustAmountOfExternalAllocatedMemoryFunction( | |
119 int64_t diff); | |
120 | |
121 class DataHolder : public ThreadSafeRefCounted<DataHolder> { | |
122 WTF_MAKE_NONCOPYABLE(DataHolder); | |
123 | |
124 public: | |
125 DataHolder(); | |
126 ~DataHolder(); | |
127 | |
128 void allocateNew(unsigned sizeInBytes, | |
129 SharingType isShared, | |
130 InitializationPolicy); | |
131 void adopt(DataHandle, unsigned sizeInBytes, SharingType isShared); | |
132 void copyMemoryFrom(const DataHolder& source); | |
133 | |
134 const void* data() const { return m_data.get(); } | |
135 void* data() { return m_data.get(); } | |
136 unsigned sizeInBytes() const { return m_sizeInBytes; } | |
137 bool isShared() const { return m_isShared == Shared; } | |
138 | |
139 void registerExternalAllocationWithCurrentContext(); | |
140 void unregisterExternalAllocationWithCurrentContext(); | |
141 | |
142 private: | |
143 void adjustAmountOfExternalAllocatedMemory(int64_t diff) { | |
144 m_hasRegisteredExternalAllocation = !m_hasRegisteredExternalAllocation; | |
145 DCHECK(!diff || (m_hasRegisteredExternalAllocation == (diff > 0))); | |
146 checkIfAdjustAmountOfExternalAllocatedMemoryIsConsistent(); | |
147 s_adjustAmountOfExternalAllocatedMemoryFunction(diff); | |
148 } | |
149 | |
150 void adjustAmountOfExternalAllocatedMemory(unsigned diff) { | |
151 adjustAmountOfExternalAllocatedMemory(static_cast<int64_t>(diff)); | |
152 } | |
153 | |
154 void checkIfAdjustAmountOfExternalAllocatedMemoryIsConsistent() { | |
155 DCHECK(s_adjustAmountOfExternalAllocatedMemoryFunction); | |
156 | |
157 #if DCHECK_IS_ON() | |
158 // Make sure that the function actually used is always the same. | |
159 // Shouldn't be updated during its use. | |
160 if (!s_lastUsedAdjustAmountOfExternalAllocatedMemoryFunction) { | |
161 s_lastUsedAdjustAmountOfExternalAllocatedMemoryFunction = | |
162 s_adjustAmountOfExternalAllocatedMemoryFunction; | |
163 } | |
164 DCHECK_EQ(s_adjustAmountOfExternalAllocatedMemoryFunction, | |
165 s_lastUsedAdjustAmountOfExternalAllocatedMemoryFunction); | |
166 #endif | |
167 } | |
168 | |
169 DataHandle m_data; | |
170 unsigned m_sizeInBytes; | |
171 SharingType m_isShared; | |
172 bool m_hasRegisteredExternalAllocation; | |
173 }; | |
174 | |
175 RefPtr<DataHolder> m_holder; | |
176 static AdjustAmountOfExternalAllocatedMemoryFunction | |
177 s_adjustAmountOfExternalAllocatedMemoryFunction; | |
178 #if DCHECK_IS_ON() | |
179 static AdjustAmountOfExternalAllocatedMemoryFunction | |
180 s_lastUsedAdjustAmountOfExternalAllocatedMemoryFunction; | |
181 #endif | |
182 }; | |
183 | |
184 } // namespace WTF | |
185 | |
186 #endif // ArrayBufferContents_h | |
OLD | NEW |