[objects] Split js-array-buffer.h from js-array.h

JSArrays and JSArrayBuffers are very different animals. As such,
split the js-array.h header into two parts.

R=ulan@chromium.org,mstarzinger@chromium.org

Bug: v8:5402
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: I82f987ecea3e2e1ceaf8f8962a2b88165558c57e
Reviewed-on: https://chromium-review.googlesource.com/1177760
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55183}
This commit is contained in:
Ben L. Titzer 2018-08-16 18:01:36 +02:00 committed by Commit Bot
parent 1ad4f28407
commit 515d3400d1
42 changed files with 482 additions and 410 deletions

View File

@ -844,6 +844,8 @@ action("postmortem-metadata") {
"src/objects/fixed-array.h",
"src/objects/js-array-inl.h",
"src/objects/js-array.h",
"src/objects/js-array-buffer-inl.h",
"src/objects/js-array-buffer.h",
"src/objects/js-regexp-inl.h",
"src/objects/js-regexp.h",
"src/objects/js-regexp-string-iterator-inl.h",
@ -2157,6 +2159,8 @@ v8_source_set("v8_base") {
"src/objects/intl-objects-inl.h",
"src/objects/intl-objects.cc",
"src/objects/intl-objects.h",
"src/objects/js-array-buffer-inl.h",
"src/objects/js-array-buffer.h",
"src/objects/js-array-inl.h",
"src/objects/js-array.h",
"src/objects/js-collator-inl.h",

View File

@ -51,6 +51,7 @@
#include "src/messages.h"
#include "src/objects-inl.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-collection-inl.h"
#include "src/objects/js-generator-inl.h"
#include "src/objects/js-promise-inl.h"

View File

@ -28,6 +28,7 @@
#include "src/objects/js-list-format.h"
#include "src/objects/js-locale.h"
#endif // V8_INTL_SUPPORT
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-regexp-string-iterator.h"
#include "src/objects/js-regexp.h"

View File

@ -8,7 +8,7 @@
#include "src/counters.h"
#include "src/maybe-handles-inl.h"
#include "src/objects-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-array-buffer-inl.h"
namespace v8 {
namespace internal {

View File

@ -9,7 +9,7 @@
#include "src/heap/factory.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-array-buffer-inl.h"
namespace v8 {
namespace internal {

View File

@ -14,7 +14,7 @@
#include "src/globals.h"
#include "src/heap/factory.h"
#include "src/objects-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-array-buffer-inl.h"
namespace v8 {
namespace internal {

View File

@ -7,7 +7,7 @@
#include "src/counters.h"
#include "src/elements.h"
#include "src/objects-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-array-buffer-inl.h"
namespace v8 {
namespace internal {

View File

@ -23,6 +23,7 @@
#include "src/ic/call-optimization.h"
#include "src/objects-inl.h"
#include "src/objects/arguments-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/vector-slot-pair.h"

View File

@ -20,6 +20,7 @@
#include "src/feedback-vector.h"
#include "src/field-index-inl.h"
#include "src/isolate-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/templates.h"
#include "src/vector-slot-pair.h"

View File

@ -14,6 +14,7 @@
#include "src/objects-inl.h"
#include "src/objects/arguments-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/utils.h"

View File

@ -12,7 +12,7 @@
#include "src/handles-inl.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-array-buffer-inl.h"
namespace v8 {
namespace internal {

View File

@ -8,7 +8,7 @@
#include <vector>
#include "src/base/platform/mutex.h"
#include "src/objects/js-array.h"
#include "src/objects/js-array-buffer.h"
namespace v8 {
namespace internal {

View File

@ -10,7 +10,7 @@
#include "src/heap/heap.h"
#include "src/heap/spaces.h"
#include "src/objects.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-array-buffer-inl.h"
namespace v8 {
namespace internal {

View File

@ -10,7 +10,7 @@
#include "src/allocation.h"
#include "src/base/platform/mutex.h"
#include "src/globals.h"
#include "src/objects/js-array.h"
#include "src/objects/js-array-buffer.h"
namespace v8 {
namespace internal {

View File

@ -21,6 +21,7 @@
#include "src/objects/bigint.h"
#include "src/objects/debug-objects-inl.h"
#include "src/objects/frame-array-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-collection-inl.h"
#include "src/objects/js-generator-inl.h"
#include "src/objects/js-regexp-inl.h"

View File

@ -14,6 +14,7 @@
#include "src/objects/code.h"
#include "src/objects/dictionary.h"
#include "src/objects/hash-table.h"
#include "src/objects/js-array-buffer.h"
#include "src/objects/js-array.h"
#include "src/objects/js-regexp.h"
#include "src/objects/ordered-hash-table.h"

View File

@ -21,6 +21,7 @@
#include "src/heap/sweeper.h"
#include "src/msan.h"
#include "src/objects-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/snapshot/snapshot.h"
#include "src/v8.h"

View File

@ -41,6 +41,7 @@
#include "src/messages.h"
#include "src/objects/frame-array-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/module-inl.h"
#include "src/objects/promise-inl.h"
#include "src/profiler/tracing-cpu-profiler.h"

View File

@ -11,6 +11,7 @@
#include "src/isolate-inl.h"
#include "src/keys.h"
#include "src/objects/frame-array-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/string-builder-inl.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-objects.h"

View File

@ -21,6 +21,7 @@
#include "src/objects/data-handler-inl.h"
#include "src/objects/debug-objects-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-collection-inl.h"
#include "src/objects/js-generator-inl.h"
#include "src/objects/literal-objects-inl.h"

View File

@ -20,6 +20,8 @@
#include "src/objects/data-handler-inl.h"
#include "src/objects/debug-objects-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-collection-inl.h"
#include "src/objects/js-generator-inl.h"
#ifdef V8_INTL_SUPPORT

View File

@ -59,6 +59,7 @@
#include "src/objects/debug-objects-inl.h"
#include "src/objects/frame-array-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-collator.h"
#endif // V8_INTL_SUPPORT

View File

@ -0,0 +1,210 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_OBJECTS_JS_ARRAY_BUFFER_INL_H_
#define V8_OBJECTS_JS_ARRAY_BUFFER_INL_H_
#include "src/objects/js-array-buffer.h"
#include "src/objects-inl.h" // Needed for write barriers
#include "src/wasm/wasm-engine.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
CAST_ACCESSOR(JSArrayBuffer)
CAST_ACCESSOR(JSArrayBufferView)
CAST_ACCESSOR(JSTypedArray)
void* JSArrayBuffer::backing_store() const {
intptr_t ptr = READ_INTPTR_FIELD(this, kBackingStoreOffset);
return reinterpret_cast<void*>(ptr);
}
void JSArrayBuffer::set_backing_store(void* value, WriteBarrierMode mode) {
intptr_t ptr = reinterpret_cast<intptr_t>(value);
WRITE_INTPTR_FIELD(this, kBackingStoreOffset, ptr);
}
ACCESSORS(JSArrayBuffer, byte_length, Object, kByteLengthOffset)
size_t JSArrayBuffer::allocation_length() const {
if (backing_store() == nullptr) {
return 0;
}
// If this buffer is managed by the WasmMemoryTracker
if (is_wasm_memory()) {
const auto* data =
GetIsolate()->wasm_engine()->memory_tracker()->FindAllocationData(
backing_store());
DCHECK_NOT_NULL(data);
return data->allocation_length;
}
return byte_length()->Number();
}
void* JSArrayBuffer::allocation_base() const {
if (backing_store() == nullptr) {
return nullptr;
}
// If this buffer is managed by the WasmMemoryTracker
if (is_wasm_memory()) {
const auto* data =
GetIsolate()->wasm_engine()->memory_tracker()->FindAllocationData(
backing_store());
DCHECK_NOT_NULL(data);
return data->allocation_base;
}
return backing_store();
}
bool JSArrayBuffer::is_wasm_memory() const {
bool const is_wasm_memory = IsWasmMemory::decode(bit_field());
DCHECK_EQ(is_wasm_memory,
GetIsolate()->wasm_engine()->memory_tracker()->IsWasmMemory(
backing_store()));
return is_wasm_memory;
}
void JSArrayBuffer::set_bit_field(uint32_t bits) {
if (kInt32Size != kPointerSize) {
#if V8_TARGET_LITTLE_ENDIAN
WRITE_UINT32_FIELD(this, kBitFieldSlot + kInt32Size, 0);
#else
WRITE_UINT32_FIELD(this, kBitFieldSlot, 0);
#endif
}
WRITE_UINT32_FIELD(this, kBitFieldOffset, bits);
}
uint32_t JSArrayBuffer::bit_field() const {
return READ_UINT32_FIELD(this, kBitFieldOffset);
}
bool JSArrayBuffer::is_external() { return IsExternal::decode(bit_field()); }
void JSArrayBuffer::set_is_external(bool value) {
set_bit_field(IsExternal::update(bit_field(), value));
}
bool JSArrayBuffer::is_neuterable() {
return IsNeuterable::decode(bit_field());
}
void JSArrayBuffer::set_is_neuterable(bool value) {
set_bit_field(IsNeuterable::update(bit_field(), value));
}
bool JSArrayBuffer::was_neutered() { return WasNeutered::decode(bit_field()); }
void JSArrayBuffer::set_was_neutered(bool value) {
set_bit_field(WasNeutered::update(bit_field(), value));
}
bool JSArrayBuffer::is_shared() { return IsShared::decode(bit_field()); }
void JSArrayBuffer::set_is_shared(bool value) {
set_bit_field(IsShared::update(bit_field(), value));
}
bool JSArrayBuffer::is_growable() { return IsGrowable::decode(bit_field()); }
void JSArrayBuffer::set_is_growable(bool value) {
set_bit_field(IsGrowable::update(bit_field(), value));
}
Object* JSArrayBufferView::byte_offset() const {
if (WasNeutered()) return Smi::kZero;
return Object::cast(READ_FIELD(this, kByteOffsetOffset));
}
void JSArrayBufferView::set_byte_offset(Object* value, WriteBarrierMode mode) {
WRITE_FIELD(this, kByteOffsetOffset, value);
CONDITIONAL_WRITE_BARRIER(this, kByteOffsetOffset, value, mode);
}
Object* JSArrayBufferView::byte_length() const {
if (WasNeutered()) return Smi::kZero;
return Object::cast(READ_FIELD(this, kByteLengthOffset));
}
void JSArrayBufferView::set_byte_length(Object* value, WriteBarrierMode mode) {
WRITE_FIELD(this, kByteLengthOffset, value);
CONDITIONAL_WRITE_BARRIER(this, kByteLengthOffset, value, mode);
}
ACCESSORS(JSArrayBufferView, buffer, Object, kBufferOffset)
#ifdef VERIFY_HEAP
ACCESSORS(JSArrayBufferView, raw_byte_offset, Object, kByteOffsetOffset)
ACCESSORS(JSArrayBufferView, raw_byte_length, Object, kByteLengthOffset)
#endif
bool JSArrayBufferView::WasNeutered() const {
return JSArrayBuffer::cast(buffer())->was_neutered();
}
Object* JSTypedArray::length() const {
if (WasNeutered()) return Smi::kZero;
return Object::cast(READ_FIELD(this, kLengthOffset));
}
size_t JSTypedArray::length_value() const {
if (WasNeutered()) return 0;
double val = Object::cast(READ_FIELD(this, kLengthOffset))->Number();
DCHECK_LE(val, kMaxSafeInteger); // 2^53-1
DCHECK_GE(val, -kMaxSafeInteger); // -2^53+1
DCHECK_LE(val, std::numeric_limits<size_t>::max());
DCHECK_GE(val, std::numeric_limits<size_t>::min());
return static_cast<size_t>(val);
}
void JSTypedArray::set_length(Object* value, WriteBarrierMode mode) {
WRITE_FIELD(this, kLengthOffset, value);
CONDITIONAL_WRITE_BARRIER(this, kLengthOffset, value, mode);
}
bool JSTypedArray::is_on_heap() const {
DisallowHeapAllocation no_gc;
// Checking that buffer()->backing_store() is not nullptr is not sufficient;
// it will be nullptr when byte_length is 0 as well.
FixedTypedArrayBase* fta(FixedTypedArrayBase::cast(elements()));
return fta->base_pointer() == fta;
}
// static
MaybeHandle<JSTypedArray> JSTypedArray::Validate(Isolate* isolate,
Handle<Object> receiver,
const char* method_name) {
if (V8_UNLIKELY(!receiver->IsJSTypedArray())) {
const MessageTemplate::Template message = MessageTemplate::kNotTypedArray;
THROW_NEW_ERROR(isolate, NewTypeError(message), JSTypedArray);
}
Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver);
if (V8_UNLIKELY(array->WasNeutered())) {
const MessageTemplate::Template message =
MessageTemplate::kDetachedOperation;
Handle<String> operation =
isolate->factory()->NewStringFromAsciiChecked(method_name);
THROW_NEW_ERROR(isolate, NewTypeError(message, operation), JSTypedArray);
}
// spec describes to return `buffer`, but it may disrupt current
// implementations, and it's much useful to return array for now.
return array;
}
#ifdef VERIFY_HEAP
ACCESSORS(JSTypedArray, raw_length, Object, kLengthOffset)
#endif
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_JS_ARRAY_BUFFER_INL_H_

View File

@ -0,0 +1,230 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_OBJECTS_JS_ARRAY_BUFFER_H_
#define V8_OBJECTS_JS_ARRAY_BUFFER_H_
#include "src/objects.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
// Whether a JSArrayBuffer is a SharedArrayBuffer or not.
enum class SharedFlag { kNotShared, kShared };
class JSArrayBuffer : public JSObject {
public:
// [byte_length]: length in bytes
DECL_ACCESSORS(byte_length, Object)
// [backing_store]: backing memory for this array
DECL_ACCESSORS(backing_store, void)
// For non-wasm, allocation_length and allocation_base are byte_length and
// backing_store, respectively.
inline size_t allocation_length() const;
inline void* allocation_base() const;
inline uint32_t bit_field() const;
inline void set_bit_field(uint32_t bits);
// [is_external]: true indicates that the embedder is in charge of freeing the
// backing_store, while is_external == false means that v8 will free the
// memory block once all ArrayBuffers referencing it are collected by the GC.
inline bool is_external();
inline void set_is_external(bool value);
inline bool is_neuterable();
inline void set_is_neuterable(bool value);
inline bool was_neutered();
inline void set_was_neutered(bool value);
inline bool is_shared();
inline void set_is_shared(bool value);
inline bool is_growable();
inline void set_is_growable(bool value);
DECL_CAST(JSArrayBuffer)
void Neuter();
struct Allocation {
Allocation(void* allocation_base, size_t length, void* backing_store,
bool is_wasm_memory)
: allocation_base(allocation_base),
length(length),
backing_store(backing_store),
is_wasm_memory(is_wasm_memory) {}
void* allocation_base;
size_t length;
void* backing_store;
bool is_wasm_memory;
};
// Returns whether the buffer is tracked by the WasmMemoryTracker.
inline bool is_wasm_memory() const;
// Sets whether the buffer is tracked by the WasmMemoryTracker.
void set_is_wasm_memory(bool is_wasm_memory);
// Removes the backing store from the WasmMemoryTracker and sets
// |is_wasm_memory| to false.
void StopTrackingWasmMemory(Isolate* isolate);
void FreeBackingStoreFromMainThread();
static void FreeBackingStore(Isolate* isolate, Allocation allocation);
V8_EXPORT_PRIVATE static void Setup(
Handle<JSArrayBuffer> array_buffer, Isolate* isolate, bool is_external,
void* data, size_t allocated_length,
SharedFlag shared = SharedFlag::kNotShared, bool is_wasm_memory = false);
// Returns false if array buffer contents could not be allocated.
// In this case, |array_buffer| will not be set up.
static bool SetupAllocatingData(
Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
size_t allocated_length, bool initialize = true,
SharedFlag shared = SharedFlag::kNotShared) V8_WARN_UNUSED_RESULT;
// Dispatched behavior.
DECL_PRINTER(JSArrayBuffer)
DECL_VERIFIER(JSArrayBuffer)
static const int kByteLengthOffset = JSObject::kHeaderSize;
// The rest of the fields are not JSObjects, so they are not iterated over in
// objects-body-descriptors-inl.h.
static const int kBackingStoreOffset = kByteLengthOffset + kPointerSize;
static const int kBitFieldSlot = kBackingStoreOffset + kPointerSize;
#if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
static const int kBitFieldOffset = kBitFieldSlot;
#else
static const int kBitFieldOffset = kBitFieldSlot + kInt32Size;
#endif
static const int kSize = kBitFieldSlot + kPointerSize;
static const int kSizeWithEmbedderFields =
kSize + v8::ArrayBuffer::kEmbedderFieldCount * kPointerSize;
// Iterates all fields in the object including internal ones except
// kBackingStoreOffset and kBitFieldSlot.
class BodyDescriptor;
// No weak fields.
typedef BodyDescriptor BodyDescriptorWeak;
class IsExternal : public BitField<bool, 1, 1> {};
class IsNeuterable : public BitField<bool, 2, 1> {};
class WasNeutered : public BitField<bool, 3, 1> {};
class IsShared : public BitField<bool, 4, 1> {};
class IsGrowable : public BitField<bool, 5, 1> {};
class IsWasmMemory : public BitField<bool, 6, 1> {};
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer);
};
class JSArrayBufferView : public JSObject {
public:
// [buffer]: ArrayBuffer that this typed array views.
DECL_ACCESSORS(buffer, Object)
// [byte_offset]: offset of typed array in bytes.
DECL_ACCESSORS(byte_offset, Object)
// [byte_length]: length of typed array in bytes.
DECL_ACCESSORS(byte_length, Object)
DECL_CAST(JSArrayBufferView)
DECL_VERIFIER(JSArrayBufferView)
inline bool WasNeutered() const;
static const int kBufferOffset = JSObject::kHeaderSize;
static const int kByteOffsetOffset = kBufferOffset + kPointerSize;
static const int kByteLengthOffset = kByteOffsetOffset + kPointerSize;
static const int kViewSize = kByteLengthOffset + kPointerSize;
private:
#ifdef VERIFY_HEAP
DECL_ACCESSORS(raw_byte_offset, Object)
DECL_ACCESSORS(raw_byte_length, Object)
#endif
DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBufferView);
};
class JSTypedArray : public JSArrayBufferView {
public:
// [length]: length of typed array in elements.
DECL_ACCESSORS(length, Object)
inline size_t length_value() const;
// ES6 9.4.5.3
V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty(
Isolate* isolate, Handle<JSTypedArray> o, Handle<Object> key,
PropertyDescriptor* desc, ShouldThrow should_throw);
DECL_CAST(JSTypedArray)
ExternalArrayType type();
V8_EXPORT_PRIVATE size_t element_size();
Handle<JSArrayBuffer> GetBuffer();
// Whether the buffer's backing store is on-heap or off-heap.
inline bool is_on_heap() const;
static inline MaybeHandle<JSTypedArray> Validate(Isolate* isolate,
Handle<Object> receiver,
const char* method_name);
// Dispatched behavior.
DECL_PRINTER(JSTypedArray)
DECL_VERIFIER(JSTypedArray)
static const int kLengthOffset = kViewSize;
static const int kSize = kLengthOffset + kPointerSize;
static const int kSizeWithEmbedderFields =
kSize + v8::ArrayBufferView::kEmbedderFieldCount * kPointerSize;
private:
static Handle<JSArrayBuffer> MaterializeArrayBuffer(
Handle<JSTypedArray> typed_array);
#ifdef VERIFY_HEAP
DECL_ACCESSORS(raw_length, Object)
#endif
DISALLOW_IMPLICIT_CONSTRUCTORS(JSTypedArray);
};
class JSDataView : public JSArrayBufferView {
public:
DECL_CAST(JSDataView)
// Dispatched behavior.
DECL_PRINTER(JSDataView)
DECL_VERIFIER(JSDataView)
static const int kSize = kViewSize;
static const int kSizeWithEmbedderFields =
kSize + v8::ArrayBufferView::kEmbedderFieldCount * kPointerSize;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataView);
};
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_JS_ARRAY_BUFFER_H_

View File

@ -8,7 +8,6 @@
#include "src/objects/js-array.h"
#include "src/objects-inl.h" // Needed for write barriers
#include "src/wasm/wasm-engine.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@ -17,10 +16,7 @@ namespace v8 {
namespace internal {
CAST_ACCESSOR(JSArray)
CAST_ACCESSOR(JSArrayBuffer)
CAST_ACCESSOR(JSArrayBufferView)
CAST_ACCESSOR(JSArrayIterator)
CAST_ACCESSOR(JSTypedArray)
ACCESSORS(JSArray, length, Object, kLengthOffset)
@ -59,188 +55,6 @@ bool JSArray::HasArrayPrototype(Isolate* isolate) {
return map()->prototype() == *isolate->initial_array_prototype();
}
void* JSArrayBuffer::backing_store() const {
intptr_t ptr = READ_INTPTR_FIELD(this, kBackingStoreOffset);
return reinterpret_cast<void*>(ptr);
}
void JSArrayBuffer::set_backing_store(void* value, WriteBarrierMode mode) {
intptr_t ptr = reinterpret_cast<intptr_t>(value);
WRITE_INTPTR_FIELD(this, kBackingStoreOffset, ptr);
}
ACCESSORS(JSArrayBuffer, byte_length, Object, kByteLengthOffset)
size_t JSArrayBuffer::allocation_length() const {
if (backing_store() == nullptr) {
return 0;
}
// If this buffer is managed by the WasmMemoryTracker
if (is_wasm_memory()) {
const auto* data =
GetIsolate()->wasm_engine()->memory_tracker()->FindAllocationData(
backing_store());
DCHECK_NOT_NULL(data);
return data->allocation_length;
}
return byte_length()->Number();
}
void* JSArrayBuffer::allocation_base() const {
if (backing_store() == nullptr) {
return nullptr;
}
// If this buffer is managed by the WasmMemoryTracker
if (is_wasm_memory()) {
const auto* data =
GetIsolate()->wasm_engine()->memory_tracker()->FindAllocationData(
backing_store());
DCHECK_NOT_NULL(data);
return data->allocation_base;
}
return backing_store();
}
bool JSArrayBuffer::is_wasm_memory() const {
bool const is_wasm_memory = IsWasmMemory::decode(bit_field());
DCHECK_EQ(is_wasm_memory,
GetIsolate()->wasm_engine()->memory_tracker()->IsWasmMemory(
backing_store()));
return is_wasm_memory;
}
void JSArrayBuffer::set_bit_field(uint32_t bits) {
if (kInt32Size != kPointerSize) {
#if V8_TARGET_LITTLE_ENDIAN
WRITE_UINT32_FIELD(this, kBitFieldSlot + kInt32Size, 0);
#else
WRITE_UINT32_FIELD(this, kBitFieldSlot, 0);
#endif
}
WRITE_UINT32_FIELD(this, kBitFieldOffset, bits);
}
uint32_t JSArrayBuffer::bit_field() const {
return READ_UINT32_FIELD(this, kBitFieldOffset);
}
bool JSArrayBuffer::is_external() { return IsExternal::decode(bit_field()); }
void JSArrayBuffer::set_is_external(bool value) {
set_bit_field(IsExternal::update(bit_field(), value));
}
bool JSArrayBuffer::is_neuterable() {
return IsNeuterable::decode(bit_field());
}
void JSArrayBuffer::set_is_neuterable(bool value) {
set_bit_field(IsNeuterable::update(bit_field(), value));
}
bool JSArrayBuffer::was_neutered() { return WasNeutered::decode(bit_field()); }
void JSArrayBuffer::set_was_neutered(bool value) {
set_bit_field(WasNeutered::update(bit_field(), value));
}
bool JSArrayBuffer::is_shared() { return IsShared::decode(bit_field()); }
void JSArrayBuffer::set_is_shared(bool value) {
set_bit_field(IsShared::update(bit_field(), value));
}
bool JSArrayBuffer::is_growable() { return IsGrowable::decode(bit_field()); }
void JSArrayBuffer::set_is_growable(bool value) {
set_bit_field(IsGrowable::update(bit_field(), value));
}
Object* JSArrayBufferView::byte_offset() const {
if (WasNeutered()) return Smi::kZero;
return Object::cast(READ_FIELD(this, kByteOffsetOffset));
}
void JSArrayBufferView::set_byte_offset(Object* value, WriteBarrierMode mode) {
WRITE_FIELD(this, kByteOffsetOffset, value);
CONDITIONAL_WRITE_BARRIER(this, kByteOffsetOffset, value, mode);
}
Object* JSArrayBufferView::byte_length() const {
if (WasNeutered()) return Smi::kZero;
return Object::cast(READ_FIELD(this, kByteLengthOffset));
}
void JSArrayBufferView::set_byte_length(Object* value, WriteBarrierMode mode) {
WRITE_FIELD(this, kByteLengthOffset, value);
CONDITIONAL_WRITE_BARRIER(this, kByteLengthOffset, value, mode);
}
ACCESSORS(JSArrayBufferView, buffer, Object, kBufferOffset)
#ifdef VERIFY_HEAP
ACCESSORS(JSArrayBufferView, raw_byte_offset, Object, kByteOffsetOffset)
ACCESSORS(JSArrayBufferView, raw_byte_length, Object, kByteLengthOffset)
#endif
bool JSArrayBufferView::WasNeutered() const {
return JSArrayBuffer::cast(buffer())->was_neutered();
}
Object* JSTypedArray::length() const {
if (WasNeutered()) return Smi::kZero;
return Object::cast(READ_FIELD(this, kLengthOffset));
}
size_t JSTypedArray::length_value() const {
if (WasNeutered()) return 0;
double val = Object::cast(READ_FIELD(this, kLengthOffset))->Number();
DCHECK_LE(val, kMaxSafeInteger); // 2^53-1
DCHECK_GE(val, -kMaxSafeInteger); // -2^53+1
DCHECK_LE(val, std::numeric_limits<size_t>::max());
DCHECK_GE(val, std::numeric_limits<size_t>::min());
return static_cast<size_t>(val);
}
void JSTypedArray::set_length(Object* value, WriteBarrierMode mode) {
WRITE_FIELD(this, kLengthOffset, value);
CONDITIONAL_WRITE_BARRIER(this, kLengthOffset, value, mode);
}
bool JSTypedArray::is_on_heap() const {
DisallowHeapAllocation no_gc;
// Checking that buffer()->backing_store() is not nullptr is not sufficient;
// it will be nullptr when byte_length is 0 as well.
FixedTypedArrayBase* fta(FixedTypedArrayBase::cast(elements()));
return fta->base_pointer() == fta;
}
// static
MaybeHandle<JSTypedArray> JSTypedArray::Validate(Isolate* isolate,
Handle<Object> receiver,
const char* method_name) {
if (V8_UNLIKELY(!receiver->IsJSTypedArray())) {
const MessageTemplate::Template message = MessageTemplate::kNotTypedArray;
THROW_NEW_ERROR(isolate, NewTypeError(message), JSTypedArray);
}
Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver);
if (V8_UNLIKELY(array->WasNeutered())) {
const MessageTemplate::Template message =
MessageTemplate::kDetachedOperation;
Handle<String> operation =
isolate->factory()->NewStringFromAsciiChecked(method_name);
THROW_NEW_ERROR(isolate, NewTypeError(message, operation), JSTypedArray);
}
// spec describes to return `buffer`, but it may disrupt current
// implementations, and it's much useful to return array for now.
return array;
}
#ifdef VERIFY_HEAP
ACCESSORS(JSTypedArray, raw_length, Object, kLengthOffset)
#endif
ACCESSORS(JSArrayIterator, iterated_object, Object, kIteratedObjectOffset)
ACCESSORS(JSArrayIterator, next_index, Object, kNextIndexOffset)

View File

@ -132,215 +132,6 @@ class JSArrayIterator : public JSObject {
DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayIterator);
};
// Whether a JSArrayBuffer is a SharedArrayBuffer or not.
enum class SharedFlag { kNotShared, kShared };
class JSArrayBuffer : public JSObject {
public:
// [byte_length]: length in bytes
DECL_ACCESSORS(byte_length, Object)
// [backing_store]: backing memory for this array
DECL_ACCESSORS(backing_store, void)
// For non-wasm, allocation_length and allocation_base are byte_length and
// backing_store, respectively.
inline size_t allocation_length() const;
inline void* allocation_base() const;
inline uint32_t bit_field() const;
inline void set_bit_field(uint32_t bits);
// [is_external]: true indicates that the embedder is in charge of freeing the
// backing_store, while is_external == false means that v8 will free the
// memory block once all ArrayBuffers referencing it are collected by the GC.
inline bool is_external();
inline void set_is_external(bool value);
inline bool is_neuterable();
inline void set_is_neuterable(bool value);
inline bool was_neutered();
inline void set_was_neutered(bool value);
inline bool is_shared();
inline void set_is_shared(bool value);
inline bool is_growable();
inline void set_is_growable(bool value);
DECL_CAST(JSArrayBuffer)
void Neuter();
struct Allocation {
Allocation(void* allocation_base, size_t length, void* backing_store,
bool is_wasm_memory)
: allocation_base(allocation_base),
length(length),
backing_store(backing_store),
is_wasm_memory(is_wasm_memory) {}
void* allocation_base;
size_t length;
void* backing_store;
bool is_wasm_memory;
};
// Returns whether the buffer is tracked by the WasmMemoryTracker.
inline bool is_wasm_memory() const;
// Sets whether the buffer is tracked by the WasmMemoryTracker.
void set_is_wasm_memory(bool is_wasm_memory);
// Removes the backing store from the WasmMemoryTracker and sets
// |is_wasm_memory| to false.
void StopTrackingWasmMemory(Isolate* isolate);
void FreeBackingStoreFromMainThread();
static void FreeBackingStore(Isolate* isolate, Allocation allocation);
V8_EXPORT_PRIVATE static void Setup(
Handle<JSArrayBuffer> array_buffer, Isolate* isolate, bool is_external,
void* data, size_t allocated_length,
SharedFlag shared = SharedFlag::kNotShared, bool is_wasm_memory = false);
// Returns false if array buffer contents could not be allocated.
// In this case, |array_buffer| will not be set up.
static bool SetupAllocatingData(
Handle<JSArrayBuffer> array_buffer, Isolate* isolate,
size_t allocated_length, bool initialize = true,
SharedFlag shared = SharedFlag::kNotShared) V8_WARN_UNUSED_RESULT;
// Dispatched behavior.
DECL_PRINTER(JSArrayBuffer)
DECL_VERIFIER(JSArrayBuffer)
static const int kByteLengthOffset = JSObject::kHeaderSize;
// The rest of the fields are not JSObjects, so they are not iterated over in
// objects-body-descriptors-inl.h.
static const int kBackingStoreOffset = kByteLengthOffset + kPointerSize;
static const int kBitFieldSlot = kBackingStoreOffset + kPointerSize;
#if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
static const int kBitFieldOffset = kBitFieldSlot;
#else
static const int kBitFieldOffset = kBitFieldSlot + kInt32Size;
#endif
static const int kSize = kBitFieldSlot + kPointerSize;
static const int kSizeWithEmbedderFields =
kSize + v8::ArrayBuffer::kEmbedderFieldCount * kPointerSize;
// Iterates all fields in the object including internal ones except
// kBackingStoreOffset and kBitFieldSlot.
class BodyDescriptor;
// No weak fields.
typedef BodyDescriptor BodyDescriptorWeak;
class IsExternal : public BitField<bool, 1, 1> {};
class IsNeuterable : public BitField<bool, 2, 1> {};
class WasNeutered : public BitField<bool, 3, 1> {};
class IsShared : public BitField<bool, 4, 1> {};
class IsGrowable : public BitField<bool, 5, 1> {};
class IsWasmMemory : public BitField<bool, 6, 1> {};
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer);
};
class JSArrayBufferView : public JSObject {
public:
// [buffer]: ArrayBuffer that this typed array views.
DECL_ACCESSORS(buffer, Object)
// [byte_offset]: offset of typed array in bytes.
DECL_ACCESSORS(byte_offset, Object)
// [byte_length]: length of typed array in bytes.
DECL_ACCESSORS(byte_length, Object)
DECL_CAST(JSArrayBufferView)
DECL_VERIFIER(JSArrayBufferView)
inline bool WasNeutered() const;
static const int kBufferOffset = JSObject::kHeaderSize;
static const int kByteOffsetOffset = kBufferOffset + kPointerSize;
static const int kByteLengthOffset = kByteOffsetOffset + kPointerSize;
static const int kViewSize = kByteLengthOffset + kPointerSize;
private:
#ifdef VERIFY_HEAP
DECL_ACCESSORS(raw_byte_offset, Object)
DECL_ACCESSORS(raw_byte_length, Object)
#endif
DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBufferView);
};
class JSTypedArray : public JSArrayBufferView {
public:
// [length]: length of typed array in elements.
DECL_ACCESSORS(length, Object)
inline size_t length_value() const;
// ES6 9.4.5.3
V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty(
Isolate* isolate, Handle<JSTypedArray> o, Handle<Object> key,
PropertyDescriptor* desc, ShouldThrow should_throw);
DECL_CAST(JSTypedArray)
ExternalArrayType type();
V8_EXPORT_PRIVATE size_t element_size();
Handle<JSArrayBuffer> GetBuffer();
// Whether the buffer's backing store is on-heap or off-heap.
inline bool is_on_heap() const;
static inline MaybeHandle<JSTypedArray> Validate(Isolate* isolate,
Handle<Object> receiver,
const char* method_name);
// Dispatched behavior.
DECL_PRINTER(JSTypedArray)
DECL_VERIFIER(JSTypedArray)
static const int kLengthOffset = kViewSize;
static const int kSize = kLengthOffset + kPointerSize;
static const int kSizeWithEmbedderFields =
kSize + v8::ArrayBufferView::kEmbedderFieldCount * kPointerSize;
private:
static Handle<JSArrayBuffer> MaterializeArrayBuffer(
Handle<JSTypedArray> typed_array);
#ifdef VERIFY_HEAP
DECL_ACCESSORS(raw_length, Object)
#endif
DISALLOW_IMPLICIT_CONSTRUCTORS(JSTypedArray);
};
class JSDataView : public JSArrayBufferView {
public:
DECL_CAST(JSDataView)
// Dispatched behavior.
DECL_PRINTER(JSDataView)
DECL_VERIFIER(JSDataView)
static const int kSize = kViewSize;
static const int kSizeWithEmbedderFields =
kSize + v8::ArrayBufferView::kEmbedderFieldCount * kPointerSize;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSDataView);
};
} // namespace internal
} // namespace v8

View File

@ -16,6 +16,7 @@
#include "src/objects-inl.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-collection-inl.h"
#include "src/objects/js-generator-inl.h"

View File

@ -7,7 +7,7 @@
#include "src/base/platform/mutex.h"
#include "src/conversions-inl.h"
#include "src/heap/factory.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/runtime/runtime-utils.h"
// Implement Atomic accesses to SharedArrayBuffers as defined in the

View File

@ -10,6 +10,7 @@
#include "src/frames-inl.h"
#include "src/isolate-inl.h"
#include "src/messages.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/runtime/runtime-utils.h"
#include "src/v8threads.h"

View File

@ -9,7 +9,7 @@
#include "src/conversions-inl.h"
#include "src/futex-emulation.h"
#include "src/globals.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-array-buffer-inl.h"
// Implement Futex API for SharedArrayBuffers as defined in the
// SharedArrayBuffer draft spec, found here:

View File

@ -8,7 +8,7 @@
#include "src/heap/heap-inl.h"
#include "src/messages.h"
#include "src/objects-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/runtime/runtime-utils.h"
#include "src/runtime/runtime.h"

View File

@ -9,6 +9,7 @@
#include "src/isolate.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/hash-table.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/maybe-object.h"
#include "src/objects/string.h"

View File

@ -7,6 +7,7 @@
#include "src/assembler-inl.h"
#include "src/interpreter/interpreter.h"
#include "src/objects/code.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/map.h"
#include "src/snapshot/builtin-serializer-allocator.h"

View File

@ -16,6 +16,7 @@
#include "src/isolate.h"
#include "src/maybe-handles-inl.h"
#include "src/objects-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-collection-inl.h"
#include "src/objects/js-regexp-inl.h"
#include "src/objects/ordered-hash-table-inl.h"

View File

@ -6,7 +6,7 @@
#include "src/heap/heap-inl.h"
#include "src/objects-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-memory.h"

View File

@ -11,7 +11,7 @@
#include "src/base/platform/mutex.h"
#include "src/flags.h"
#include "src/handles.h"
#include "src/objects/js-array.h"
#include "src/objects/js-array-buffer.h"
namespace v8 {
namespace internal {

View File

@ -11,6 +11,7 @@
#include "src/debug/interface-types.h"
#include "src/frames-inl.h"
#include "src/objects.h"
#include "src/objects/js-array-inl.h"
#include "src/property-descriptor.h"
#include "src/simulator.h"
#include "src/snapshot/snapshot.h"

View File

@ -9,7 +9,7 @@
#include "src/contexts-inl.h"
#include "src/heap/heap-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/managed.h"
#include "src/v8memory.h"
#include "src/wasm/wasm-code-manager.h"

View File

@ -8,7 +8,7 @@
#include "src/heap/spaces.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-utils.h"

View File

@ -52,6 +52,7 @@
#include "src/lookup.h"
#include "src/objects-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-promise-inl.h"
#include "src/parsing/preparse-data.h"

View File

@ -17,6 +17,7 @@
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/promise-inl.h"
#include "test/cctest/compiler/code-assembler-tester.h"

View File

@ -40,6 +40,7 @@
#include "src/heap/spaces.h"
#include "src/macro-assembler-inl.h"
#include "src/objects-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/runtime/runtime.h"
#include "src/snapshot/builtin-deserializer.h"