Line data Source code
1 : // Copyright 2018 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_OBJECTS_JS_ARRAY_BUFFER_H_
6 : #define V8_OBJECTS_JS_ARRAY_BUFFER_H_
7 :
8 : #include "src/objects/js-objects.h"
9 :
10 : // Has to be the last include (doesn't have include guards):
11 : #include "src/objects/object-macros.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 : // Whether a JSArrayBuffer is a SharedArrayBuffer or not.
17 : enum class SharedFlag : uint32_t { kNotShared, kShared };
18 :
19 : class JSArrayBuffer : public JSObject {
20 : public:
21 : // The maximum length for JSArrayBuffer's supported by V8.
22 : // On 32-bit architectures we limit this to 2GiB, so that
23 : // we can continue to use CheckBounds with the Unsigned31
24 : // restriction for the length.
25 : #if V8_HOST_ARCH_32_BIT
26 : static constexpr size_t kMaxByteLength = kMaxInt;
27 : #else
28 : static constexpr size_t kMaxByteLength = kMaxSafeInteger;
29 : #endif
30 :
31 : // [byte_length]: length in bytes
32 : DECL_PRIMITIVE_ACCESSORS(byte_length, size_t)
33 :
34 : // [backing_store]: backing memory for this array
35 : DECL_ACCESSORS(backing_store, void*)
36 :
37 : // For non-wasm, allocation_length and allocation_base are byte_length and
38 : // backing_store, respectively.
39 : inline size_t allocation_length() const;
40 : inline void* allocation_base() const;
41 :
42 : // [bit_field]: boolean flags
43 : DECL_PRIMITIVE_ACCESSORS(bit_field, uint32_t)
44 :
45 : // Clear uninitialized padding space. This ensures that the snapshot content
46 : // is deterministic. Depending on the V8 build mode there could be no padding.
47 : V8_INLINE void clear_padding();
48 :
49 : // Bit positions for [bit_field].
50 : #define JS_ARRAY_BUFFER_BIT_FIELD_FIELDS(V, _) \
51 : V(IsExternalBit, bool, 1, _) \
52 : V(IsDetachableBit, bool, 1, _) \
53 : V(WasDetachedBit, bool, 1, _) \
54 : V(IsSharedBit, bool, 1, _) \
55 : V(IsGrowableBit, bool, 1, _) \
56 : V(IsWasmMemoryBit, bool, 1, _)
57 : DEFINE_BIT_FIELDS(JS_ARRAY_BUFFER_BIT_FIELD_FIELDS)
58 : #undef JS_ARRAY_BUFFER_BIT_FIELD_FIELDS
59 :
60 : // [is_external]: true indicates that the embedder is in charge of freeing the
61 : // backing_store, while is_external == false means that v8 will free the
62 : // memory block once all ArrayBuffers referencing it are collected by the GC.
63 : DECL_BOOLEAN_ACCESSORS(is_external)
64 :
65 : // [is_detachable]: false indicates that this buffer cannot be detached.
66 : DECL_BOOLEAN_ACCESSORS(is_detachable)
67 :
68 : // [was_detached]: true if the buffer was previously detached.
69 : DECL_BOOLEAN_ACCESSORS(was_detached)
70 :
71 : // [is_shared]: tells whether this is an ArrayBuffer or a SharedArrayBuffer.
72 : DECL_BOOLEAN_ACCESSORS(is_shared)
73 :
74 : // [is_growable]: indicates whether it's possible to grow this buffer.
75 : DECL_BOOLEAN_ACCESSORS(is_growable)
76 :
77 : // [is_wasm_memory]: whether the buffer is tracked by the WasmMemoryTracker.
78 : DECL_BOOLEAN_ACCESSORS(is_wasm_memory)
79 :
80 : DECL_CAST(JSArrayBuffer)
81 :
82 : void Detach();
83 :
84 : struct Allocation {
85 : Allocation(void* allocation_base, size_t length, void* backing_store,
86 : bool is_wasm_memory)
87 : : allocation_base(allocation_base),
88 : length(length),
89 : backing_store(backing_store),
90 506817 : is_wasm_memory(is_wasm_memory) {}
91 :
92 : void* allocation_base;
93 : size_t length;
94 : void* backing_store;
95 : bool is_wasm_memory;
96 : };
97 :
98 : void FreeBackingStoreFromMainThread();
99 : static void FreeBackingStore(Isolate* isolate, Allocation allocation);
100 :
101 : V8_EXPORT_PRIVATE static void Setup(
102 : Handle<JSArrayBuffer> array_buffer, Isolate* isolate, bool is_external,
103 : void* data, size_t allocated_length,
104 : SharedFlag shared_flag = SharedFlag::kNotShared,
105 : bool is_wasm_memory = false);
106 :
107 : // Initialize the object as empty one to avoid confusing heap verifier if
108 : // the failure happened in the middle of JSArrayBuffer construction.
109 : V8_EXPORT_PRIVATE static void SetupAsEmpty(Handle<JSArrayBuffer> array_buffer,
110 : Isolate* isolate);
111 :
112 : // Returns false if array buffer contents could not be allocated.
113 : // In this case, |array_buffer| will not be set up.
114 : static bool SetupAllocatingData(
115 : Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
116 : size_t allocated_length, bool initialize = true,
117 : SharedFlag shared_flag = SharedFlag::kNotShared) V8_WARN_UNUSED_RESULT;
118 :
119 : // Dispatched behavior.
120 : DECL_PRINTER(JSArrayBuffer)
121 : DECL_VERIFIER(JSArrayBuffer)
122 :
123 : // Layout description.
124 : #define JS_ARRAY_BUFFER_FIELDS(V) \
125 : V(kEndOfTaggedFieldsOffset, 0) \
126 : /* Raw data fields. */ \
127 : V(kByteLengthOffset, kUIntptrSize) \
128 : V(kBackingStoreOffset, kSystemPointerSize) \
129 : V(kBitFieldOffset, kInt32Size) \
130 : /* Pads header size to be a multiple of kTaggedSize. */ \
131 : V(kOptionalPaddingOffset, OBJECT_POINTER_PADDING(kOptionalPaddingOffset)) \
132 : /* Header size. */ \
133 : V(kHeaderSize, 0)
134 :
135 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_ARRAY_BUFFER_FIELDS)
136 : #undef JS_ARRAY_BUFFER_FIELDS
137 :
138 : static const int kSizeWithEmbedderFields =
139 : kHeaderSize +
140 : v8::ArrayBuffer::kEmbedderFieldCount * kEmbedderDataSlotSize;
141 :
142 : class BodyDescriptor;
143 :
144 20213344 : OBJECT_CONSTRUCTORS(JSArrayBuffer, JSObject);
145 : };
146 :
147 : class JSArrayBufferView : public JSObject {
148 : public:
149 : // [buffer]: ArrayBuffer that this typed array views.
150 : DECL_ACCESSORS(buffer, Object)
151 :
152 : // [byte_offset]: offset of typed array in bytes.
153 : DECL_PRIMITIVE_ACCESSORS(byte_offset, size_t)
154 :
155 : // [byte_length]: length of typed array in bytes.
156 : DECL_PRIMITIVE_ACCESSORS(byte_length, size_t)
157 :
158 : DECL_CAST(JSArrayBufferView)
159 :
160 : DECL_VERIFIER(JSArrayBufferView)
161 :
162 : inline bool WasDetached() const;
163 :
164 : // Layout description.
165 : #define JS_ARRAY_BUFFER_VIEW_FIELDS(V) \
166 : V(kBufferOffset, kTaggedSize) \
167 : V(kEndOfTaggedFieldsOffset, 0) \
168 : /* Raw data fields. */ \
169 : V(kByteOffsetOffset, kUIntptrSize) \
170 : V(kByteLengthOffset, kUIntptrSize) \
171 : /* Header size. */ \
172 : V(kHeaderSize, 0)
173 :
174 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
175 : JS_ARRAY_BUFFER_VIEW_FIELDS)
176 : #undef JS_ARRAY_BUFFER_VIEW_FIELDS
177 :
178 : class BodyDescriptor;
179 :
180 : OBJECT_CONSTRUCTORS(JSArrayBufferView, JSObject);
181 : };
182 :
183 : class JSTypedArray : public JSArrayBufferView {
184 : public:
185 : // [length]: length of typed array in elements.
186 : DECL_ACCESSORS(length, Object)
187 : inline size_t length_value() const;
188 :
189 : // ES6 9.4.5.3
190 : V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty(
191 : Isolate* isolate, Handle<JSTypedArray> o, Handle<Object> key,
192 : PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw);
193 :
194 : DECL_CAST(JSTypedArray)
195 :
196 : ExternalArrayType type();
197 : V8_EXPORT_PRIVATE size_t element_size();
198 :
199 : Handle<JSArrayBuffer> GetBuffer();
200 :
201 : // Whether the buffer's backing store is on-heap or off-heap.
202 : inline bool is_on_heap() const;
203 :
204 : static inline MaybeHandle<JSTypedArray> Validate(Isolate* isolate,
205 : Handle<Object> receiver,
206 : const char* method_name);
207 :
208 : // Dispatched behavior.
209 : DECL_PRINTER(JSTypedArray)
210 : DECL_VERIFIER(JSTypedArray)
211 :
212 : // Layout description.
213 : #define JS_TYPED_ARRAY_FIELDS(V) \
214 : /* Raw data fields. */ \
215 : V(kLengthOffset, kSystemPointerSize) \
216 : /* Header size. */ \
217 : V(kHeaderSize, 0)
218 :
219 : DEFINE_FIELD_OFFSET_CONSTANTS(JSArrayBufferView::kHeaderSize,
220 : JS_TYPED_ARRAY_FIELDS)
221 : #undef JS_TYPED_ARRAY_FIELDS
222 :
223 : static const int kSizeWithEmbedderFields =
224 : kHeaderSize +
225 : v8::ArrayBufferView::kEmbedderFieldCount * kEmbedderDataSlotSize;
226 :
227 : private:
228 : static Handle<JSArrayBuffer> MaterializeArrayBuffer(
229 : Handle<JSTypedArray> typed_array);
230 : #ifdef VERIFY_HEAP
231 : DECL_ACCESSORS(raw_length, Object)
232 : #endif
233 :
234 121185233 : OBJECT_CONSTRUCTORS(JSTypedArray, JSArrayBufferView);
235 : };
236 :
237 : class JSDataView : public JSArrayBufferView {
238 : public:
239 : DECL_CAST(JSDataView)
240 :
241 : // Dispatched behavior.
242 : DECL_PRINTER(JSDataView)
243 : DECL_VERIFIER(JSDataView)
244 :
245 : // Layout description.
246 : static const int kSizeWithEmbedderFields =
247 : kHeaderSize +
248 : v8::ArrayBufferView::kEmbedderFieldCount * kEmbedderDataSlotSize;
249 :
250 : OBJECT_CONSTRUCTORS(JSDataView, JSArrayBufferView);
251 : };
252 :
253 : } // namespace internal
254 : } // namespace v8
255 :
256 : #include "src/objects/object-macros-undef.h"
257 :
258 : #endif // V8_OBJECTS_JS_ARRAY_BUFFER_H_
|