Skip to content

Commit

Permalink
[JSC] Use destroying delete for ArrayBufferView
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=245653

Reviewed by Darin Adler.

Set TypedArrayType in ArrayBufferView field and use destroying delete for destruction and the other tiny functions.
So, we remove vtable pointer for that class.

* Source/JavaScriptCore/runtime/ArrayBufferView.cpp:
(JSC::ArrayBufferView::ArrayBufferView):
(JSC::ArrayBufferView::visitDerived):
(JSC::ArrayBufferView::visitDerived const):
(JSC::ArrayBufferView::wrap):
(JSC::ArrayBufferView::operator delete):
* Source/JavaScriptCore/runtime/ArrayBufferView.h:
(JSC::ArrayBufferView::getType const):
* Source/JavaScriptCore/runtime/DataView.cpp:
(JSC::DataView::DataView):
(JSC::DataView::wrapImpl):
(JSC::DataView::wrap): Deleted.
* Source/JavaScriptCore/runtime/DataView.h:
* Source/JavaScriptCore/runtime/GenericTypedArrayView.h:
* Source/JavaScriptCore/runtime/GenericTypedArrayViewInlines.h:
(JSC::GenericTypedArrayView<Adaptor>::GenericTypedArrayView):
(JSC::GenericTypedArrayView<Adaptor>::wrapImpl):
(JSC::GenericTypedArrayView<Adaptor>::wrap): Deleted.
* Source/JavaScriptCore/runtime/TypedArrayType.h:

Canonical link: https://commits.webkit.org/254891@main
  • Loading branch information
Constellation committed Sep 27, 2022
1 parent 62267f9 commit 4f3aa59
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 49 deletions.
5 changes: 2 additions & 3 deletions Source/JavaScriptCore/bytecode/AccessCase.cpp
Expand Up @@ -2846,10 +2846,9 @@ bool AccessCase::canBeShared(const AccessCase& lhs, const AccessCase& rhs)
void AccessCase::operator delete(AccessCase* accessCase, std::destroying_delete_t)
{
accessCase->runWithDowncast([](auto* accessCase) {
using T = std::decay_t<decltype(*accessCase)>;
accessCase->~T();
std::destroy_at(accessCase);
std::decay_t<decltype(*accessCase)>::freeAfterDestruction(accessCase);
});
AccessCase::freeAfterDestruction(accessCase);
}

Ref<AccessCase> AccessCase::clone() const
Expand Down
5 changes: 2 additions & 3 deletions Source/JavaScriptCore/bytecode/Watchpoint.cpp
Expand Up @@ -64,10 +64,9 @@ inline void Watchpoint::runWithDowncast(const Func& func)
void Watchpoint::operator delete(Watchpoint* watchpoint, std::destroying_delete_t)
{
watchpoint->runWithDowncast([](auto* derived) {
using T = std::decay_t<decltype(*derived)>;
derived->~T();
std::destroy_at(derived);
std::decay_t<decltype(*derived)>::freeAfterDestruction(derived);
});
Watchpoint::freeAfterDestruction(watchpoint);
}

Watchpoint::~Watchpoint()
Expand Down
5 changes: 2 additions & 3 deletions Source/JavaScriptCore/jit/JITStubRoutine.cpp
Expand Up @@ -106,9 +106,8 @@ void JITStubRoutine::markRequiredObjects(SlotVisitor& visitor)
void JITStubRoutine::operator delete(JITStubRoutine* stubRoutine, std::destroying_delete_t)
{
stubRoutine->runWithDowncast([&](auto* derived) {
using T = std::decay_t<decltype(*derived)>;
derived->~T();
T::freeAfterDestruction(derived);
std::destroy_at(derived);
std::decay_t<decltype(*derived)>::freeAfterDestruction(derived);
});
}

Expand Down
45 changes: 39 additions & 6 deletions Source/JavaScriptCore/runtime/ArrayBufferView.cpp
Expand Up @@ -26,11 +26,14 @@
#include "config.h"
#include "ArrayBufferView.h"

#include "DataView.h"
#include "TypedArrayInlines.h"

