| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 4454f5f commit 7bdad94
11 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -36,7 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | 37 | # Reset this number to 0 on major V8 upgrades. | |
| 38 | 38 | # Increment by one for each non-official patch applied to deps/v8. | |
| 39 | - 'v8_embedder_string': '-node.10', | ||
| 39 | + 'v8_embedder_string': '-node.11', | ||
| 40 | 40 | ||
| 41 | 41 | ##### V8 defaults for Node.js ##### | |
| 42 | 42 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -398,7 +398,8 @@ constexpr uint64_t kAllExternalPointerTypeTags[] = { | |||
| 398 | 398 | V(kWasmInternalFunctionCallTargetTag, sandboxed, TAG(17)) \ | |
| 399 | 399 | V(kWasmTypeInfoNativeTypeTag, sandboxed, TAG(18)) \ | |
| 400 | 400 | V(kWasmExportedFunctionDataSignatureTag, sandboxed, TAG(19)) \ | |
| 401 | - V(kWasmContinuationJmpbufTag, sandboxed, TAG(20)) | ||
| 401 | + V(kWasmContinuationJmpbufTag, sandboxed, TAG(20)) \ | ||
| 402 | + V(kArrayBufferExtensionTag, sandboxed, TAG(21)) | ||
| 402 | 403 | ||
| 403 | 404 | // All external pointer tags. | |
| 404 | 405 | #define ALL_EXTERNAL_POINTER_TAGS(V) \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -68,8 +68,15 @@ TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::AllocateEmptyOnHeapBuffer( | |||
| 68 | 68 | UintPtrConstant(0)); | |
| 69 | 69 | StoreSandboxedPointerToObject(buffer, JSArrayBuffer::kBackingStoreOffset, | |
| 70 | 70 | EmptyBackingStoreBufferConstant()); | |
| 71 | + #ifdef V8_COMPRESS_POINTERS | ||
| 72 | + // When pointer compression is enabled, the extension slot contains a | ||
| 73 | + // (lazily-initialized) external pointer handle. | ||
| 74 | + StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kExtensionOffset, | ||
| 75 | + ExternalPointerHandleNullConstant()); | ||
| 76 | + #else | ||
| 71 | 77 | StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kExtensionOffset, | |
| 72 | 78 | IntPtrConstant(0)); | |
| 79 | + #endif | ||
| 73 | 80 | for (int offset = JSArrayBuffer::kHeaderSize; | |
| 74 | 81 | offset < JSArrayBuffer::kSizeWithEmbedderFields; offset += kTaggedSize) { | |
| 75 | 82 | // TODO(v8:10391, saelo): Handle external pointers in EmbedderDataSlot | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -552,6 +552,9 @@ class V8_EXPORT_PRIVATE CodeAssembler { | |||
| 552 | 552 | TNode<BoolT> BoolConstant(bool value) { | |
| 553 | 553 | return value ? Int32TrueConstant() : Int32FalseConstant(); | |
| 554 | 554 | } | |
| 555 | + TNode<ExternalPointerHandleT> ExternalPointerHandleNullConstant() { | ||
| 556 | + return ReinterpretCast<ExternalPointerHandleT>(Uint32Constant(0)); | ||
| 557 | + } | ||
| 555 | 558 | ||
| 556 | 559 | bool IsMapOffsetConstant(Node* node); | |
| 557 | 560 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -79,65 +79,60 @@ void JSArrayBuffer::SetBackingStoreRefForSerialization(uint32_t ref) { | |||
| 79 | 79 | ||
| 80 | 80 | ArrayBufferExtension* JSArrayBuffer::extension() const { | |
| 81 | 81 | #if V8_COMPRESS_POINTERS | |
| 82 | - // With pointer compression the extension-field might not be | ||
| 83 | - // pointer-aligned. However on ARM64 this field needs to be aligned to | ||
| 84 | - // perform atomic operations on it. Therefore we split the pointer into two | ||
| 85 | - // 32-bit words that we update atomically. We don't have an ABA problem here | ||
| 86 | - // since there can never be an Attach() after Detach() (transitions only | ||
| 87 | - // from NULL --> some ptr --> NULL). | ||
| 88 | - | ||
| 89 | - // Synchronize with publishing release store of non-null extension | ||
| 90 | - uint32_t lo = base::AsAtomic32::Acquire_Load(extension_lo()); | ||
| 91 | - if (lo & kUninitializedTagMask) return nullptr; | ||
| 92 | - | ||
| 93 | - // Synchronize with release store of null extension | ||
| 94 | - uint32_t hi = base::AsAtomic32::Acquire_Load(extension_hi()); | ||
| 95 | - uint32_t verify_lo = base::AsAtomic32::Relaxed_Load(extension_lo()); | ||
| 96 | - if (lo != verify_lo) return nullptr; | ||
| 97 | - | ||
| 98 | - uintptr_t address = static_cast<uintptr_t>(lo); | ||
| 99 | - address |= static_cast<uintptr_t>(hi) << 32; | ||
| 100 | - return reinterpret_cast<ArrayBufferExtension*>(address); | ||
| 82 | + // We need Acquire semantics here when loading the entry, see below. | ||
| 83 | + // Consider adding respective external pointer accessors if non-relaxed | ||
| 84 | + // ordering semantics are ever needed in other places as well. | ||
| 85 | + Isolate* isolate = GetIsolateFromWritableObject(*this); | ||
| 86 | + ExternalPointerHandle handle = | ||
| 87 | + base::AsAtomic32::Acquire_Load(extension_handle_location()); | ||
| 88 | + return reinterpret_cast<ArrayBufferExtension*>( | ||
| 89 | + isolate->external_pointer_table().Get(handle, kArrayBufferExtensionTag)); | ||
| 101 | 90 | #else | |
| 102 | - return base::AsAtomicPointer::Acquire_Load(extension_location()); | ||
| 103 | - #endif | ||
| 91 | + return base::AsAtomicPointer::Acquire_Load(extension_location()); | ||
| 92 | + #endif // V8_COMPRESS_POINTERS | ||
| 104 | 93 | } | |
| 105 | 94 | ||
| 106 | 95 | void JSArrayBuffer::set_extension(ArrayBufferExtension* extension) { | |
| 107 | 96 | #if V8_COMPRESS_POINTERS | |
| 108 | - if (extension != nullptr) { | ||
| 109 | - uintptr_t address = reinterpret_cast<uintptr_t>(extension); | ||
| 110 | - base::AsAtomic32::Relaxed_Store(extension_hi(), | ||
| 111 | - static_cast<uint32_t>(address >> 32)); | ||
| 112 | - base::AsAtomic32::Release_Store(extension_lo(), | ||
| 113 | - static_cast<uint32_t>(address)); | ||
| 114 | - } else { | ||
| 115 | - base::AsAtomic32::Relaxed_Store(extension_lo(), | ||
| 116 | - 0 | kUninitializedTagMask); | ||
| 117 | - base::AsAtomic32::Release_Store(extension_hi(), 0); | ||
| 118 | - } | ||
| 97 | + if (extension != nullptr) { | ||
| 98 | + Isolate* isolate = GetIsolateFromWritableObject(*this); | ||
| 99 | + ExternalPointerTable& table = isolate->external_pointer_table(); | ||
| 100 | + | ||
| 101 | + // The external pointer handle for the extension is initialized lazily and | ||
| 102 | + // so has to be zero here since, once set, the extension field can only be | ||
| 103 | + // cleared, but not changed. | ||
| 104 | + DCHECK_EQ(0, base::AsAtomic32::Relaxed_Load(extension_handle_location())); | ||
| 105 | + | ||
| 106 | + // We need Release semantics here, see above. | ||
| 107 | + ExternalPointerHandle handle = table.AllocateAndInitializeEntry( | ||
| 108 | + isolate, reinterpret_cast<Address>(extension), | ||
| 109 | + kArrayBufferExtensionTag); | ||
| 110 | + base::AsAtomic32::Release_Store(extension_handle_location(), handle); | ||
| 111 | + } else { | ||
| 112 | + // This special handling of nullptr is required as it is used to initialize | ||
| 113 | + // the slot, but is also beneficial when an ArrayBuffer is detached as it | ||
| 114 | + // allows the external pointer table entry to be reclaimed while the | ||
| 115 | + // ArrayBuffer is still alive. | ||
| 116 | + base::AsAtomic32::Release_Store(extension_handle_location(), | ||
| 117 | + kNullExternalPointerHandle); | ||
| 118 | + } | ||
| 119 | 119 | #else | |
| 120 | - base::AsAtomicPointer::Release_Store(extension_location(), extension); | ||
| 121 | - #endif | ||
| 122 | - WriteBarrier::Marking(*this, extension); | ||
| 123 | - } | ||
| 124 | - | ||
| 125 | - ArrayBufferExtension** JSArrayBuffer::extension_location() const { | ||
| 126 | - Address location = field_address(kExtensionOffset); | ||
| 127 | - return reinterpret_cast<ArrayBufferExtension**>(location); | ||
| 120 | + base::AsAtomicPointer::Release_Store(extension_location(), extension); | ||
| 121 | + #endif // V8_COMPRESS_POINTERS | ||
| 122 | + WriteBarrier::Marking(*this, extension); | ||
| 128 | 123 | } | |
| 129 | 124 | ||
| 130 | 125 | #if V8_COMPRESS_POINTERS | |
| 131 | - uint32_t* JSArrayBuffer::extension_lo() const { | ||
| 126 | + ExternalPointerHandle* JSArrayBuffer::extension_handle_location() const { | ||
| 132 | 127 | Address location = field_address(kExtensionOffset); | |
| 133 | - return reinterpret_cast<uint32_t*>(location); | ||
| 128 | + return reinterpret_cast<ExternalPointerHandle*>(location); | ||
| 134 | 129 | } | |
| 135 | - | ||
| 136 | - uint32_t* JSArrayBuffer::extension_hi() const { | ||
| 137 | - Address location = field_address(kExtensionOffset) + sizeof(uint32_t); | ||
| 138 | - return reinterpret_cast<uint32_t*>(location); | ||
| 130 | + #else | ||
| 131 | + ArrayBufferExtension** JSArrayBuffer::extension_location() const { | ||
| 132 | + Address location = field_address(kExtensionOffset); | ||
| 133 | + return reinterpret_cast<ArrayBufferExtension**>(location); | ||
| 139 | 134 | } | |
| 140 | - #endif | ||
| 135 | + #endif // V8_COMPRESS_POINTERS | ||
| 141 | 136 | ||
| 142 | 137 | void JSArrayBuffer::clear_padding() { | |
| 143 | 138 | if (FIELD_SIZE(kOptionalPaddingOffset) != 0) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -160,14 +160,15 @@ class JSArrayBuffer | |||
| 160 | 160 | class BodyDescriptor; | |
| 161 | 161 | ||
| 162 | 162 | private: | |
| 163 | - inline ArrayBufferExtension** extension_location() const; | ||
| 164 | - | ||
| 165 | 163 | #if V8_COMPRESS_POINTERS | |
| 166 | - static const int kUninitializedTagMask = 1; | ||
| 167 | - | ||
| 168 | - inline uint32_t* extension_lo() const; | ||
| 169 | - inline uint32_t* extension_hi() const; | ||
| 170 | - #endif | ||
| 164 | + // When pointer compression is enabled, the pointer to the extension is | ||
| 165 | + // stored in the external pointer table and the object itself only contains a | ||
| 166 | + // 32-bit external pointer handles. This simplifies alignment requirements | ||
| 167 | + // and is also necessary for the sandbox. | ||
| 168 | + inline ExternalPointerHandle* extension_handle_location() const; | ||
| 169 | + #else | ||
| 170 | + inline ArrayBufferExtension** extension_location() const; | ||
| 171 | + #endif // V8_COMPRESS_POINTERS | ||
| 171 | 172 | ||
| 172 | 173 | TQ_OBJECT_CONSTRUCTORS(JSArrayBuffer) | |
| 173 | 174 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,7 +18,7 @@ extern class JSArrayBuffer extends JSObjectWithEmbedderSlots { | |||
| 18 | 18 | raw_max_byte_length: uintptr; | |
| 19 | 19 | // A SandboxedPtr if the sandbox is enabled | |
| 20 | 20 | backing_store: RawPtr; | |
| 21 | - extension: RawPtr; | ||
| 21 | + extension: ExternalPointer; | ||
| 22 | 22 | bit_field: JSArrayBufferFlags; | |
| 23 | 23 | // Pads header size to be a multiple of kTaggedSize. | |
| 24 | 24 | @if(TAGGED_SIZE_8_BYTES) optional_padding: uint32; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -387,6 +387,8 @@ class JSArrayBuffer::BodyDescriptor final : public BodyDescriptorBase { | |||
| 387 | 387 | // JSArrayBuffer instances contain raw data that the GC does not know about. | |
| 388 | 388 | IteratePointers(obj, kPropertiesOrHashOffset, kEndOfTaggedFieldsOffset, v); | |
| 389 | 389 | IterateJSObjectBodyImpl(map, obj, kHeaderSize, object_size, v); | |
| 390 | + v->VisitExternalPointer(map, obj.RawExternalPointerField(kExtensionOffset), | ||
| 391 | + kArrayBufferExtensionTag); | ||
| 390 | 392 | } | |
| 391 | 393 | ||
| 392 | 394 | static inline int SizeOf(Map map, HeapObject object) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -98,7 +98,7 @@ class V8_EXPORT_PRIVATE ExternalPointerTable { | |||
| 98 | 98 | // returning the previous value. The same tag is applied both to decode the | |
| 99 | 99 | // previous value and encode the given value. | |
| 100 | 100 | // | |
| 101 | - // This method is atomic and can call be called from background threads. | ||
| 101 | + // This method is atomic and can be called from background threads. | ||
| 102 | 102 | inline Address Exchange(ExternalPointerHandle handle, Address value, | |
| 103 | 103 | ExternalPointerTag tag); | |
| 104 | 104 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -397,6 +397,7 @@ void Deserializer<IsolateT>::PostProcessNewJSReceiver( | |||
| 397 | 397 | auto buffer = JSArrayBuffer::cast(*obj); | |
| 398 | 398 | uint32_t store_index = buffer.GetBackingStoreRefForDeserialization(); | |
| 399 | 399 | if (store_index == kEmptyBackingStoreRefSentinel) { | |
| 400 | + buffer.set_extension(nullptr); | ||
| 400 | 401 | buffer.set_backing_store(main_thread_isolate(), | |
| 401 | 402 | EmptyBackingStoreBuffer()); | |
| 402 | 403 | } else { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments