Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (240455 => 240456)
--- trunk/Source/_javascript_Core/ChangeLog 2019-01-25 00:35:19 UTC (rev 240455)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-01-25 00:49:44 UTC (rev 240456)
@@ -1,5 +1,44 @@
2019-01-24 Yusuke Suzuki <[email protected]>
+ [JSC] SharedArrayBufferConstructor and ArrayBufferConstructor should not have their own IsoSubspace
+ https://bugs.webkit.org/show_bug.cgi?id=193774
+
+ Reviewed by Mark Lam.
+
+ We put all the instances of InternalFunction and its subclasses in IsoSubspace to make safer from UAF.
+ But since IsoSubspace requires the memory layout of instances is the same, we created different IsoSubspace
+ for subclasses of InternalFunction if sizeof(subclass) != sizeof(InternalFunction). One example is
+ ArrayBufferConstructor and SharedArrayBufferConstructor. But it is too costly to allocate 16KB page just
+ for these two constructor instances. They are only two instances per JSGlobalObject.
+
+ This patch makes sizeof(ArrayBufferConstructor) == sizeof(InternalFunction) so that they can use IsoSubspace
+ of InternalFunction. We introduce JSGenericArrayBufferConstructor, and it takes ArrayBufferSharingMode as
+ its template parameter. We define JSArrayBufferConstructor as JSGenericArrayBufferConstructor<ArrayBufferSharingMode::Default>
+ and JSSharedArrayBufferConstructor as JSGenericArrayBufferConstructor<ArrayBufferSharingMode::Shared> so that
+ we do not need to hold ArrayBufferSharingMode in the field of the constructor. This change removes IsoSubspace
+ for ArrayBufferConstructors, and reduces the memory usage.
+
+ * runtime/JSArrayBufferConstructor.cpp:
+ (JSC::JSGenericArrayBufferConstructor<sharingMode>::JSGenericArrayBufferConstructor):
+ (JSC::JSGenericArrayBufferConstructor<sharingMode>::finishCreation):
+ (JSC::JSGenericArrayBufferConstructor<sharingMode>::constructArrayBuffer):
+ (JSC::JSGenericArrayBufferConstructor<sharingMode>::createStructure):
+ (JSC::JSGenericArrayBufferConstructor<sharingMode>::info):
+ (JSC::JSArrayBufferConstructor::JSArrayBufferConstructor): Deleted.
+ (JSC::JSArrayBufferConstructor::finishCreation): Deleted.
+ (JSC::JSArrayBufferConstructor::create): Deleted.
+ (JSC::JSArrayBufferConstructor::createStructure): Deleted.
+ (JSC::constructArrayBuffer): Deleted.
+ * runtime/JSArrayBufferConstructor.h:
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::init):
+ * runtime/JSGlobalObject.h:
+ * runtime/VM.cpp:
+ (JSC::VM::VM):
+ * runtime/VM.h:
+
+2019-01-24 Yusuke Suzuki <[email protected]>
+
stress/const-semantics.js fails a dfg-eager / ftl-eager run with an ASAN release build.
https://bugs.webkit.org/show_bug.cgi?id=190693
Modified: trunk/Source/_javascript_Core/runtime/JSArrayBufferConstructor.cpp (240455 => 240456)
--- trunk/Source/_javascript_Core/runtime/JSArrayBufferConstructor.cpp 2019-01-25 00:35:19 UTC (rev 240455)
+++ trunk/Source/_javascript_Core/runtime/JSArrayBufferConstructor.cpp 2019-01-25 00:49:44 UTC (rev 240456)
@@ -38,29 +38,35 @@
namespace JSC {
static EncodedJSValue JSC_HOST_CALL arrayBufferFuncIsView(ExecState*);
+static EncodedJSValue JSC_HOST_CALL callArrayBuffer(ExecState*);
+template<>
const ClassInfo JSArrayBufferConstructor::s_info = {
"Function", &Base::s_info, nullptr, nullptr,
CREATE_METHOD_TABLE(JSArrayBufferConstructor)
};
-static EncodedJSValue JSC_HOST_CALL callArrayBuffer(ExecState*);
-static EncodedJSValue JSC_HOST_CALL constructArrayBuffer(ExecState*);
+template<>
+const ClassInfo JSSharedArrayBufferConstructor::s_info = {
+ "Function", &Base::s_info, nullptr, nullptr,
+ CREATE_METHOD_TABLE(JSSharedArrayBufferConstructor)
+};
-JSArrayBufferConstructor::JSArrayBufferConstructor(VM& vm, Structure* structure, ArrayBufferSharingMode sharingMode)
- : Base(vm, structure, callArrayBuffer, constructArrayBuffer)
- , m_sharingMode(sharingMode)
+template<ArrayBufferSharingMode sharingMode>
+JSGenericArrayBufferConstructor<sharingMode>::JSGenericArrayBufferConstructor(VM& vm, Structure* structure)
+ : Base(vm, structure, callArrayBuffer, JSGenericArrayBufferConstructor<sharingMode>::constructArrayBuffer)
{
}
-void JSArrayBufferConstructor::finishCreation(VM& vm, JSArrayBufferPrototype* prototype, GetterSetter* speciesSymbol)
+template<ArrayBufferSharingMode sharingMode>
+void JSGenericArrayBufferConstructor<sharingMode>::finishCreation(VM& vm, JSArrayBufferPrototype* prototype, GetterSetter* speciesSymbol)
{
- Base::finishCreation(vm, arrayBufferSharingModeName(m_sharingMode));
+ Base::finishCreation(vm, arrayBufferSharingModeName(sharingMode));
putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
putDirectNonIndexAccessor(vm, vm.propertyNames->speciesSymbol, speciesSymbol, PropertyAttribute::Accessor | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);
- if (m_sharingMode == ArrayBufferSharingMode::Default) {
+ if (sharingMode == ArrayBufferSharingMode::Default) {
JSGlobalObject* globalObject = this->globalObject(vm);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->isView, arrayBufferFuncIsView, static_cast<unsigned>(PropertyAttribute::DontEnum), 1);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().isViewPrivateName(), arrayBufferFuncIsView, static_cast<unsigned>(PropertyAttribute::DontEnum), 1);
@@ -67,31 +73,15 @@
}
}
-JSArrayBufferConstructor* JSArrayBufferConstructor::create(VM& vm, Structure* structure, JSArrayBufferPrototype* prototype, GetterSetter* speciesSymbol, ArrayBufferSharingMode sharingMode)
+template<ArrayBufferSharingMode sharingMode>
+EncodedJSValue JSC_HOST_CALL JSGenericArrayBufferConstructor<sharingMode>::constructArrayBuffer(ExecState* exec)
{
- JSArrayBufferConstructor* result =
- new (NotNull, allocateCell<JSArrayBufferConstructor>(vm.heap))
- JSArrayBufferConstructor(vm, structure, sharingMode);
- result->finishCreation(vm, prototype, speciesSymbol);
- return result;
-}
-
-Structure* JSArrayBufferConstructor::createStructure(
- VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-{
- return Structure::create(
- vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info());
-}
-
-static EncodedJSValue JSC_HOST_CALL constructArrayBuffer(ExecState* exec)
-{
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
- JSArrayBufferConstructor* constructor =
- jsCast<JSArrayBufferConstructor*>(exec->jsCallee());
+ JSGenericArrayBufferConstructor* constructor = jsCast<JSGenericArrayBufferConstructor*>(exec->jsCallee());
- Structure* arrayBufferStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), constructor->globalObject(vm)->arrayBufferStructure(constructor->sharingMode()));
+ Structure* arrayBufferStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), constructor->globalObject(vm)->arrayBufferStructure(sharingMode));
RETURN_IF_EXCEPTION(scope, { });
unsigned length;
@@ -109,14 +99,26 @@
if (!buffer)
return JSValue::encode(throwOutOfMemoryError(exec, scope));
- if (constructor->sharingMode() == ArrayBufferSharingMode::Shared)
+ if (sharingMode == ArrayBufferSharingMode::Shared)
buffer->makeShared();
- ASSERT(constructor->sharingMode() == buffer->sharingMode());
+ ASSERT(sharingMode == buffer->sharingMode());
JSArrayBuffer* result = JSArrayBuffer::create(vm, arrayBufferStructure, WTFMove(buffer));
return JSValue::encode(result);
}
+template<ArrayBufferSharingMode sharingMode>
+Structure* JSGenericArrayBufferConstructor<sharingMode>::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+ return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info());
+}
+
+template<ArrayBufferSharingMode sharingMode>
+const ClassInfo* JSGenericArrayBufferConstructor<sharingMode>::info()
+{
+ return &JSGenericArrayBufferConstructor<sharingMode>::s_info;
+}
+
static EncodedJSValue JSC_HOST_CALL callArrayBuffer(ExecState* exec)
{
VM& vm = exec->vm();
@@ -131,7 +133,10 @@
{
return JSValue::encode(jsBoolean(jsDynamicCast<JSArrayBufferView*>(exec->vm(), exec->argument(0))));
}
-
+// Instantiate JSGenericArrayBufferConstructors.
+template class JSGenericArrayBufferConstructor<ArrayBufferSharingMode::Shared>;
+template class JSGenericArrayBufferConstructor<ArrayBufferSharingMode::Default>;
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/JSArrayBufferConstructor.h (240455 => 240456)
--- trunk/Source/_javascript_Core/runtime/JSArrayBufferConstructor.h 2019-01-25 00:35:19 UTC (rev 240455)
+++ trunk/Source/_javascript_Core/runtime/JSArrayBufferConstructor.h 2019-01-25 00:49:44 UTC (rev 240456)
@@ -33,31 +33,35 @@
class JSArrayBufferPrototype;
class GetterSetter;
-class JSArrayBufferConstructor final : public InternalFunction {
+template<ArrayBufferSharingMode sharingMode>
+class JSGenericArrayBufferConstructor final : public InternalFunction {
public:
- typedef InternalFunction Base;
+ using Base = InternalFunction;
- template<typename CellType>
- static IsoSubspace* subspaceFor(VM& vm)
- {
- return &vm.arrayBufferConstructorSpace;
- }
-
protected:
- JSArrayBufferConstructor(VM&, Structure*, ArrayBufferSharingMode);
+ JSGenericArrayBufferConstructor(VM&, Structure*);
void finishCreation(VM&, JSArrayBufferPrototype*, GetterSetter* speciesSymbol);
+ static EncodedJSValue JSC_HOST_CALL constructArrayBuffer(ExecState*);
+
public:
- static JSArrayBufferConstructor* create(VM&, Structure*, JSArrayBufferPrototype*, GetterSetter* speciesSymbol, ArrayBufferSharingMode);
-
- DECLARE_INFO;
-
+ static JSGenericArrayBufferConstructor* create(VM& vm, Structure* structure, JSArrayBufferPrototype* prototype, GetterSetter* speciesSymbol)
+ {
+ JSGenericArrayBufferConstructor* result =
+ new (NotNull, allocateCell<JSGenericArrayBufferConstructor>(vm.heap)) JSGenericArrayBufferConstructor(vm, structure);
+ result->finishCreation(vm, prototype, speciesSymbol);
+ return result;
+ }
+
static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
- ArrayBufferSharingMode sharingMode() const { return m_sharingMode; }
-
-private:
- ArrayBufferSharingMode m_sharingMode;
+ static const ClassInfo s_info; // This is never accessed directly, since that would break linkage on some compilers.
+ static const ClassInfo* info();
};
+using JSArrayBufferConstructor = JSGenericArrayBufferConstructor<ArrayBufferSharingMode::Default>;
+using JSSharedArrayBufferConstructor = JSGenericArrayBufferConstructor<ArrayBufferSharingMode::Shared>;
+static_assert(sizeof(JSArrayBufferConstructor::Base) == sizeof(JSArrayBufferConstructor), "");
+static_assert(sizeof(JSSharedArrayBufferConstructor::Base) == sizeof(JSSharedArrayBufferConstructor), "");
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (240455 => 240456)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2019-01-25 00:35:19 UTC (rev 240455)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2019-01-25 00:49:44 UTC (rev 240456)
@@ -676,12 +676,12 @@
m_regExpConstructor.set(vm, this, RegExpConstructor::create(vm, RegExpConstructor::createStructure(vm, this, m_functionPrototype.get()), m_regExpPrototype.get(), m_speciesGetterSetter.get()));
- JSArrayBufferConstructor* arrayBufferConstructor = JSArrayBufferConstructor::create(vm, JSArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_arrayBufferPrototype.get(), m_speciesGetterSetter.get(), ArrayBufferSharingMode::Default);
+ JSArrayBufferConstructor* arrayBufferConstructor = JSArrayBufferConstructor::create(vm, JSArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_arrayBufferPrototype.get(), m_speciesGetterSetter.get());
m_arrayBufferPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, arrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
#if ENABLE(SHARED_ARRAY_BUFFER)
- JSArrayBufferConstructor* sharedArrayBufferConstructor = nullptr;
- sharedArrayBufferConstructor = JSArrayBufferConstructor::create(vm, JSArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_sharedArrayBufferPrototype.get(), m_speciesGetterSetter.get(), ArrayBufferSharingMode::Shared);
+ JSSharedArrayBufferConstructor* sharedArrayBufferConstructor = nullptr;
+ sharedArrayBufferConstructor = JSSharedArrayBufferConstructor::create(vm, JSSharedArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_sharedArrayBufferPrototype.get(), m_speciesGetterSetter.get());
m_sharedArrayBufferPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, sharedArrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
AtomicsObject* atomicsObject = AtomicsObject::create(vm, this, AtomicsObject::createStructure(vm, this, m_objectPrototype.get()));
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (240455 => 240456)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2019-01-25 00:35:19 UTC (rev 240455)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2019-01-25 00:49:44 UTC (rev 240456)
@@ -82,7 +82,6 @@
class InputCursor;
class IntlObject;
class JSArrayBuffer;
-class JSArrayBufferConstructor;
class JSArrayBufferPrototype;
class JSCallee;
class JSGlobalObjectDebuggable;
@@ -93,7 +92,6 @@
class JSPromiseConstructor;
class JSPromisePrototype;
class JSSharedArrayBuffer;
-class JSSharedArrayBufferConstructor;
class JSSharedArrayBufferPrototype;
class JSTypedArrayViewConstructor;
class JSTypedArrayViewPrototype;
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (240455 => 240456)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2019-01-25 00:35:19 UTC (rev 240455)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2019-01-25 00:49:44 UTC (rev 240456)
@@ -292,7 +292,6 @@
, destructibleObjectSpace("JSDestructibleObject", heap, destructibleObjectHeapCellType.get(), fastMallocAllocator.get())
, eagerlySweptDestructibleObjectSpace("Eagerly Swept JSDestructibleObject", heap, destructibleObjectHeapCellType.get(), fastMallocAllocator.get())
, segmentedVariableObjectSpace("JSSegmentedVariableObjectSpace", heap, segmentedVariableObjectHeapCellType.get(), fastMallocAllocator.get())
- , arrayBufferConstructorSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), JSArrayBufferConstructor)
, asyncFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSAsyncFunction)
, asyncGeneratorFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSAsyncGeneratorFunction)
, boundFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSBoundFunction)
Modified: trunk/Source/_javascript_Core/runtime/VM.h (240455 => 240456)
--- trunk/Source/_javascript_Core/runtime/VM.h 2019-01-25 00:35:19 UTC (rev 240455)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2019-01-25 00:49:44 UTC (rev 240456)
@@ -367,7 +367,6 @@
CompleteSubspace eagerlySweptDestructibleObjectSpace;
CompleteSubspace segmentedVariableObjectSpace;
- IsoSubspace arrayBufferConstructorSpace;
IsoSubspace asyncFunctionSpace;
IsoSubspace asyncGeneratorFunctionSpace;
IsoSubspace boundFunctionSpace;