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(IsWasmMemoryBit, bool, 1, _)
56 : DEFINE_BIT_FIELDS(JS_ARRAY_BUFFER_BIT_FIELD_FIELDS)
57 : #undef JS_ARRAY_BUFFER_BIT_FIELD_FIELDS
58 :
59 : // [is_external]: true indicates that the embedder is in charge of freeing the
60 : // backing_store, while is_external == false means that v8 will free the
61 : // memory block once all ArrayBuffers referencing it are collected by the GC.
62 : DECL_BOOLEAN_ACCESSORS(is_external)
63 :
64 : // [is_detachable]: false indicates that this buffer cannot be detached.
65 : DECL_BOOLEAN_ACCESSORS(is_detachable)
66 :
67 : // [was_detached]: true if the buffer was previously detached.
68 : DECL_BOOLEAN_ACCESSORS(was_detached)
69 :
70 : // [is_shared]: tells whether this is an ArrayBuffer or a SharedArrayBuffer.
71 : DECL_BOOLEAN_ACCESSORS(is_shared)
72 :
73 : // [is_wasm_memory]: whether the buffer is tracked by the WasmMemoryTracker.
74 : DECL_BOOLEAN_ACCESSORS(is_wasm_memory)
75 :
76 : DECL_CAST(JSArrayBuffer)
77 :
78 : void Detach();
79 :
80 : struct Allocation {
81 : Allocation(void* allocation_base, size_t length, void* backing_store,
82 : bool is_wasm_memory)
83 : : allocation_base(allocation_base),
84 : length(length),
85 : backing_store(backing_store),
86 550794 : is_wasm_memory(is_wasm_memory) {}
87 :
88 : void* allocation_base;
89 : size_t length;
90 : void* backing_store;
91 : bool is_wasm_memory;
92 : };
93 :
94 : V8_EXPORT_PRIVATE void FreeBackingStoreFromMainThread();
95 : V8_EXPORT_PRIVATE static void FreeBackingStore(Isolate* isolate,
96 : Allocation allocation);
97 :
98 : V8_EXPORT_PRIVATE static void Setup(
99 : Handle<JSArrayBuffer> array_buffer, Isolate* isolate, bool is_external,
100 : void* data, size_t allocated_length,
101 : SharedFlag shared_flag = SharedFlag::kNotShared,
102 : bool is_wasm_memory = false);
103 :
104 : // Initialize the object as empty one to avoid confusing heap verifier if
105 : // the failure happened in the middle of JSArrayBuffer construction.
106 : V8_EXPORT_PRIVATE static void SetupAsEmpty(Handle<JSArrayBuffer> array_buffer,
107 : Isolate* isolate);
108 :
109 : // Returns false if array buffer contents could not be allocated.
110 : // In this case, |array_buffer| will not be set up.
111 : V8_EXPORT_PRIVATE static bool SetupAllocatingData(
112 : Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
113 : size_t allocated_length, bool initialize = true,
114 : SharedFlag shared_flag = SharedFlag::kNotShared) V8_WARN_UNUSED_RESULT;
115 :
116 : // Dispatched behavior.
117 : DECL_PRINTER(JSArrayBuffer)
118 : DECL_VERIFIER(JSArrayBuffer)
119 :
120 : // Layout description.
121 : #define JS_ARRAY_BUFFER_FIELDS(V) \
122 : V(kEndOfTaggedFieldsOffset, 0) \
123 : /* Raw data fields. */ \
124 : V(kByteLengthOffset, kUIntptrSize) \
125 : V(kBackingStoreOffset, kSystemPointerSize) \
126 : V(kBitFieldOffset, kInt32Size) \
127 : /* Pads header size to be a multiple of kTaggedSize. */ \
128 : V(kOptionalPaddingOffset, OBJECT_POINTER_PADDING(kOptionalPaddingOffset)) \
129 : /* Header size. */ \
130 : V(kHeaderSize, 0)
131 :
132 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_ARRAY_BUFFER_FIELDS)
133 : #undef JS_ARRAY_BUFFER_FIELDS
134 :
135 : static const int kSizeWithEmbedderFields =
136 : kHeaderSize +
137 : v8::ArrayBuffer::kEmbedderFieldCount * kEmbedderDataSlotSize;
138 :
139 : class BodyDescriptor;
140 :
141 : OBJECT_CONSTRUCTORS(JSArrayBuffer, JSObject);
142 : };
143 :
144 : class JSArrayBufferView : public JSObject {
145 : public:
146 : // [buffer]: ArrayBuffer that this typed array views.
147 : DECL_ACCESSORS(buffer, Object)
148 :
149 : // [byte_offset]: offset of typed array in bytes.
150 : DECL_PRIMITIVE_ACCESSORS(byte_offset, size_t)
151 :
152 : // [byte_length]: length of typed array in bytes.
153 : DECL_PRIMITIVE_ACCESSORS(byte_length, size_t)
154 :
155 : DECL_CAST(JSArrayBufferView)
156 :
157 : DECL_VERIFIER(JSArrayBufferView)
158 :
159 : inline bool WasDetached() const;
160 :
161 : // Layout description.
162 : #define JS_ARRAY_BUFFER_VIEW_FIELDS(V) \
163 : V(kBufferOffset, kTaggedSize) \
164 : V(kEndOfTaggedFieldsOffset, 0) \
165 : /* Raw data fields. */ \
166 : V(kByteOffsetOffset, kUIntptrSize) \
167 : V(kByteLengthOffset, kUIntptrSize) \
168 : /* Header size. */ \
169 : V(kHeaderSize, 0)
170 :
171 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
172 : JS_ARRAY_BUFFER_VIEW_FIELDS)
173 : #undef JS_ARRAY_BUFFER_VIEW_FIELDS
174 :
175 : class BodyDescriptor;
176 :
177 : OBJECT_CONSTRUCTORS(JSArrayBufferView, JSObject);
178 : };
179 :
180 : class JSTypedArray : public JSArrayBufferView {
181 : public:
182 : // [length]: length of typed array in elements.
183 : DECL_PRIMITIVE_ACCESSORS(length, size_t)
184 :
185 : // ES6 9.4.5.3
186 : V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty(
187 : Isolate* isolate, Handle<JSTypedArray> o, Handle<Object> key,
188 : PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw);
189 :
190 : DECL_CAST(JSTypedArray)
191 :
192 : ExternalArrayType type();
193 : V8_EXPORT_PRIVATE size_t element_size();
194 :
195 : V8_EXPORT_PRIVATE Handle<JSArrayBuffer> GetBuffer();
196 :
197 : // Whether the buffer's backing store is on-heap or off-heap.
198 : inline bool is_on_heap() const;
199 :
200 : static inline MaybeHandle<JSTypedArray> Validate(Isolate* isolate,
201 : Handle<Object> receiver,
202 : const char* method_name);
203 :
204 : // Dispatched behavior.
205 : DECL_PRINTER(JSTypedArray)
206 : DECL_VERIFIER(JSTypedArray)
207 :
208 : // Layout description.
209 : #define JS_TYPED_ARRAY_FIELDS(V) \
210 : /* Raw data fields. */ \
211 : V(kLengthOffset, kTaggedSize) \
212 : /* Header size. */ \
213 : V(kHeaderSize, 0)
214 :
215 : DEFINE_FIELD_OFFSET_CONSTANTS(JSArrayBufferView::kHeaderSize,
216 : JS_TYPED_ARRAY_FIELDS)
217 : #undef JS_TYPED_ARRAY_FIELDS
218 :
219 : static const int kSizeWithEmbedderFields =
220 : kHeaderSize +
221 : v8::ArrayBufferView::kEmbedderFieldCount * kEmbedderDataSlotSize;
222 :
223 : private:
224 : static Handle<JSArrayBuffer> MaterializeArrayBuffer(
225 : Handle<JSTypedArray> typed_array);
226 :
227 : DECL_ACCESSORS(raw_length, Object)
228 :
229 : OBJECT_CONSTRUCTORS(JSTypedArray, JSArrayBufferView);
230 : };
231 :
232 : class JSDataView : public JSArrayBufferView {
233 : public:
234 : DECL_CAST(JSDataView)
235 :
236 : // Dispatched behavior.
237 : DECL_PRINTER(JSDataView)
238 : DECL_VERIFIER(JSDataView)
239 :
240 : // Layout description.
241 : static const int kSizeWithEmbedderFields =
242 : kHeaderSize +
243 : v8::ArrayBufferView::kEmbedderFieldCount * kEmbedderDataSlotSize;
244 :
245 : OBJECT_CONSTRUCTORS(JSDataView, JSArrayBufferView);
246 : };
247 :
248 : } // namespace internal
249 : } // namespace v8
250 :
251 : #include "src/objects/object-macros-undef.h"
252 :
253 : #endif // V8_OBJECTS_JS_ARRAY_BUFFER_H_
|