Title: [233467] trunk/Source/_javascript_Core
Revision
233467
Author
[email protected]
Date
2018-07-03 10:50:12 -0700 (Tue, 03 Jul 2018)

Log Message

[JSC] Move slowDownAndWasteMemory function to JSArrayBufferView
https://bugs.webkit.org/show_bug.cgi?id=187290

Reviewed by Saam Barati.

slowDownAndWasteMemory is just overridden by typed arrays. Since they are limited,
we do not need to add this function to MethodTable: just dispatching it in JSArrayBufferView
is fine. And slowDownAndWasteMemory only requires the sizeof(element), which can be
easily calculated from JSType.
This patch removes slowDownAndWasteMemory from MethodTable, and moves it to JSArrayBufferView.

* runtime/ClassInfo.h:
* runtime/JSArrayBufferView.cpp:
(JSC::elementSize):
(JSC::JSArrayBufferView::slowDownAndWasteMemory):
* runtime/JSArrayBufferView.h:
* runtime/JSArrayBufferViewInlines.h:
(JSC::JSArrayBufferView::possiblySharedBuffer):
* runtime/JSCell.cpp:
(JSC::JSCell::slowDownAndWasteMemory): Deleted.
* runtime/JSCell.h:
* runtime/JSDataView.cpp:
(JSC::JSDataView::slowDownAndWasteMemory): Deleted.
* runtime/JSDataView.h:
* runtime/JSGenericTypedArrayView.h:
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView<Adaptor>::slowDownAndWasteMemory): Deleted.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (233466 => 233467)


--- trunk/Source/_javascript_Core/ChangeLog	2018-07-03 16:50:57 UTC (rev 233466)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-07-03 17:50:12 UTC (rev 233467)
@@ -1,3 +1,33 @@
+2018-07-03  Yusuke Suzuki  <[email protected]>
+
+        [JSC] Move slowDownAndWasteMemory function to JSArrayBufferView
+        https://bugs.webkit.org/show_bug.cgi?id=187290
+
+        Reviewed by Saam Barati.
+
+        slowDownAndWasteMemory is just overridden by typed arrays. Since they are limited,
+        we do not need to add this function to MethodTable: just dispatching it in JSArrayBufferView
+        is fine. And slowDownAndWasteMemory only requires the sizeof(element), which can be
+        easily calculated from JSType.
+        This patch removes slowDownAndWasteMemory from MethodTable, and moves it to JSArrayBufferView.
+
+        * runtime/ClassInfo.h:
+        * runtime/JSArrayBufferView.cpp:
+        (JSC::elementSize):
+        (JSC::JSArrayBufferView::slowDownAndWasteMemory):
+        * runtime/JSArrayBufferView.h:
+        * runtime/JSArrayBufferViewInlines.h:
+        (JSC::JSArrayBufferView::possiblySharedBuffer):
+        * runtime/JSCell.cpp:
+        (JSC::JSCell::slowDownAndWasteMemory): Deleted.
+        * runtime/JSCell.h:
+        * runtime/JSDataView.cpp:
+        (JSC::JSDataView::slowDownAndWasteMemory): Deleted.
+        * runtime/JSDataView.h:
+        * runtime/JSGenericTypedArrayView.h:
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView<Adaptor>::slowDownAndWasteMemory): Deleted.
+
 2018-07-02  Sukolsak Sakshuwong  <[email protected]>
 
         Regular expressions with ".?" expressions at the start and the end match the entire string

Modified: trunk/Source/_javascript_Core/runtime/ClassInfo.h (233466 => 233467)


--- trunk/Source/_javascript_Core/runtime/ClassInfo.h	2018-07-03 16:50:57 UTC (rev 233466)
+++ trunk/Source/_javascript_Core/runtime/ClassInfo.h	2018-07-03 17:50:12 UTC (rev 233467)
@@ -101,9 +101,6 @@
     using DefineOwnPropertyFunctionPtr = bool (*)(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool);
     DefineOwnPropertyFunctionPtr WTF_METHOD_TABLE_ENTRY(defineOwnProperty);
 
-    using SlowDownAndWasteMemory = ArrayBuffer* (*)(JSArrayBufferView*);
-    SlowDownAndWasteMemory WTF_METHOD_TABLE_ENTRY(slowDownAndWasteMemory);
-
     using GetTypedArrayImpl = RefPtr<ArrayBufferView> (*)(JSArrayBufferView*);
     GetTypedArrayImpl WTF_METHOD_TABLE_ENTRY(getTypedArrayImpl);
 
