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);