Skip to content

Commit c9d650e

Browse files
isheludkoCommit Bot
authored andcommitted
[sandbox] Access external pointer in JSArrayBuffer via bottlenecks
Bug: v8:10391 Change-Id: I316a3c5cd986a74d7f46da6d0b85cb3d549be497 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2153209 Commit-Queue: Igor Sheludko <ishell@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#67533}
1 parent c586450 commit c9d650e

14 files changed

Lines changed: 70 additions & 49 deletions

src/builtins/builtins-sharedarraybuffer-gen.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ void SharedArrayBufferBuiltinsAssembler::ValidateSharedTypedArray(
8989
BIND(&not_float_or_clamped);
9090
*out_elements_kind = elements_kind;
9191

92-
TNode<RawPtrT> backing_store = LoadJSArrayBufferBackingStore(array_buffer);
92+
TNode<RawPtrT> backing_store = LoadJSArrayBufferBackingStorePtr(array_buffer);
9393
TNode<UintPtrT> byte_offset = LoadJSArrayBufferViewByteOffset(array);
9494
*out_backing_store = RawPtrAdd(backing_store, Signed(byte_offset));
9595
}

src/builtins/builtins-typed-array-gen.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@ TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::AllocateEmptyOnHeapBuffer(
6565

6666
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kByteLengthOffset,
6767
byte_length);
68-
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kBackingStoreOffset,
69-
IntPtrConstant(0));
68+
StoreJSArrayBufferBackingStore(
69+
buffer,
70+
EncodeExternalPointer(ReinterpretCast<RawPtrT>(IntPtrConstant(0))));
7071
if (V8_ARRAY_BUFFER_EXTENSION_BOOL) {
7172
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kExtensionOffset,
7273
IntPtrConstant(0));
@@ -239,7 +240,7 @@ TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::GetBuffer(
239240

240241
TNode<JSArrayBuffer> buffer = LoadJSArrayBufferViewBuffer(array);
241242
GotoIf(IsDetachedBuffer(buffer), &call_runtime);
242-
TNode<RawPtrT> backing_store = LoadJSArrayBufferBackingStore(buffer);
243+
TNode<RawPtrT> backing_store = LoadJSArrayBufferBackingStorePtr(buffer);
243244
GotoIf(WordEqual(backing_store, IntPtrConstant(0)), &call_runtime);
244245
var_result = buffer;
245246
Goto(&done);

src/builtins/data-view.tq

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,16 @@ namespace data_view {
122122
macro LoadDataView8(
123123
buffer: JSArrayBuffer, offset: uintptr, signed: constexpr bool): Smi {
124124
if constexpr (signed) {
125-
return Convert<Smi>(LoadInt8(buffer.backing_store, offset));
125+
return Convert<Smi>(LoadInt8(buffer.backing_store_ptr, offset));
126126
} else {
127-
return Convert<Smi>(LoadUint8(buffer.backing_store, offset));
127+
return Convert<Smi>(LoadUint8(buffer.backing_store_ptr, offset));
128128
}
129129
}
130130

131131
macro LoadDataView16(
132132
buffer: JSArrayBuffer, offset: uintptr, requestedLittleEndian: bool,
133133
signed: constexpr bool): Number {
134-
const dataPointer: RawPtr = buffer.backing_store;
134+
const dataPointer: RawPtr = buffer.backing_store_ptr;
135135

136136
let b0: int32;
137137
let b1: int32;
@@ -158,7 +158,7 @@ namespace data_view {
158158
macro LoadDataView32(
159159
buffer: JSArrayBuffer, offset: uintptr, requestedLittleEndian: bool,
160160
kind: constexpr ElementsKind): Number {
161-
const dataPointer: RawPtr = buffer.backing_store;
161+
const dataPointer: RawPtr = buffer.backing_store_ptr;
162162

163163
const b0: uint32 = LoadUint8(dataPointer, offset);
164164
const b1: uint32 = LoadUint8(dataPointer, offset + 1);
@@ -187,7 +187,7 @@ namespace data_view {
187187
macro LoadDataViewFloat64(
188188
buffer: JSArrayBuffer, offset: uintptr,
189189
requestedLittleEndian: bool): Number {
190-
const dataPointer: RawPtr = buffer.backing_store;
190+
const dataPointer: RawPtr = buffer.backing_store_ptr;
191191

192192
const b0: uint32 = LoadUint8(dataPointer, offset);
193193
const b1: uint32 = LoadUint8(dataPointer, offset + 1);
@@ -329,7 +329,7 @@ namespace data_view {
329329
macro LoadDataViewBigInt(implicit context: Context)(
330330
buffer: JSArrayBuffer, offset: uintptr, requestedLittleEndian: bool,
331331
signed: constexpr bool): BigInt {
332-
const dataPointer: RawPtr = buffer.backing_store;
332+
const dataPointer: RawPtr = buffer.backing_store_ptr;
333333

334334
const b0: uint32 = LoadUint8(dataPointer, offset);
335335
const b1: uint32 = LoadUint8(dataPointer, offset + 1);
@@ -533,13 +533,13 @@ namespace data_view {
533533
void;
534534

535535
macro StoreDataView8(buffer: JSArrayBuffer, offset: uintptr, value: uint32) {
536-
StoreWord8(buffer.backing_store, offset, value & 0xFF);
536+
StoreWord8(buffer.backing_store_ptr, offset, value & 0xFF);
537537
}
538538

539539
macro StoreDataView16(
540540
buffer: JSArrayBuffer, offset: uintptr, value: uint32,
541541
requestedLittleEndian: bool) {
542-
const dataPointer: RawPtr = buffer.backing_store;
542+
const dataPointer: RawPtr = buffer.backing_store_ptr;
543543

544544
const b0: uint32 = value & 0xFF;
545545
const b1: uint32 = (value >>> 8) & 0xFF;
@@ -556,7 +556,7 @@ namespace data_view {
556556
macro StoreDataView32(
557557
buffer: JSArrayBuffer, offset: uintptr, value: uint32,
558558
requestedLittleEndian: bool) {
559-
const dataPointer: RawPtr = buffer.backing_store;
559+
const dataPointer: RawPtr = buffer.backing_store_ptr;
560560

561561
const b0: uint32 = value & 0xFF;
562562
const b1: uint32 = (value >>> 8) & 0xFF;
@@ -579,7 +579,7 @@ namespace data_view {
579579
macro StoreDataView64(
580580
buffer: JSArrayBuffer, offset: uintptr, lowWord: uint32, highWord: uint32,
581581
requestedLittleEndian: bool) {
582-
const dataPointer: RawPtr = buffer.backing_store;
582+
const dataPointer: RawPtr = buffer.backing_store_ptr;
583583

584584
const b0: uint32 = lowWord & 0xFF;
585585
const b1: uint32 = (lowWord >>> 8) & 0xFF;

src/builtins/typed-array-createtypedarray.tq

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace typed_array {
3232
// platforms are self-limiting, because we can't allocate an array bigger
3333
// than our 32-bit arithmetic range anyway. 64 bit platforms could
3434
// theoretically have an offset up to 2^35 - 1.
35-
const backingStore: uintptr = Convert<uintptr>(buffer.backing_store);
35+
const backingStore: uintptr = Convert<uintptr>(buffer.backing_store_ptr);
3636

3737
// Assert no overflow has occurred. Only assert if the mock array buffer
3838
// allocator is NOT used. When the mock array buffer is used, impossibly
@@ -58,10 +58,10 @@ namespace typed_array {
5858
typedArray, elements, byteOffset);
5959
} else {
6060
typed_array::SetJSTypedArrayOffHeapDataPtr(
61-
typedArray, buffer.backing_store, byteOffset);
61+
typedArray, buffer.backing_store_ptr, byteOffset);
6262
assert(
6363
typedArray.data_ptr ==
64-
(buffer.backing_store + Convert<intptr>(byteOffset)));
64+
(buffer.backing_store_ptr + Convert<intptr>(byteOffset)));
6565
}
6666
SetupTypedArrayEmbedderFields(typedArray);
6767
return typedArray;

src/codegen/code-stub-assembler.cc

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12635,15 +12635,9 @@ void CodeStubAssembler::ThrowIfArrayBufferViewBufferIsDetached(
1263512635
ThrowIfArrayBufferIsDetached(context, buffer, method_name);
1263612636
}
1263712637

12638-
TNode<Uint32T> CodeStubAssembler::LoadJSArrayBufferBitField(
12638+
TNode<RawPtrT> CodeStubAssembler::LoadJSArrayBufferBackingStorePtr(
1263912639
TNode<JSArrayBuffer> array_buffer) {
12640-
return LoadObjectField<Uint32T>(array_buffer, JSArrayBuffer::kBitFieldOffset);
12641-
}
12642-
12643-
TNode<RawPtrT> CodeStubAssembler::LoadJSArrayBufferBackingStore(
12644-
TNode<JSArrayBuffer> array_buffer) {
12645-
return LoadObjectField<RawPtrT>(array_buffer,
12646-
JSArrayBuffer::kBackingStoreOffset);
12640+
return DecodeExternalPointer(LoadJSArrayBufferBackingStore(array_buffer));
1264712641
}
1264812642

1264912643
TNode<JSArrayBuffer> CodeStubAssembler::LoadJSArrayBufferViewBuffer(

src/codegen/code-stub-assembler.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3642,8 +3642,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
36423642
TNode<BoolT> IsDebugActive();
36433643

36443644
// JSArrayBuffer helpers
3645-
TNode<Uint32T> LoadJSArrayBufferBitField(TNode<JSArrayBuffer> array_buffer);
3646-
TNode<RawPtrT> LoadJSArrayBufferBackingStore(
3645+
TNode<RawPtrT> LoadJSArrayBufferBackingStorePtr(
36473646
TNode<JSArrayBuffer> array_buffer);
36483647
void ThrowIfArrayBufferIsDetached(SloppyTNode<Context> context,
36493648
TNode<JSArrayBuffer> array_buffer,

src/objects/js-array-buffer-inl.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef V8_OBJECTS_JS_ARRAY_BUFFER_INL_H_
66
#define V8_OBJECTS_JS_ARRAY_BUFFER_INL_H_
77

8+
#include "src/common/external-pointer.h"
89
#include "src/objects/js-array-buffer.h"
910

1011
#include "src/common/external-pointer-inl.h"
@@ -37,12 +38,27 @@ void JSArrayBuffer::set_byte_length(size_t value) {
3738
WriteField<size_t>(kByteLengthOffset, value);
3839
}
3940

40-
void* JSArrayBuffer::backing_store() const {
41-
return reinterpret_cast<void*>(ReadField<Address>(kBackingStoreOffset));
41+
DEF_GETTER(JSArrayBuffer, backing_store, void*) {
42+
ExternalPointer_t encoded_value =
43+
ReadField<ExternalPointer_t>(kBackingStoreOffset);
44+
return reinterpret_cast<void*>(DecodeExternalPointer(isolate, encoded_value));
4245
}
4346

44-
void JSArrayBuffer::set_backing_store(void* value) {
45-
WriteField<Address>(kBackingStoreOffset, reinterpret_cast<Address>(value));
47+
void JSArrayBuffer::set_backing_store(Isolate* isolate, void* value) {
48+
ExternalPointer_t encoded_value =
49+
EncodeExternalPointer(isolate, reinterpret_cast<Address>(value));
50+
WriteField<ExternalPointer_t>(kBackingStoreOffset, encoded_value);
51+
}
52+
53+
uint32_t JSArrayBuffer::GetBackingStoreRefForDeserialization() const {
54+
ExternalPointer_t encoded_value =
55+
ReadField<ExternalPointer_t>(kBackingStoreOffset);
56+
return static_cast<uint32_t>(encoded_value);
57+
}
58+
59+
void JSArrayBuffer::SetBackingStoreRefForSerialization(uint32_t ref) {
60+
ExternalPointer_t encoded_value = ref;
61+
WriteField<ExternalPointer_t>(kBackingStoreOffset, encoded_value);
4662
}
4763

4864
ArrayBufferExtension* JSArrayBuffer::extension() const {

src/objects/js-array-buffer.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ void JSArrayBuffer::Setup(SharedFlag shared,
4545
}
4646
set_extension(nullptr);
4747
if (!backing_store) {
48-
set_backing_store(nullptr);
48+
set_backing_store(GetIsolate(), nullptr);
4949
set_byte_length(0);
5050
} else {
5151
Attach(std::move(backing_store));
@@ -60,19 +60,20 @@ void JSArrayBuffer::Attach(std::shared_ptr<BackingStore> backing_store) {
6060
DCHECK_NOT_NULL(backing_store);
6161
DCHECK_EQ(is_shared(), backing_store->is_shared());
6262
DCHECK(!was_detached());
63-
set_backing_store(backing_store->buffer_start());
63+
Isolate* isolate = GetIsolate();
64+
set_backing_store(isolate, backing_store->buffer_start());
6465
set_byte_length(backing_store->byte_length());
6566
if (backing_store->is_wasm_memory()) set_is_detachable(false);
6667
if (!backing_store->free_on_destruct()) set_is_external(true);
6768
if (V8_ARRAY_BUFFER_EXTENSION_BOOL) {
68-
Heap* heap = GetIsolate()->heap();
69+
Heap* heap = isolate->heap();
6970
ArrayBufferExtension* extension = EnsureExtension();
7071
size_t bytes = backing_store->PerIsolateAccountingLength();
7172
extension->set_accounting_length(bytes);
7273
extension->set_backing_store(std::move(backing_store));
7374
heap->AppendArrayBufferExtension(*this, extension);
7475
} else {
75-
GetIsolate()->heap()->RegisterBackingStore(*this, std::move(backing_store));
76+
isolate->heap()->RegisterBackingStore(*this, std::move(backing_store));
7677
}
7778
}
7879

@@ -103,7 +104,7 @@ void JSArrayBuffer::Detach(bool force_for_wasm_memory) {
103104

104105
DCHECK(!is_shared());
105106
DCHECK(!is_asmjs_memory());
106-
set_backing_store(nullptr);
107+
set_backing_store(isolate, nullptr);
107108
set_byte_length(0);
108109
set_was_detached(true);
109110
}

src/objects/js-array-buffer.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ class JSArrayBuffer : public JSObject {
3333
DECL_PRIMITIVE_ACCESSORS(byte_length, size_t)
3434

3535
// [backing_store]: backing memory for this array
36-
DECL_PRIMITIVE_ACCESSORS(backing_store, void*)
36+
DECL_GETTER(backing_store, void*)
37+
inline void set_backing_store(Isolate* isolate, void* value);
3738

3839
// [extension]: extension object used for GC
3940
DECL_PRIMITIVE_ACCESSORS(extension, ArrayBufferExtension*)
@@ -50,7 +51,7 @@ class JSArrayBuffer : public JSObject {
5051
// is deterministic. Depending on the V8 build mode there could be no padding.
5152
V8_INLINE void clear_padding();
5253

53-
// Bit positions for [bit_field].
54+
// Bit positions for [bit_field].
5455
DEFINE_TORQUE_GENERATED_JS_ARRAY_BUFFER_FLAGS()
5556

5657
// [is_external]: true indicates that the embedder is in charge of freeing the
@@ -110,6 +111,17 @@ class JSArrayBuffer : public JSObject {
110111
void YoungMarkExtension();
111112
void YoungMarkExtensionPromoted();
112113

114+
//
115+
// Serializer/deserializer support.
116+
//
117+
118+
// Backing stores are serialized/deserialized separately. During serialization
119+
// the backing store reference is stored in the backing store field and upon
120+
// deserialization it is converted back to actual external (off-heap) pointer
121+
// value.
122+
inline uint32_t GetBackingStoreRefForDeserialization() const;
123+
inline void SetBackingStoreRefForSerialization(uint32_t ref);
124+
113125
// Dispatched behavior.
114126
DECL_PRINTER(JSArrayBuffer)
115127
DECL_VERIFIER(JSArrayBuffer)

src/objects/js-array-buffer.tq

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ bitfield struct JSArrayBufferFlags extends uint32 {
1212

1313
extern class JSArrayBuffer extends JSObject {
1414
byte_length: uintptr;
15-
backing_store: RawPtr;
15+
backing_store: ExternalPointer;
1616
@if(V8_ARRAY_BUFFER_EXTENSION_BOOL) extension: RawPtr;
1717
@ifnot(V8_ARRAY_BUFFER_EXTENSION_BOOL) extension: void;
1818
bit_field: JSArrayBufferFlags;
@@ -21,6 +21,9 @@ extern class JSArrayBuffer extends JSObject {
2121
@ifnot(TAGGED_SIZE_8_BYTES) optional_padding: void;
2222
}
2323

24+
extern operator '.backing_store_ptr' macro LoadJSArrayBufferBackingStorePtr(
25+
JSArrayBuffer): RawPtr;
26+
2427
@export
2528
macro IsDetachedBuffer(buffer: JSArrayBuffer): bool {
2629
return buffer.bit_field.was_detached;

0 commit comments

Comments
 (0)