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.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 { kNotShared, kShared }; 18 19 class JSArrayBuffer : public JSObject { 20 public: 21 // [byte_length]: length in bytes 22 DECL_ACCESSORS(byte_length, Object) 23 24 // [backing_store]: backing memory for this array 25 DECL_ACCESSORS(backing_store, void) 26 27 // For non-wasm, allocation_length and allocation_base are byte_length and 28 // backing_store, respectively. 29 inline size_t allocation_length() const; 30 inline void* allocation_base() const; 31 32 inline uint32_t bit_field() const; 33 inline void set_bit_field(uint32_t bits); 34 35 // [is_external]: true indicates that the embedder is in charge of freeing the 36 // backing_store, while is_external == false means that v8 will free the 37 // memory block once all ArrayBuffers referencing it are collected by the GC. 38 inline bool is_external(); 39 inline void set_is_external(bool value); 40 41 inline bool is_neuterable(); 42 inline void set_is_neuterable(bool value); 43 44 inline bool was_neutered(); 45 inline void set_was_neutered(bool value); 46 47 inline bool is_shared(); 48 inline void set_is_shared(bool value); 49 50 inline bool is_growable(); 51 inline void set_is_growable(bool value); 52 53 DECL_CAST(JSArrayBuffer) 54 55 void Neuter(); 56 57 struct Allocation { AllocationAllocation58 Allocation(void* allocation_base, size_t length, void* backing_store, 59 bool is_wasm_memory) 60 : allocation_base(allocation_base), 61 length(length), 62 backing_store(backing_store), 63 is_wasm_memory(is_wasm_memory) {} 64 65 void* allocation_base; 66 size_t length; 67 void* backing_store; 68 bool is_wasm_memory; 69 }; 70 71 // Returns whether the buffer is tracked by the WasmMemoryTracker. 72 inline bool is_wasm_memory() const; 73 74 // Sets whether the buffer is tracked by the WasmMemoryTracker. 75 void set_is_wasm_memory(bool is_wasm_memory); 76 77 // Removes the backing store from the WasmMemoryTracker and sets 78 // |is_wasm_memory| to false. 79 void StopTrackingWasmMemory(Isolate* isolate); 80 81 void FreeBackingStoreFromMainThread(); 82 static void FreeBackingStore(Isolate* isolate, Allocation allocation); 83 84 V8_EXPORT_PRIVATE static void Setup( 85 Handle<JSArrayBuffer> array_buffer, Isolate* isolate, bool is_external, 86 void* data, size_t allocated_length, 87 SharedFlag shared = SharedFlag::kNotShared, bool is_wasm_memory = false); 88 89 // Returns false if array buffer contents could not be allocated. 90 // In this case, |array_buffer| will not be set up. 91 static bool SetupAllocatingData( 92 Handle<JSArrayBuffer> array_buffer, Isolate* isolate, 93 size_t allocated_length, bool initialize = true, 94 SharedFlag shared = SharedFlag::kNotShared) V8_WARN_UNUSED_RESULT; 95 96 // Dispatched behavior. 97 DECL_PRINTER(JSArrayBuffer) 98 DECL_VERIFIER(JSArrayBuffer) 99 100 static const int kByteLengthOffset = JSObject::kHeaderSize; 101 // The rest of the fields are not JSObjects, so they are not iterated over in 102 // objects-body-descriptors-inl.h. 103 static const int kBackingStoreOffset = kByteLengthOffset + kPointerSize; 104 static const int kBitFieldSlot = kBackingStoreOffset + kPointerSize; 105 #if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT 106 static const int kBitFieldOffset = kBitFieldSlot; 107 #else 108 static const int kBitFieldOffset = kBitFieldSlot + kInt32Size; 109 #endif 110 static const int kSize = kBitFieldSlot + kPointerSize; 111 112 static const int kSizeWithEmbedderFields = 113 kSize + v8::ArrayBuffer::kEmbedderFieldCount * kPointerSize; 114 115 // Iterates all fields in the object including internal ones except 116 // kBackingStoreOffset and kBitFieldSlot. 117 class BodyDescriptor; 118 // No weak fields. 119 typedef BodyDescriptor BodyDescriptorWeak; 120 121 class IsExternal : public BitField<bool, 1, 1> {}; 122 class IsNeuterable : public BitField<bool, 2, 1> {}; 123 class WasNeutered : public BitField<bool, 3, 1> {}; 124 class IsShared : public BitField<bool, 4, 1> {}; 125 class IsGrowable : public BitField<bool, 5, 1> {}; 126 class IsWasmMemory : public BitField<bool, 6, 1> {}; 127 128 private: 129 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer); 130 }; 131 132 class JSArrayBufferView : public JSObject { 133 public: 134 // [buffer]: ArrayBuffer that this typed array views. 135 DECL_ACCESSORS(buffer, Object) 136 137 // [byte_offset]: offset of typed array in bytes. 138 DECL_ACCESSORS(byte_offset, Object) 139 140 // [byte_length]: length of typed array in bytes. 141 DECL_ACCESSORS(byte_length, Object) 142 143 DECL_CAST(JSArrayBufferView) 144 145 DECL_VERIFIER(JSArrayBufferView) 146 147 inline bool WasNeutered() const; 148 149 static const int kBufferOffset = JSObject::kHeaderSize; 150 static const int kByteOffsetOffset = kBufferOffset + kPointerSize; 151 static const int kByteLengthOffset = kByteOffsetOffset + kPointerSize; 152 static const int kViewSize = kByteLengthOffset + kPointerSize; 153 154 private: 155 #ifdef VERIFY_HEAP 156 DECL_ACCESSORS(raw_byte_offset, Object) 157 DECL_ACCESSORS(raw_byte_length, Object) 158 #endif 159 160 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBufferView); 161 }; 162 163 class JSTypedArray : public JSArrayBufferView { 164 public: 165 // [length]: length of typed array in elements. 166 DECL_ACCESSORS(length, Object) 167 inline size_t length_value() const; 168 169 // ES6 9.4.5.3 170 V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty( 171 Isolate* isolate, Handle<JSTypedArray> o, Handle<Object> key, 172 PropertyDescriptor* desc, ShouldThrow should_throw); 173 174 DECL_CAST(JSTypedArray) 175 176 ExternalArrayType type(); 177 V8_EXPORT_PRIVATE size_t element_size(); 178 179 Handle<JSArrayBuffer> GetBuffer(); 180 181 // Whether the buffer's backing store is on-heap or off-heap. 182 inline bool is_on_heap() const; 183 184 static inline MaybeHandle<JSTypedArray> Validate(Isolate* isolate, 185 Handle<Object> receiver, 186 const char* method_name); 187 188 // Dispatched behavior. 189 DECL_PRINTER(JSTypedArray) 190 DECL_VERIFIER(JSTypedArray) 191 192 static const int kLengthOffset = kViewSize; 193 static const int kSize = kLengthOffset + kPointerSize; 194 195 static const int kSizeWithEmbedderFields = 196 kSize + v8::ArrayBufferView::kEmbedderFieldCount * kPointerSize; 197 198 private: 199 static Handle<JSArrayBuffer> MaterializeArrayBuffer( 200 Handle<JSTypedArray> typed_array); 201 #ifdef VERIFY_HEAP 202 DECL_ACCESSORS(raw_length, Object) 203 #endif 204 205 DISALLOW_IMPLICIT_CONSTRUCTORS(JSTypedArray); 206 }; 207 208 class JSDataView : public JSArrayBufferView { 209 public: 210 DECL_CAST(JSDataView) 211 212 // Dispatched behavior. 213 DECL_PRINTER(JSDataView) 214 DECL_VERIFIER(JSDataView) 215 216 static const int kSize = kViewSize; 217 218 static const int kSizeWithEmbedderFields = 219 kSize + v8::ArrayBufferView::kEmbedderFieldCount * kPointerSize; 220 221 private: 222 DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataView); 223 }; 224 225 } // namespace internal 226 } // namespace v8 227 228 #include "src/objects/object-macros-undef.h" 229 230 #endif // V8_OBJECTS_JS_ARRAY_BUFFER_H_ 231