GitHub Viewer
/*
* Copyright (C) 2009-2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include
WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace JSC {
class VM;
class ArrayBuffer;
class ArrayBufferView;
class JSArrayBuffer;
namespace Wasm {
class Memory;
}
using ArrayBufferDestructorFunction = RefPtr;
class SharedArrayBufferContents final : public ThreadSafeRefCounted {
public:
enum class Mode : uint8_t {
Default,
WebAssembly,
};
JS_EXPORT_PRIVATE ~SharedArrayBufferContents();
static Ref create(std::span data, std::optional maxByteLength, RefPtr memoryHandle, ArrayBufferDestructorFunction&& destructor, Mode mode)
{
return adoptRef(*new SharedArrayBufferContents(data, maxByteLength, WTF::move(memoryHandle), WTF::move(destructor), mode));
}
void* data() const LIFETIME_BOUND { return m_data.getMayBeNull(); }
size_t sizeInBytes(std::memory_order order) const
{
return m_sizeInBytes.load(order);
}
std::optional maxByteLength() const
{
if (m_hasMaxByteLength)
return m_maxByteLength;
return std::nullopt;
}
Mode mode() const { return m_mode; }
Expected grow(VM&, size_t newByteLength, bool requirePageMultiple);
// One attempt, which cannot collect because it takes no VM. Reports what the caller owes the heap
// once it has released the memory handle's lock: asking for a collection of either kind can run
// finalizers on the calling thread, so neither may be asked for while that lock is held. On
// SyncTryToReclaimMemory the caller must recompute the whole attempt, since the size it was working
// from can move while unlocked.
Expected tryGrow(const AbstractLocker&, size_t newByteLength, bool requirePageMultiple, BufferMemoryResult::Kind&);
void updateSize(size_t sizeInBytes, std::memory_order order = std::memory_order_seq_cst)
{
m_sizeInBytes.store(sizeInBytes, order);
}
BufferMemoryHandle* memoryHandle() const { return m_memoryHandle.get(); }
static constexpr ptrdiff_t offsetOfSizeInBytes() { return OBJECT_OFFSETOF(SharedArrayBufferContents, m_sizeInBytes); }
private:
SharedArrayBufferContents(std::span data, std::optional maxByteLength, RefPtr memoryHandle, ArrayBufferDestructorFunction&& destructor, Mode mode)
: m_data(data.data())
, m_destructor(WTF::move(destructor))
, m_memoryHandle(WTF::move(memoryHandle))
, m_sizeInBytes(data.size())
, m_maxByteLength(maxByteLength.value_or(data.size()))
, m_hasMaxByteLength(!!maxByteLength)
, m_mode(mode)
{
RELEASE_ASSERT(m_maxByteLength