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_INL_H_
6 : #define V8_OBJECTS_JS_ARRAY_BUFFER_INL_H_
7 :
8 : #include "src/objects/js-array-buffer.h"
9 :
10 : #include "src/objects-inl.h" // Needed for write barriers
11 : #include "src/wasm/wasm-engine.h"
12 :
13 : // Has to be the last include (doesn't have include guards):
14 : #include "src/objects/object-macros.h"
15 :
16 : namespace v8 {
17 : namespace internal {
18 :
19 122720176 : OBJECT_CONSTRUCTORS_IMPL(JSArrayBuffer, JSObject)
20 3830518 : OBJECT_CONSTRUCTORS_IMPL(JSArrayBufferView, JSObject)
21 37648212 : OBJECT_CONSTRUCTORS_IMPL(JSTypedArray, JSArrayBufferView)
22 40732 : OBJECT_CONSTRUCTORS_IMPL(JSDataView, JSArrayBufferView)
23 :
24 61360122 : CAST_ACCESSOR(JSArrayBuffer)
25 1915259 : CAST_ACCESSOR(JSArrayBufferView)
26 18824109 : CAST_ACCESSOR(JSTypedArray)
27 20366 : CAST_ACCESSOR(JSDataView)
28 :
29 3362 : size_t JSArrayBuffer::byte_length() const {
30 1278159 : return READ_UINTPTR_FIELD(this, kByteLengthOffset);
31 : }
32 :
33 : void JSArrayBuffer::set_byte_length(size_t value) {
34 456374 : WRITE_UINTPTR_FIELD(this, kByteLengthOffset, value);
35 : }
36 :
37 6436 : void* JSArrayBuffer::backing_store() const {
38 20842117 : intptr_t ptr = READ_INTPTR_FIELD(this, kBackingStoreOffset);
39 20842117 : return reinterpret_cast<void*>(ptr);
40 : }
41 :
42 : void JSArrayBuffer::set_backing_store(void* value, WriteBarrierMode mode) {
43 463916 : intptr_t ptr = reinterpret_cast<intptr_t>(value);
44 469365 : WRITE_INTPTR_FIELD(this, kBackingStoreOffset, ptr);
45 : }
46 :
47 315560 : size_t JSArrayBuffer::allocation_length() const {
48 315560 : if (backing_store() == nullptr) {
49 : return 0;
50 : }
51 : // If this buffer is managed by the WasmMemoryTracker
52 315338 : if (is_wasm_memory()) {
53 : const auto* data =
54 : GetIsolate()->wasm_engine()->memory_tracker()->FindAllocationData(
55 2506 : backing_store());
56 : DCHECK_NOT_NULL(data);
57 2506 : return data->allocation_length;
58 : }
59 312832 : return byte_length();
60 : }
61 :
62 313196 : void* JSArrayBuffer::allocation_base() const {
63 313196 : if (backing_store() == nullptr) {
64 : return nullptr;
65 : }
66 : // If this buffer is managed by the WasmMemoryTracker
67 312974 : if (is_wasm_memory()) {
68 : const auto* data =
69 : GetIsolate()->wasm_engine()->memory_tracker()->FindAllocationData(
70 142 : backing_store());
71 : DCHECK_NOT_NULL(data);
72 142 : return data->allocation_base;
73 : }
74 : return backing_store();
75 : }
76 :
77 : bool JSArrayBuffer::is_wasm_memory() const {
78 : bool const is_wasm_memory = IsWasmMemoryBit::decode(bit_field());
79 : DCHECK_EQ(is_wasm_memory,
80 : GetIsolate()->wasm_engine()->memory_tracker()->IsWasmMemory(
81 : backing_store()));
82 : return is_wasm_memory;
83 : }
84 :
85 : void JSArrayBuffer::set_is_wasm_memory(bool is_wasm_memory) {
86 : set_bit_field(IsWasmMemoryBit::update(bit_field(), is_wasm_memory));
87 : }
88 :
89 : void JSArrayBuffer::clear_padding() {
90 : if (FIELD_SIZE(kOptionalPaddingOffset) != 0) {
91 : DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset));
92 450975 : memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
93 450975 : FIELD_SIZE(kOptionalPaddingOffset));
94 : }
95 : }
96 :
97 : void JSArrayBuffer::set_bit_field(uint32_t bits) {
98 2707586 : WRITE_UINT32_FIELD(this, kBitFieldOffset, bits);
99 : }
100 :
101 : uint32_t JSArrayBuffer::bit_field() const {
102 46141231 : return READ_UINT32_FIELD(this, kBitFieldOffset);
103 : }
104 :
105 : // |bit_field| fields.
106 5968 : BIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_external,
107 : JSArrayBuffer::IsExternalBit)
108 6022 : BIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_detachable,
109 : JSArrayBuffer::IsDetachableBit)
110 : BIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, was_detached,
111 : JSArrayBuffer::WasDetachedBit)
112 37048988 : BIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_shared,
113 : JSArrayBuffer::IsSharedBit)
114 : BIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_growable,
115 : JSArrayBuffer::IsGrowableBit)
116 :
117 18521510 : size_t JSArrayBufferView::byte_offset() const {
118 18526227 : return READ_UINTPTR_FIELD(this, kByteOffsetOffset);
119 : }
120 :
121 : void JSArrayBufferView::set_byte_offset(size_t value) {
122 4400 : WRITE_UINTPTR_FIELD(this, kByteOffsetOffset, value);
123 : }
124 :
125 : size_t JSArrayBufferView::byte_length() const {
126 7407 : return READ_UINTPTR_FIELD(this, kByteLengthOffset);
127 : }
128 :
129 : void JSArrayBufferView::set_byte_length(size_t value) {
130 4400 : WRITE_UINTPTR_FIELD(this, kByteLengthOffset, value);
131 : }
132 :
133 178691083 : ACCESSORS(JSArrayBufferView, buffer, Object, kBufferOffset)
134 :
135 22489179 : bool JSArrayBufferView::WasDetached() const {
136 44978358 : return JSArrayBuffer::cast(buffer())->was_detached();
137 : }
138 :
139 55587878 : Object JSTypedArray::length() const { return READ_FIELD(this, kLengthOffset); }
140 :
141 1737 : size_t JSTypedArray::length_value() const {
142 23348 : double val = length()->Number();
143 : DCHECK_LE(val, kMaxSafeInteger); // 2^53-1
144 : DCHECK_GE(val, -kMaxSafeInteger); // -2^53+1
145 : DCHECK_LE(val, std::numeric_limits<size_t>::max());
146 : DCHECK_GE(val, std::numeric_limits<size_t>::min());
147 23349 : return static_cast<size_t>(val);
148 : }
149 :
150 395 : void JSTypedArray::set_length(Object value, WriteBarrierMode mode) {
151 395 : WRITE_FIELD(this, kLengthOffset, value);
152 1185 : CONDITIONAL_WRITE_BARRIER(*this, kLengthOffset, value, mode);
153 395 : }
154 :
155 37069623 : bool JSTypedArray::is_on_heap() const {
156 : DisallowHeapAllocation no_gc;
157 : // Checking that buffer()->backing_store() is not nullptr is not sufficient;
158 : // it will be nullptr when byte_length is 0 as well.
159 74139224 : FixedTypedArrayBase fta = FixedTypedArrayBase::cast(elements());
160 74139180 : return fta->base_pointer()->ptr() == fta.ptr();
161 : }
162 :
163 : // static
164 13779 : MaybeHandle<JSTypedArray> JSTypedArray::Validate(Isolate* isolate,
165 : Handle<Object> receiver,
166 : const char* method_name) {
167 27558 : if (V8_UNLIKELY(!receiver->IsJSTypedArray())) {
168 : const MessageTemplate message = MessageTemplate::kNotTypedArray;
169 846 : THROW_NEW_ERROR(isolate, NewTypeError(message), JSTypedArray);
170 : }
171 :
172 12933 : Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver);
173 12933 : if (V8_UNLIKELY(array->WasDetached())) {
174 : const MessageTemplate message = MessageTemplate::kDetachedOperation;
175 : Handle<String> operation =
176 405 : isolate->factory()->NewStringFromAsciiChecked(method_name);
177 405 : THROW_NEW_ERROR(isolate, NewTypeError(message, operation), JSTypedArray);
178 : }
179 :
180 : // spec describes to return `buffer`, but it may disrupt current
181 : // implementations, and it's much useful to return array for now.
182 12528 : return array;
183 : }
184 :
185 : #ifdef VERIFY_HEAP
186 : ACCESSORS(JSTypedArray, raw_length, Object, kLengthOffset)
187 : #endif
188 :
189 : } // namespace internal
190 : } // namespace v8
191 :
192 : #include "src/objects/object-macros-undef.h"
193 :
194 : #endif // V8_OBJECTS_JS_ARRAY_BUFFER_INL_H_
|