@@ -174,7 +171,6 @@
         &ClassName::toStringName, \
         &ClassName::customHasInstance, \
         &ClassName::defineOwnProperty, \
-        &ClassName::slowDownAndWasteMemory, \
         &ClassName::getTypedArrayImpl, \
         &ClassName::preventExtensions, \
         &ClassName::isExtensible, \

Modified: trunk/Source/_javascript_Core/runtime/JSArrayBufferView.cpp (233466 => 233467)


--- trunk/Source/_javascript_Core/runtime/JSArrayBufferView.cpp	2018-07-03 16:50:57 UTC (rev 233466)
+++ trunk/Source/_javascript_Core/runtime/JSArrayBufferView.cpp	2018-07-03 17:50:12 UTC (rev 233467)
@@ -28,6 +28,7 @@
 
 #include "JSArrayBuffer.h"
 #include "JSCInlines.h"
+#include "JSTypedArrays.h"
 #include "TypeError.h"
 #include "TypedArrayController.h"
 #include <wtf/Gigacage.h>
@@ -217,6 +218,92 @@
     m_vector.clear();
 }
 
+static const constexpr size_t ElementSizeData[] = {
+    sizeof(typename Int8Adaptor::Type), // Int8ArrayType
+    sizeof(typename Uint8Adaptor::Type), // Uint8ArrayType
+    sizeof(typename Uint8ClampedAdaptor::Type), // Uint8ClampedArrayType
+    sizeof(typename Int16Adaptor::Type), // Int16ArrayType
+    sizeof(typename Uint16Adaptor::Type), // Uint16ArrayType
+    sizeof(typename Int32Adaptor::Type), // Int32ArrayType
+    sizeof(typename Uint32Adaptor::Type), // Uint32ArrayType
+    sizeof(typename Float32Adaptor::Type), // Float32ArrayType
+    sizeof(typename Float64Adaptor::Type), // Float64ArrayType
+};
+
+static_assert(std::is_final<JSInt8Array>::value, "");
+static_assert(std::is_final<JSUint8Array>::value, "");
+static_assert(std::is_final<JSUint8ClampedArray>::value, "");
+static_assert(std::is_final<JSInt16Array>::value, "");
+static_assert(std::is_final<JSUint16Array>::value, "");
+static_assert(std::is_final<JSInt32Array>::value, "");
+static_assert(std::is_final<JSUint32Array>::value, "");
+static_assert(std::is_final<JSFloat32Array>::value, "");
+static_assert(std::is_final<JSFloat64Array>::value, "");
+
+static inline size_t elementSize(JSType type)
+{
+    ASSERT(type >= Int8ArrayType && type <= Float64ArrayType);
+    return ElementSizeData[type - Int8ArrayType];
+}
+
+ArrayBuffer* JSArrayBufferView::slowDownAndWasteMemory()
+{
+    ASSERT(m_mode == FastTypedArray || m_mode == OversizeTypedArray);
+
+    // We play this game because we want this to be callable even from places that
+    // don't have access to ExecState* or the VM, and we only allocate so little
+    // memory here that it's not necessary to trigger a GC - just accounting what
+    // we have done is good enough. The sort of bizarre exception to the "allocating
+    // little memory" is when we transfer a backing buffer into the C heap; this
+    // will temporarily get counted towards heap footprint (incorrectly, in the case
+    // of adopting an oversize typed array) but we don't GC here anyway. That's
+    // almost certainly fine. The worst case is if you created a ton of fast typed
+    // arrays, and did nothing but caused all of them to slow down and waste memory.
+    // In that case, your memory footprint will double before the GC realizes what's
+    // up. But if you do *anything* to trigger a GC watermark check, it will know
+    // that you *had* done those allocations and it will GC appropriately.
+    Heap* heap = Heap::heap(this);
+    VM& vm = *heap->vm();
+    DeferGCForAWhile deferGC(*heap);
+
+    RELEASE_ASSERT(!hasIndexingHeader(vm));
+    Structure* structure = this->structure(vm);
+    setButterfly(vm, Butterfly::createOrGrowArrayRight(
+        butterfly(), vm, this, structure,
+        structure->outOfLineCapacity(), false, 0, 0));
+
+    RefPtr<ArrayBuffer> buffer;
+    unsigned byteLength = m_length * elementSize(type());
+
+    switch (m_mode) {
+    case FastTypedArray:
+        buffer = ArrayBuffer::create(vector(), byteLength);
+        break;
+
+    case OversizeTypedArray:
+        // FIXME: consider doing something like "subtracting" from extra memory
+        // cost, since right now this case will cause the GC to think that we reallocated
+        // the whole buffer.
+        buffer = ArrayBuffer::createAdopted(vector(), byteLength);
+        break;
+
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
+    }
+
+    {
+        auto locker = holdLock(cellLock());
+        butterfly()->indexingHeader()->setArrayBuffer(buffer.get());
+        m_vector.setWithoutBarrier(buffer->data());
+        WTF::storeStoreFence();
+        m_mode = WastefulTypedArray;
+    }
+    heap->addReference(this, buffer.get());
+
+    return buffer.get();
+}
+
 } // namespace JSC
 
 namespace WTF {

Modified: trunk/Source/_javascript_Core/runtime/JSArrayBufferView.h (233466 => 233467)


--- trunk/Source/_javascript_Core/runtime/JSArrayBufferView.h	2018-07-03 16:50:57 UTC (rev 233466)
+++ trunk/Source/_javascript_Core/runtime/JSArrayBufferView.h	2018-07-03 17:50:12 UTC (rev 233467)
@@ -181,6 +181,7 @@
     static RefPtr<ArrayBufferView> toWrapped(VM&, JSValue);
 
 private:
+    JS_EXPORT_PRIVATE ArrayBuffer* slowDownAndWasteMemory();
     static void finalize(JSCell*);
 
 protected:

Modified: trunk/Source/_javascript_Core/runtime/JSArrayBufferViewInlines.h (233466 => 233467)


--- trunk/Source/_javascript_Core/runtime/JSArrayBufferViewInlines.h	2018-07-03 16:50:57 UTC (rev 233466)
+++ trunk/Source/_javascript_Core/runtime/JSArrayBufferViewInlines.h	2018-07-03 17:50:12 UTC (rev 233467)
@@ -50,9 +50,12 @@
         return existingBufferInButterfly();
     case DataViewMode:
         return jsCast<JSDataView*>(this)->possiblySharedBuffer();
-    default:
-        return methodTable()->slowDownAndWasteMemory(this);
+    case FastTypedArray:
+    case OversizeTypedArray:
+        return slowDownAndWasteMemory();
     }