namespace JSC {

ArrayBufferView::ArrayBufferView(
RefPtr<ArrayBuffer>&& buffer, size_t byteOffset, size_t byteLength)
: m_byteOffset(byteOffset)
ArrayBufferView::ArrayBufferView(TypedArrayType type, RefPtr<ArrayBuffer>&& buffer, size_t byteOffset, size_t byteLength)
: m_type(type)
, m_byteOffset(byteOffset)
, m_byteLength(byteLength)
, m_buffer(WTFMove(buffer))
{
Expand All @@ -41,10 +44,40 @@ ArrayBufferView::ArrayBufferView(
m_baseAddress = BaseAddress(static_cast<char*>(m_buffer->data()) + m_byteOffset, byteLength);
}

ArrayBufferView::~ArrayBufferView()
template<typename Visitor> constexpr decltype(auto) ArrayBufferView::visitDerived(Visitor&& visitor)
{
if (!m_isDetachable)
m_buffer->unpin();
switch (m_type) {
case TypedArrayType::NotTypedArray:
case TypedArrayType::TypeDataView:
return std::invoke(std::forward<Visitor>(visitor), static_cast<DataView&>(*this));
#define DECLARE_TYPED_ARRAY_TYPE(name) \
case TypedArrayType::Type##name: \
return std::invoke(std::forward<Visitor>(visitor), static_cast<name##Array&>(*this));
FOR_EACH_TYPED_ARRAY_TYPE_EXCLUDING_DATA_VIEW(DECLARE_TYPED_ARRAY_TYPE)
#undef DECLARE_TYPED_ARRAY_TYPE
}
ASSERT_NOT_REACHED();
}

template<typename Visitor> constexpr decltype(auto) ArrayBufferView::visitDerived(Visitor&& visitor) const
{
return const_cast<ArrayBufferView&>(*this).visitDerived([&](auto& value) {
return std::invoke(std::forward<Visitor>(visitor), std::as_const(value));
});
}

JSArrayBufferView* ArrayBufferView::wrap(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject)
{
return visitDerived([&](auto& derived) { return derived.wrapImpl(lexicalGlobalObject, globalObject); });
}

void ArrayBufferView::operator delete(ArrayBufferView* value, std::destroying_delete_t)
{
value->visitDerived([](auto& value) {
using T = std::decay_t<decltype(value)>;
std::destroy_at(&value);
T::freeAfterDestruction(&value);
});
}

void ArrayBufferView::setDetachable(bool flag)
Expand Down
24 changes: 18 additions & 6 deletions Source/JavaScriptCore/runtime/ArrayBufferView.h
Expand Up @@ -41,7 +41,7 @@ class CallFrame;

class ArrayBufferView : public RefCounted<ArrayBufferView> {
public:
virtual TypedArrayType getType() const = 0;
TypedArrayType getType() const { return m_type; }

bool isDetached() const
{
Expand Down Expand Up @@ -90,7 +90,7 @@ class ArrayBufferView : public RefCounted<ArrayBufferView> {
JS_EXPORT_PRIVATE void setDetachable(bool);
bool isDetachable() const { return m_isDetachable; }

JS_EXPORT_PRIVATE virtual ~ArrayBufferView();
inline ~ArrayBufferView();

// Helper to verify byte offset is size aligned.
static bool verifyByteOffsetAlignment(size_t byteOffset, size_t elementSize)
Expand All @@ -109,11 +109,13 @@ class ArrayBufferView : public RefCounted<ArrayBufferView> {
return false;
return true;
}

virtual JSArrayBufferView* wrap(JSGlobalObject*, JSGlobalObject*) = 0;


JS_EXPORT_PRIVATE JSArrayBufferView* wrap(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject);

JS_EXPORT_PRIVATE void operator delete(ArrayBufferView*, std::destroying_delete_t);

protected:
JS_EXPORT_PRIVATE ArrayBufferView(RefPtr<ArrayBuffer>&&, size_t byteOffset, size_t byteLength);
JS_EXPORT_PRIVATE ArrayBufferView(TypedArrayType, RefPtr<ArrayBuffer>&&, size_t byteOffset, size_t byteLength);

inline bool setImpl(ArrayBufferView*, size_t byteOffset);

Expand Down Expand Up @@ -148,6 +150,7 @@ class ArrayBufferView : public RefCounted<ArrayBufferView> {
*numElements = std::min(remainingElements, *numElements);
}

TypedArrayType m_type { TypedArrayType::NotTypedArray };
#if USE(LARGE_TYPED_ARRAYS)
uint64_t m_byteOffset : 63;
#else
Expand All @@ -162,9 +165,18 @@ class ArrayBufferView : public RefCounted<ArrayBufferView> {

private:
friend class ArrayBuffer;
template<typename Visitor> constexpr decltype(auto) visitDerived(Visitor&&);
template<typename Visitor> constexpr decltype(auto) visitDerived(Visitor&&) const;

RefPtr<ArrayBuffer> m_buffer;
};

ArrayBufferView::~ArrayBufferView()
{
if (!m_isDetachable)
m_buffer->unpin();
}

bool ArrayBufferView::setImpl(ArrayBufferView* array, size_t byteOffset)
{
if (!isSumSmallerThanOrEqual(byteOffset, array->byteLength(), byteLength()))
Expand Down
4 changes: 2 additions & 2 deletions Source/JavaScriptCore/runtime/DataView.cpp
Expand Up @@ -33,7 +33,7 @@
namespace JSC {

DataView::DataView(RefPtr<ArrayBuffer>&& buffer, size_t byteOffset, size_t byteLength)
: ArrayBufferView(WTFMove(buffer), byteOffset, byteLength)
: ArrayBufferView(TypeDataView, WTFMove(buffer), byteOffset, byteLength)
{
}

Expand All @@ -49,7 +49,7 @@ Ref<DataView> DataView::create(RefPtr<ArrayBuffer>&& buffer)
return create(WTFMove(buffer), 0, byteLength);
}

JSArrayBufferView* DataView::wrap(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject)
JSArrayBufferView* DataView::wrapImpl(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject)
{
return JSDataView::create(
lexicalGlobalObject, globalObject->typedArrayStructure(TypeDataView), possiblySharedBuffer(), byteOffset(),
Expand Down
7 changes: 1 addition & 6 deletions Source/JavaScriptCore/runtime/DataView.h
Expand Up @@ -34,13 +34,8 @@ class DataView final : public ArrayBufferView {
public:
JS_EXPORT_PRIVATE static Ref<DataView> create(RefPtr<ArrayBuffer>&&, size_t byteOffset, size_t length);
static Ref<DataView> create(RefPtr<ArrayBuffer>&&);

TypedArrayType getType() const final
{
return TypeDataView;
}

JSArrayBufferView* wrap(JSGlobalObject*, JSGlobalObject*) final;
JSArrayBufferView* wrapImpl(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject);

template<typename T>
T get(size_t offset, bool littleEndian, bool* status = nullptr)
Expand Down
7 changes: 1 addition & 6 deletions Source/JavaScriptCore/runtime/GenericTypedArrayView.h
Expand Up @@ -102,13 +102,8 @@ class GenericTypedArrayView final : public ArrayBufferView {
{
return isSumSmallerThanOrEqual(offset, count, this->length());
}

TypedArrayType getType() const final
{
return Adaptor::typeValue;
}

JSArrayBufferView* wrap(JSGlobalObject*, JSGlobalObject*) final;
JSArrayBufferView* wrapImpl(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject);

private:
GenericTypedArrayView(RefPtr<ArrayBuffer>&&, size_t byteOffset, size_t length);
Expand Down
4 changes: 2 additions & 2 deletions Source/JavaScriptCore/runtime/GenericTypedArrayViewInlines.h
Expand Up @@ -33,7 +33,7 @@ namespace JSC {
template<typename Adaptor>
GenericTypedArrayView<Adaptor>::GenericTypedArrayView(
RefPtr<ArrayBuffer>&& buffer, size_t byteOffset, size_t length)
: ArrayBufferView(WTFMove(buffer), byteOffset, length * sizeof(typename Adaptor::Type))
: ArrayBufferView(Adaptor::typeValue, WTFMove(buffer), byteOffset, length * sizeof(typename Adaptor::Type))
{
ASSERT((length / sizeof(typename Adaptor::Type)) < std::numeric_limits<size_t>::max());
}
Expand Down Expand Up @@ -120,7 +120,7 @@ GenericTypedArrayView<Adaptor>::tryCreateUninitialized(size_t length)
}

template<typename Adaptor>
JSArrayBufferView* GenericTypedArrayView<Adaptor>::wrap(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject)
JSArrayBufferView* GenericTypedArrayView<Adaptor>::wrapImpl(JSGlobalObject* lexicalGlobalObject, JSGlobalObject* globalObject)
{
UNUSED_PARAM(lexicalGlobalObject);
return Adaptor::JSViewType::create(globalObject->vm(), globalObject->typedArrayStructure(Adaptor::typeValue), this);
Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/runtime/TypedArrayType.h
Expand Up @@ -50,7 +50,7 @@ struct ClassInfo;
FOR_EACH_TYPED_ARRAY_TYPE_EXCLUDING_DATA_VIEW(macro) \
macro(DataView)

enum TypedArrayType {
enum TypedArrayType : uint8_t {
NotTypedArray,
#define DECLARE_TYPED_ARRAY_TYPE(name) Type ## name,
FOR_EACH_TYPED_ARRAY_TYPE(DECLARE_TYPED_ARRAY_TYPE)
Expand Down
5 changes: 2 additions & 3 deletions Source/JavaScriptCore/wasm/WasmCallee.cpp
Expand Up @@ -123,10 +123,9 @@ void Callee::operator delete(Callee* callee, std::destroying_delete_t)
{
CalleeRegistry::singleton().unregisterCallee(callee);
callee->runWithDowncast([](auto* derived) {
using T = std::decay_t<decltype(*derived)>;
derived->~T();
std::destroy_at(derived);
std::decay_t<decltype(*derived)>::freeAfterDestruction(derived);
});
Callee::freeAfterDestruction(callee);
}

const HandlerInfo* Callee::handlerForIndex(Instance& instance, unsigned index, const Tag* tag)
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/css/CSSValue.cpp
Expand Up @@ -259,8 +259,8 @@ void CSSValue::operator delete(CSSValue* value, std::destroying_delete_t)
{
value->visitDerived([](auto& value) {
std::destroy_at(&value);
std::decay_t<decltype(value)>::freeAfterDestruction(&value);
});
freeAfterDestruction(value);
}

Ref<DeprecatedCSSOMValue> CSSValue::createDeprecatedCSSOMWrapper(CSSStyleDeclaration& styleDeclaration) const
Expand Down
12 changes: 8 additions & 4 deletions Source/WebCore/css/DeprecatedCSSOMValue.cpp
Expand Up @@ -33,18 +33,22 @@ namespace WebCore {

void DeprecatedCSSOMValue::operator delete(DeprecatedCSSOMValue* value, std::destroying_delete_t)
{
auto destroyAndFree = [&](auto& value) {
std::destroy_at(&value);
std::decay_t<decltype(value)>::freeAfterDestruction(&value);
};

switch (value->classType()) {
case ClassType::Complex:
std::destroy_at(downcast<DeprecatedCSSOMComplexValue>(value));
destroyAndFree(downcast<DeprecatedCSSOMComplexValue>(*value));
break;
case ClassType::Primitive:
std::destroy_at(downcast<DeprecatedCSSOMPrimitiveValue>(value));
destroyAndFree(downcast<DeprecatedCSSOMPrimitiveValue>(*value));
break;
case ClassType::List:
std::destroy_at(downcast<DeprecatedCSSOMValueList>(value));
destroyAndFree(downcast<DeprecatedCSSOMValueList>(*value));
break;
}
freeAfterDestruction(value);
}

unsigned short DeprecatedCSSOMValue::cssValueType() const
Expand Down
10 changes: 7 additions & 3 deletions Source/WebCore/dom/Node.cpp
Expand Up @@ -345,11 +345,15 @@ void Node::trackForDebugging()

inline void NodeRareData::operator delete(NodeRareData* nodeRareData, std::destroying_delete_t)
{
auto destroyAndFree = [&](auto& value) {
std::destroy_at(&value);
std::decay_t<decltype(value)>::freeAfterDestruction(&value);
};

if (nodeRareData->m_isElementRareData)
static_cast<ElementRareData*>(nodeRareData)->~ElementRareData();
destroyAndFree(static_cast<ElementRareData&>(*nodeRareData));
else
nodeRareData->~NodeRareData();
NodeRareData::freeAfterDestruction(nodeRareData);
destroyAndFree(*nodeRareData);
}

Node::Node(Document& document, ConstructionType type)
Expand Down

0 comments on commit 4f3aa59

Please sign in to comment.