Changeset 240456 in webkit
- Timestamp:
- Jan 24, 2019 4:49:44 PM (5 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r240449 r240456 1 2019-01-24 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] SharedArrayBufferConstructor and ArrayBufferConstructor should not have their own IsoSubspace 4 https://bugs.webkit.org/show_bug.cgi?id=193774 5 6 Reviewed by Mark Lam. 7 8 We put all the instances of InternalFunction and its subclasses in IsoSubspace to make safer from UAF. 9 But since IsoSubspace requires the memory layout of instances is the same, we created different IsoSubspace 10 for subclasses of InternalFunction if sizeof(subclass) != sizeof(InternalFunction). One example is 11 ArrayBufferConstructor and SharedArrayBufferConstructor. But it is too costly to allocate 16KB page just 12 for these two constructor instances. They are only two instances per JSGlobalObject. 13 14 This patch makes sizeof(ArrayBufferConstructor) == sizeof(InternalFunction) so that they can use IsoSubspace 15 of InternalFunction. We introduce JSGenericArrayBufferConstructor, and it takes ArrayBufferSharingMode as 16 its template parameter. We define JSArrayBufferConstructor as JSGenericArrayBufferConstructor<ArrayBufferSharingMode::Default> 17 and JSSharedArrayBufferConstructor as JSGenericArrayBufferConstructor<ArrayBufferSharingMode::Shared> so that 18 we do not need to hold ArrayBufferSharingMode in the field of the constructor. This change removes IsoSubspace 19 for ArrayBufferConstructors, and reduces the memory usage. 20 21 * runtime/JSArrayBufferConstructor.cpp: 22 (JSC::JSGenericArrayBufferConstructor<sharingMode>::JSGenericArrayBufferConstructor): 23 (JSC::JSGenericArrayBufferConstructor<sharingMode>::finishCreation): 24 (JSC::JSGenericArrayBufferConstructor<sharingMode>::constructArrayBuffer): 25 (JSC::JSGenericArrayBufferConstructor<sharingMode>::createStructure): 26 (JSC::JSGenericArrayBufferConstructor<sharingMode>::info): 27 (JSC::JSArrayBufferConstructor::JSArrayBufferConstructor): Deleted. 28 (JSC::JSArrayBufferConstructor::finishCreation): Deleted. 29 (JSC::JSArrayBufferConstructor::create): Deleted. 30 (JSC::JSArrayBufferConstructor::createStructure): Deleted. 31 (JSC::constructArrayBuffer): Deleted. 32 * runtime/JSArrayBufferConstructor.h: 33 * runtime/JSGlobalObject.cpp: 34 (JSC::JSGlobalObject::init): 35 * runtime/JSGlobalObject.h: 36 * runtime/VM.cpp: 37 (JSC::VM::VM): 38 * runtime/VM.h: 39 1 40 2019-01-24 Yusuke Suzuki <ysuzuki@apple.com> 2 41 -
trunk/Source/JavaScriptCore/runtime/JSArrayBufferConstructor.cpp
r233122 r240456 39 39 40 40 static EncodedJSValue JSC_HOST_CALL arrayBufferFuncIsView(ExecState*); 41 static EncodedJSValue JSC_HOST_CALL callArrayBuffer(ExecState*); 41 42 43 template<> 42 44 const ClassInfo JSArrayBufferConstructor::s_info = { 43 45 "Function", &Base::s_info, nullptr, nullptr, … … 45 47 }; 46 48 47 static EncodedJSValue JSC_HOST_CALL callArrayBuffer(ExecState*); 48 static EncodedJSValue JSC_HOST_CALL constructArrayBuffer(ExecState*); 49 template<> 50 const ClassInfo JSSharedArrayBufferConstructor::s_info = { 51 "Function", &Base::s_info, nullptr, nullptr, 52 CREATE_METHOD_TABLE(JSSharedArrayBufferConstructor) 53 }; 49 54 50 JSArrayBufferConstructor::JSArrayBufferConstructor(VM& vm, Structure* structure, ArrayBufferSharingMode sharingMode) 51 : Base(vm, structure, callArrayBuffer, constructArrayBuffer)52 , m_sharingMode(sharingMode)55 template<ArrayBufferSharingMode sharingMode> 56 JSGenericArrayBufferConstructor<sharingMode>::JSGenericArrayBufferConstructor(VM& vm, Structure* structure) 57 : Base(vm, structure, callArrayBuffer, JSGenericArrayBufferConstructor<sharingMode>::constructArrayBuffer) 53 58 { 54 59 } 55 60 56 void JSArrayBufferConstructor::finishCreation(VM& vm, JSArrayBufferPrototype* prototype, GetterSetter* speciesSymbol) 61 template<ArrayBufferSharingMode sharingMode> 62 void JSGenericArrayBufferConstructor<sharingMode>::finishCreation(VM& vm, JSArrayBufferPrototype* prototype, GetterSetter* speciesSymbol) 57 63 { 58 Base::finishCreation(vm, arrayBufferSharingModeName( m_sharingMode));64 Base::finishCreation(vm, arrayBufferSharingModeName(sharingMode)); 59 65 putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); 60 66 putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); 61 67 putDirectNonIndexAccessor(vm, vm.propertyNames->speciesSymbol, speciesSymbol, PropertyAttribute::Accessor | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum); 62 68 63 if ( m_sharingMode == ArrayBufferSharingMode::Default) {69 if (sharingMode == ArrayBufferSharingMode::Default) { 64 70 JSGlobalObject* globalObject = this->globalObject(vm); 65 71 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->isView, arrayBufferFuncIsView, static_cast<unsigned>(PropertyAttribute::DontEnum), 1); … … 68 74 } 69 75 70 JSArrayBufferConstructor* JSArrayBufferConstructor::create(VM& vm, Structure* structure, JSArrayBufferPrototype* prototype, GetterSetter* speciesSymbol, ArrayBufferSharingMode sharingMode) 71 { 72 JSArrayBufferConstructor* result = 73 new (NotNull, allocateCell<JSArrayBufferConstructor>(vm.heap)) 74 JSArrayBufferConstructor(vm, structure, sharingMode); 75 result->finishCreation(vm, prototype, speciesSymbol); 76 return result; 77 } 78 79 Structure* JSArrayBufferConstructor::createStructure( 80 VM& vm, JSGlobalObject* globalObject, JSValue prototype) 81 { 82 return Structure::create( 83 vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info()); 84 } 85 86 static EncodedJSValue JSC_HOST_CALL constructArrayBuffer(ExecState* exec) 76 template<ArrayBufferSharingMode sharingMode> 77 EncodedJSValue JSC_HOST_CALL JSGenericArrayBufferConstructor<sharingMode>::constructArrayBuffer(ExecState* exec) 87 78 { 88 79 VM& vm = exec->vm(); 89 80 auto scope = DECLARE_THROW_SCOPE(vm); 90 81 91 JSArrayBufferConstructor* constructor = 92 jsCast<JSArrayBufferConstructor*>(exec->jsCallee()); 82 JSGenericArrayBufferConstructor* constructor = jsCast<JSGenericArrayBufferConstructor*>(exec->jsCallee()); 93 83 94 Structure* arrayBufferStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), constructor->globalObject(vm)->arrayBufferStructure( constructor->sharingMode()));84 Structure* arrayBufferStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), constructor->globalObject(vm)->arrayBufferStructure(sharingMode)); 95 85 RETURN_IF_EXCEPTION(scope, { }); 96 86 … … 110 100 return JSValue::encode(throwOutOfMemoryError(exec, scope)); 111 101 112 if ( constructor->sharingMode()== ArrayBufferSharingMode::Shared)102 if (sharingMode == ArrayBufferSharingMode::Shared) 113 103 buffer->makeShared(); 114 ASSERT( constructor->sharingMode()== buffer->sharingMode());104 ASSERT(sharingMode == buffer->sharingMode()); 115 105 116 106 JSArrayBuffer* result = JSArrayBuffer::create(vm, arrayBufferStructure, WTFMove(buffer)); 117 107 return JSValue::encode(result); 108 } 109 110 template<ArrayBufferSharingMode sharingMode> 111 Structure* JSGenericArrayBufferConstructor<sharingMode>::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 112 { 113 return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info()); 114 } 115 116 template<ArrayBufferSharingMode sharingMode> 117 const ClassInfo* JSGenericArrayBufferConstructor<sharingMode>::info() 118 { 119 return &JSGenericArrayBufferConstructor<sharingMode>::s_info; 118 120 } 119 121 … … 132 134 return JSValue::encode(jsBoolean(jsDynamicCast<JSArrayBufferView*>(exec->vm(), exec->argument(0)))); 133 135 } 134 136 137 // Instantiate JSGenericArrayBufferConstructors. 138 template class JSGenericArrayBufferConstructor<ArrayBufferSharingMode::Shared>; 139 template class JSGenericArrayBufferConstructor<ArrayBufferSharingMode::Default>; 135 140 136 141 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSArrayBufferConstructor.h
r230813 r240456 34 34 class GetterSetter; 35 35 36 class JSArrayBufferConstructor final : public InternalFunction { 36 template<ArrayBufferSharingMode sharingMode> 37 class JSGenericArrayBufferConstructor final : public InternalFunction { 37 38 public: 38 typedef InternalFunction Base;39 using Base = InternalFunction; 39 40 40 template<typename CellType> 41 static IsoSubspace* subspaceFor(VM& vm) 41 protected: 42 JSGenericArrayBufferConstructor(VM&, Structure*); 43 void finishCreation(VM&, JSArrayBufferPrototype*, GetterSetter* speciesSymbol); 44 45 static EncodedJSValue JSC_HOST_CALL constructArrayBuffer(ExecState*); 46 47 public: 48 static JSGenericArrayBufferConstructor* create(VM& vm, Structure* structure, JSArrayBufferPrototype* prototype, GetterSetter* speciesSymbol) 42 49 { 43 return &vm.arrayBufferConstructorSpace; 50 JSGenericArrayBufferConstructor* result = 51 new (NotNull, allocateCell<JSGenericArrayBufferConstructor>(vm.heap)) JSGenericArrayBufferConstructor(vm, structure); 52 result->finishCreation(vm, prototype, speciesSymbol); 53 return result; 44 54 } 45 55 46 protected:47 JSArrayBufferConstructor(VM&, Structure*, ArrayBufferSharingMode);48 void finishCreation(VM&, JSArrayBufferPrototype*, GetterSetter* speciesSymbol);49 50 public:51 static JSArrayBufferConstructor* create(VM&, Structure*, JSArrayBufferPrototype*, GetterSetter* speciesSymbol, ArrayBufferSharingMode);52 53 DECLARE_INFO;54 55 56 static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype); 56 57 57 ArrayBufferSharingMode sharingMode() const { return m_sharingMode; } 58 59 private: 60 ArrayBufferSharingMode m_sharingMode; 58 static const ClassInfo s_info; // This is never accessed directly, since that would break linkage on some compilers. 59 static const ClassInfo* info(); 61 60 }; 62 61 62 using JSArrayBufferConstructor = JSGenericArrayBufferConstructor<ArrayBufferSharingMode::Default>; 63 using JSSharedArrayBufferConstructor = JSGenericArrayBufferConstructor<ArrayBufferSharingMode::Shared>; 64 static_assert(sizeof(JSArrayBufferConstructor::Base) == sizeof(JSArrayBufferConstructor), ""); 65 static_assert(sizeof(JSSharedArrayBufferConstructor::Base) == sizeof(JSSharedArrayBufferConstructor), ""); 66 63 67 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r240273 r240456 677 677 m_regExpConstructor.set(vm, this, RegExpConstructor::create(vm, RegExpConstructor::createStructure(vm, this, m_functionPrototype.get()), m_regExpPrototype.get(), m_speciesGetterSetter.get())); 678 678 679 JSArrayBufferConstructor* arrayBufferConstructor = JSArrayBufferConstructor::create(vm, JSArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_arrayBufferPrototype.get(), m_speciesGetterSetter.get() , ArrayBufferSharingMode::Default);679 JSArrayBufferConstructor* arrayBufferConstructor = JSArrayBufferConstructor::create(vm, JSArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_arrayBufferPrototype.get(), m_speciesGetterSetter.get()); 680 680 m_arrayBufferPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, arrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum)); 681 681 682 682 #if ENABLE(SHARED_ARRAY_BUFFER) 683 JS ArrayBufferConstructor* sharedArrayBufferConstructor = nullptr;684 sharedArrayBufferConstructor = JS ArrayBufferConstructor::create(vm, JSArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_sharedArrayBufferPrototype.get(), m_speciesGetterSetter.get(), ArrayBufferSharingMode::Shared);683 JSSharedArrayBufferConstructor* sharedArrayBufferConstructor = nullptr; 684 sharedArrayBufferConstructor = JSSharedArrayBufferConstructor::create(vm, JSSharedArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_sharedArrayBufferPrototype.get(), m_speciesGetterSetter.get()); 685 685 m_sharedArrayBufferPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, sharedArrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum)); 686 686 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r240273 r240456 83 83 class IntlObject; 84 84 class JSArrayBuffer; 85 class JSArrayBufferConstructor;86 85 class JSArrayBufferPrototype; 87 86 class JSCallee; … … 94 93 class JSPromisePrototype; 95 94 class JSSharedArrayBuffer; 96 class JSSharedArrayBufferConstructor;97 95 class JSSharedArrayBufferPrototype; 98 96 class JSTypedArrayViewConstructor; -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r240273 r240456 293 293 , eagerlySweptDestructibleObjectSpace("Eagerly Swept JSDestructibleObject", heap, destructibleObjectHeapCellType.get(), fastMallocAllocator.get()) 294 294 , segmentedVariableObjectSpace("JSSegmentedVariableObjectSpace", heap, segmentedVariableObjectHeapCellType.get(), fastMallocAllocator.get()) 295 , arrayBufferConstructorSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), JSArrayBufferConstructor)296 295 , asyncFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSAsyncFunction) 297 296 , asyncGeneratorFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSAsyncGeneratorFunction) -
trunk/Source/JavaScriptCore/runtime/VM.h
r240273 r240456 368 368 CompleteSubspace segmentedVariableObjectSpace; 369 369 370 IsoSubspace arrayBufferConstructorSpace;371 370 IsoSubspace asyncFunctionSpace; 372 371 IsoSubspace asyncGeneratorFunctionSpace;
Note: See TracChangeset
for help on using the changeset viewer.