+    ASSERT_NOT_REACHED();
+    return nullptr;
 }
 
 inline ArrayBuffer* JSArrayBufferView::existingBufferInButterfly()

Modified: trunk/Source/_javascript_Core/runtime/JSCell.cpp (233466 => 233467)


--- trunk/Source/_javascript_Core/runtime/JSCell.cpp	2018-07-03 16:50:57 UTC (rev 233466)
+++ trunk/Source/_javascript_Core/runtime/JSCell.cpp	2018-07-03 17:50:12 UTC (rev 233467)
@@ -256,12 +256,6 @@
     return false;
 }
 
-ArrayBuffer* JSCell::slowDownAndWasteMemory(JSArrayBufferView*)
-{
-    RELEASE_ASSERT_NOT_REACHED();
-    return nullptr;
-}
-
 RefPtr<ArrayBufferView> JSCell::getTypedArrayImpl(JSArrayBufferView*)
 {
     RELEASE_ASSERT_NOT_REACHED();

Modified: trunk/Source/_javascript_Core/runtime/JSCell.h (233466 => 233467)


--- trunk/Source/_javascript_Core/runtime/JSCell.h	2018-07-03 16:50:57 UTC (rev 233466)
+++ trunk/Source/_javascript_Core/runtime/JSCell.h	2018-07-03 17:50:12 UTC (rev 233467)
@@ -265,7 +265,6 @@
     static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
-    JS_EXPORT_PRIVATE static ArrayBuffer* slowDownAndWasteMemory(JSArrayBufferView*);
     JS_EXPORT_PRIVATE static RefPtr<ArrayBufferView> getTypedArrayImpl(JSArrayBufferView*);
 
 private:

Modified: trunk/Source/_javascript_Core/runtime/JSDataView.cpp (233466 => 233467)


--- trunk/Source/_javascript_Core/runtime/JSDataView.cpp	2018-07-03 16:50:57 UTC (rev 233466)
+++ trunk/Source/_javascript_Core/runtime/JSDataView.cpp	2018-07-03 17:50:12 UTC (rev 233467)
@@ -180,12 +180,6 @@
     Base::getOwnNonIndexPropertyNames(thisObject, exec, array, mode);
 }
 
