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/heap/heap-write-barrier-inl.h"
11 : #include "src/objects-inl.h"
12 : #include "src/objects/js-objects-inl.h"
13 : #include "src/wasm/wasm-engine.h"
14 :
15 : // Has to be the last include (doesn't have include guards):
16 : #include "src/objects/object-macros.h"
17 :
18 : namespace v8 {
19 : namespace internal {
20 :
21 : OBJECT_CONSTRUCTORS_IMPL(JSArrayBuffer, JSObject)
22 : OBJECT_CONSTRUCTORS_IMPL(JSArrayBufferView, JSObject)
23 : OBJECT_CONSTRUCTORS_IMPL(JSTypedArray, JSArrayBufferView)
24 : OBJECT_CONSTRUCTORS_IMPL(JSDataView, JSArrayBufferView)
25 :
26 : CAST_ACCESSOR(JSArrayBuffer)
27 : CAST_ACCESSOR(JSArrayBufferView)
28 : CAST_ACCESSOR(JSTypedArray)
29 : CAST_ACCESSOR(JSDataView)
30 :
31 : size_t JSArrayBuffer::byte_length() const {
32 1264689 : return READ_UINTPTR_FIELD(*this, kByteLengthOffset);
33 : }
34 :
35 : void JSArrayBuffer::set_byte_length(size_t value) {
36 517599 : WRITE_UINTPTR_FIELD(*this, kByteLengthOffset, value);
37 : }
38 :
39 : void* JSArrayBuffer::backing_store() const {
40 43324749 : intptr_t ptr = READ_INTPTR_FIELD(*this, kBackingStoreOffset);
41 43305977 : return reinterpret_cast<void*>(ptr);
42 : }
43 :
44 : void JSArrayBuffer::set_backing_store(void* value, WriteBarrierMode mode) {
45 529995 : intptr_t ptr = reinterpret_cast<intptr_t>(value);
46 535146 : WRITE_INTPTR_FIELD(*this, kBackingStoreOffset, ptr);
47 : }
48 :
49 287103 : size_t JSArrayBuffer::allocation_length() const {
50 287103 : if (backing_store() == nullptr) {
51 : return 0;
52 : }
53 : // If this buffer is managed by the WasmMemoryTracker
54 286907 : if (is_wasm_memory()) {
55 : const auto* data =
56 : GetIsolate()->wasm_engine()->memory_tracker()->FindAllocationData(
57 4448 : backing_store());
58 : DCHECK_NOT_NULL(data);
59 4448 : return data->allocation_length;
60 : }
61 282459 : return byte_length();
62 : }
63 :
64 282829 : void* JSArrayBuffer::allocation_base() const {
65 282829 : if (backing_store() == nullptr) {
66 : return nullptr;
67 : }
68 : // If this buffer is managed by the WasmMemoryTracker
69 282633 : if (is_wasm_memory()) {
70 : const auto* data =
71 : GetIsolate()->wasm_engine()->memory_tracker()->FindAllocationData(
72 172 : backing_store());
73 : DCHECK_NOT_NULL(data);
74 172 : return data->allocation_base;
75 : }
76 : return backing_store();
77 : }
78 :
79 : bool JSArrayBuffer::is_wasm_memory() const {
80 : return IsWasmMemoryBit::decode(bit_field());
81 : }
82 :
83 : void JSArrayBuffer::set_is_wasm_memory(bool is_wasm_memory) {
84 : set_bit_field(IsWasmMemoryBit::update(bit_field(), is_wasm_memory));
85 : }
86 :
87 : void JSArrayBuffer::clear_padding() {
88 : if (FIELD_SIZE(kOptionalPaddingOffset) != 0) {
89 : DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset));
90 512503 : memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
91 : FIELD_SIZE(kOptionalPaddingOffset));
92 : }
93 : }
94 :
95 : void JSArrayBuffer::set_bit_field(uint32_t bits) {
96 2782939 : WRITE_UINT32_FIELD(*this, kBitFieldOffset, bits);
97 : }
98 :
99 : uint32_t JSArrayBuffer::bit_field() const {
100 103999287 : return READ_UINT32_FIELD(*this, kBitFieldOffset);
101 : }
102 :
103 : // |bit_field| fields.
104 : BIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_external,
105 : JSArrayBuffer::IsExternalBit)
106 : BIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_detachable,
107 : JSArrayBuffer::IsDetachableBit)
108 : BIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, was_detached,
109 : JSArrayBuffer::WasDetachedBit)
110 : BIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_shared,
111 : JSArrayBuffer::IsSharedBit)
112 :
113 : size_t JSArrayBufferView::byte_offset() const {
114 41233751 : return READ_UINTPTR_FIELD(*this, kByteOffsetOffset);
115 : }
116 :
117 : void JSArrayBufferView::set_byte_offset(size_t value) {
118 4450 : WRITE_UINTPTR_FIELD(*this, kByteOffsetOffset, value);
119 : }
120 :
121 : size_t JSArrayBufferView::byte_length() const {
122 32385 : return READ_UINTPTR_FIELD(*this, kByteLengthOffset);
123 : }
124 :
125 : void JSArrayBufferView::set_byte_length(size_t value) {
126 4450 : WRITE_UINTPTR_FIELD(*this, kByteLengthOffset, value);
127 : }
128 :
129 127943368 : ACCESSORS(JSArrayBufferView, buffer, Object, kBufferOffset)
130 :
131 : bool JSArrayBufferView::WasDetached() const {
132 : return JSArrayBuffer::cast(buffer())->was_detached();
133 : }
134 :
135 : size_t JSTypedArray::length() const {
136 : // TODO(bmeurer, v8:4153): Change this to size_t later.
137 : int length = Smi::cast(raw_length())->value();
138 : DCHECK_LE(0, length);
139 43189475 : return length;
140 : }
141 :
142 432 : void JSTypedArray::set_length(size_t value) {
143 : // TODO(bmeurer, v8:4153): Change this to size_t later.
144 432 : CHECK_LE(value, Smi::kMaxValue);
145 432 : set_raw_length(Smi::FromInt(static_cast<int>(value)), SKIP_WRITE_BARRIER);
146 432 : }
147 :
148 : bool JSTypedArray::is_on_heap() const {
149 : DisallowHeapAllocation no_gc;
150 : // Checking that buffer()->backing_store() is not nullptr is not sufficient;
151 : // it will be nullptr when byte_length is 0 as well.
152 : FixedTypedArrayBase fta = FixedTypedArrayBase::cast(elements());
153 5017 : return fta->base_pointer()->ptr() == fta.ptr();
154 : }
155 :
156 : // static
157 13949 : MaybeHandle<JSTypedArray> JSTypedArray::Validate(Isolate* isolate,
158 : Handle<Object> receiver,
159 : const char* method_name) {
160 13949 : if (V8_UNLIKELY(!receiver->IsJSTypedArray())) {
161 : const MessageTemplate message = MessageTemplate::kNotTypedArray;
162 1692 : THROW_NEW_ERROR(isolate, NewTypeError(message), JSTypedArray);
163 : }
164 :
165 : Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver);
166 13103 : if (V8_UNLIKELY(array->WasDetached())) {
167 : const MessageTemplate message = MessageTemplate::kDetachedOperation;
168 : Handle<String> operation =
169 405 : isolate->factory()->NewStringFromAsciiChecked(method_name);
170 810 : THROW_NEW_ERROR(isolate, NewTypeError(message, operation), JSTypedArray);
171 : }
172 :
173 : // spec describes to return `buffer`, but it may disrupt current
174 : // implementations, and it's much useful to return array for now.
175 12698 : return array;
176 : }
177 :
178 43201705 : ACCESSORS(JSTypedArray, raw_length, Object, kLengthOffset)
179 :
180 : } // namespace internal
181 : } // namespace v8
182 :
183 : #include "src/objects/object-macros-undef.h"
184 :
185 : #endif // V8_OBJECTS_JS_ARRAY_BUFFER_INL_H_
|