-ArrayBuffer* JSDataView::slowDownAndWasteMemory(JSArrayBufferView*)
-{
-    UNREACHABLE_FOR_PLATFORM();
-    return 0;
-}
-
 RefPtr<ArrayBufferView> JSDataView::getTypedArrayImpl(JSArrayBufferView* object)
 {
     JSDataView* thisObject = jsCast<JSDataView*>(object);

Modified: trunk/Source/_javascript_Core/runtime/JSDataView.h (233466 => 233467)


--- trunk/Source/_javascript_Core/runtime/JSDataView.h	2018-07-03 16:50:57 UTC (rev 233466)
+++ trunk/Source/_javascript_Core/runtime/JSDataView.h	2018-07-03 17:50:12 UTC (rev 233467)
@@ -70,7 +70,6 @@
 
     static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
 
-    static ArrayBuffer* slowDownAndWasteMemory(JSArrayBufferView*);
     static RefPtr<ArrayBufferView> getTypedArrayImpl(JSArrayBufferView*);
     
 public:

Modified: trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayView.h (233466 => 233467)


--- trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayView.h	2018-07-03 16:50:57 UTC (rev 233466)
+++ trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayView.h	2018-07-03 17:50:12 UTC (rev 233467)
@@ -290,7 +290,6 @@
 
     // Allocates the full-on native buffer and moves data into the C heap if
     // necessary. Note that this never allocates in the GC heap.
-    static ArrayBuffer* slowDownAndWasteMemory(JSArrayBufferView*);
     static RefPtr<ArrayBufferView> getTypedArrayImpl(JSArrayBufferView*);
 
 private:

Modified: trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h (233466 => 233467)


--- trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h	2018-07-03 16:50:57 UTC (rev 233466)
+++ trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h	2018-07-03 17:50:12 UTC (rev 233467)
@@ -549,63 +549,6 @@
 }
 
 template<typename Adaptor>
-ArrayBuffer* JSGenericTypedArrayView<Adaptor>::slowDownAndWasteMemory(JSArrayBufferView* object)
-{
-    JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(object);
-    
-    // We play this game because we want this to be callable even from places that
-    // don't have access to ExecState* or the VM, and we only allocate so little
-    // memory here that it's not necessary to trigger a GC - just accounting what
-    // we have done is good enough. The sort of bizarro exception to the "allocating
-    // little memory" is when we transfer a backing buffer into the C heap; this
-    // will temporarily get counted towards heap footprint (incorrectly, in the case
-    // of adopting an oversize typed array) but we don't GC here anyway. That's
-    // almost certainly fine. The worst case is if you created a ton of fast typed
-    // arrays, and did nothing but caused all of them to slow down and waste memory.
-    // In that case, your memory footprint will double before the GC realizes what's
-    // up. But if you do *anything* to trigger a GC watermark check, it will know
-    // that you *had* done those allocations and it will GC appropriately.
-    Heap* heap = Heap::heap(thisObject);
-    VM& vm = *heap->vm();
-    DeferGCForAWhile deferGC(*heap);
-    
-    RELEASE_ASSERT(!thisObject->hasIndexingHeader(vm));
-    thisObject->setButterfly(vm, Butterfly::createOrGrowArrayRight(
-        thisObject->butterfly(), vm, thisObject, thisObject->structure(vm),
-        thisObject->structure(vm)->outOfLineCapacity(), false, 0, 0));
-
-    RefPtr<ArrayBuffer> buffer;
-    
-    switch (thisObject->m_mode) {
-    case FastTypedArray:
-        buffer = ArrayBuffer::create(thisObject->vector(), thisObject->byteLength());
-        break;
-        
-    case OversizeTypedArray:
-        // FIXME: consider doing something like "subtracting" from extra memory
-        // cost, since right now this case will cause the GC to think that we reallocated
-        // the whole buffer.
-        buffer = ArrayBuffer::createAdopted(thisObject->vector(), thisObject->byteLength());
-        break;
-        
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-        break;
-    }
-
-    {
-        auto locker = holdLock(thisObject->cellLock());
-        thisObject->butterfly()->indexingHeader()->setArrayBuffer(buffer.get());
-        thisObject->m_vector.setWithoutBarrier(buffer->data());
-        WTF::storeStoreFence();
-        thisObject->m_mode = WastefulTypedArray;
-    }
-    heap->addReference(thisObject, buffer.get());
-    
-    return buffer.get();
-}
-
-template<typename Adaptor>
 RefPtr<ArrayBufferView> JSGenericTypedArrayView<Adaptor>::getTypedArrayImpl(JSArrayBufferView* object)
 {
     JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(object);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to