Changeset 240465 in webkit
- Timestamp:
- Jan 24, 2019 6:47:58 PM (5 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r240457 r240465 1 2019-01-24 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] ErrorConstructor should not have own IsoSubspace 4 https://bugs.webkit.org/show_bug.cgi?id=193800 5 6 Reviewed by Saam Barati. 7 8 Similar to r240456, sizeof(ErrorConstructor) != sizeof(InternalFunction), and that is why we have 9 IsoSubspace errorConstructorSpace in VM. But it is allocated only one-per-JSGlobalObject, and it is 10 too costly to have IsoSubspace which allocates 16KB. Since stackTraceLimit information is per 11 JSGlobalObject information, we should have m_stackTraceLimit in JSGlobalObject instead and put 12 ErrorConstructor in InternalFunction's IsoSubspace. As r230813 (moving InternalFunction and subclasses 13 into IsoSubspaces) described, 14 15 "subclasses that are the same size as InternalFunction share its subspace. I did this because the subclasses 16 appear to just override methods, which are called dynamically via the structure or class of the object. 17 So, I don't see a type confusion risk if UAF is used to allocate one kind of InternalFunction over another." 18 19 Then, putting ErrorConstructor in InternalFunction IsoSubspace is fine since it meets the above condition. 20 This patch removes m_stackTraceLimit in ErrorConstructor, and drops IsoSubspace for errorConstructorSpace. 21 This reduces the memory usage. 22 23 * interpreter/Interpreter.h: 24 * runtime/Error.cpp: 25 (JSC::getStackTrace): 26 * runtime/ErrorConstructor.cpp: 27 (JSC::ErrorConstructor::ErrorConstructor): 28 (JSC::ErrorConstructor::finishCreation): 29 (JSC::constructErrorConstructor): 30 (JSC::callErrorConstructor): 31 (JSC::ErrorConstructor::put): 32 (JSC::ErrorConstructor::deleteProperty): 33 (JSC::Interpreter::constructWithErrorConstructor): Deleted. 34 (JSC::Interpreter::callErrorConstructor): Deleted. 35 * runtime/ErrorConstructor.h: 36 * runtime/JSGlobalObject.cpp: 37 (JSC::JSGlobalObject::JSGlobalObject): 38 (JSC::JSGlobalObject::init): 39 (JSC::JSGlobalObject::visitChildren): 40 * runtime/JSGlobalObject.h: 41 (JSC::JSGlobalObject::stackTraceLimit const): 42 (JSC::JSGlobalObject::setStackTraceLimit): 43 (JSC::JSGlobalObject::errorConstructor const): Deleted. 44 * runtime/VM.cpp: 45 (JSC::VM::VM): 46 * runtime/VM.h: 47 1 48 2019-01-24 Joseph Pecoraro <pecoraro@apple.com> 2 49 -
trunk/Source/JavaScriptCore/interpreter/Interpreter.h
r237547 r240465 118 118 static String stackTraceAsString(VM&, const Vector<StackFrame>&); 119 119 120 static EncodedJSValue JSC_HOST_CALL constructWithErrorConstructor(ExecState*);121 static EncodedJSValue JSC_HOST_CALL callErrorConstructor(ExecState*);122 120 static EncodedJSValue JSC_HOST_CALL constructWithNativeErrorConstructor(ExecState*); 123 121 static EncodedJSValue JSC_HOST_CALL callNativeErrorConstructor(ExecState*); -
trunk/Source/JavaScriptCore/runtime/Error.cpp
r240246 r240465 162 162 { 163 163 JSGlobalObject* globalObject = obj->globalObject(vm); 164 ErrorConstructor* errorConstructor = globalObject->errorConstructor(); 165 if (!errorConstructor->stackTraceLimit()) 164 if (!globalObject->stackTraceLimit()) 166 165 return nullptr; 167 166 168 167 size_t framesToSkip = useCurrentFrame ? 0 : 1; 169 168 std::unique_ptr<Vector<StackFrame>> stackTrace = std::make_unique<Vector<StackFrame>>(); 170 vm.interpreter->getStackTrace(obj, *stackTrace, framesToSkip, errorConstructor->stackTraceLimit().value());169 vm.interpreter->getStackTrace(obj, *stackTrace, framesToSkip, globalObject->stackTraceLimit().value()); 171 170 if (!stackTrace->isEmpty()) 172 171 ASSERT_UNUSED(exec, exec == vm.topCallFrame || exec->isGlobalExec()); -
trunk/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
r236697 r240465 34 34 const ClassInfo ErrorConstructor::s_info = { "Function", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ErrorConstructor) }; 35 35 36 static EncodedJSValue JSC_HOST_CALL callErrorConstructor(ExecState*); 37 static EncodedJSValue JSC_HOST_CALL constructErrorConstructor(ExecState*); 38 36 39 ErrorConstructor::ErrorConstructor(VM& vm, Structure* structure) 37 : InternalFunction(vm, structure, Interpreter::callErrorConstructor, Interpreter::constructWithErrorConstructor)40 : InternalFunction(vm, structure, callErrorConstructor, constructErrorConstructor) 38 41 { 39 42 } … … 45 48 putDirectWithoutTransition(vm, vm.propertyNames->prototype, errorPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); 46 49 putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); 47 48 unsigned defaultStackTraceLimit = Options::defaultErrorStackTraceLimit(); 49 m_stackTraceLimit = defaultStackTraceLimit; 50 putDirectWithoutTransition(vm, vm.propertyNames->stackTraceLimit, jsNumber(defaultStackTraceLimit), static_cast<unsigned>(PropertyAttribute::None)); 50 putDirectWithoutTransition(vm, vm.propertyNames->stackTraceLimit, jsNumber(globalObject(vm)->stackTraceLimit().valueOr(Options::defaultErrorStackTraceLimit())), static_cast<unsigned>(PropertyAttribute::None)); 51 51 } 52 52 53 53 // ECMA 15.9.3 54 54 55 EncodedJSValue JSC_HOST_CALL Interpreter::constructWithErrorConstructor(ExecState* exec)55 EncodedJSValue JSC_HOST_CALL constructErrorConstructor(ExecState* exec) 56 56 { 57 57 VM& vm = exec->vm(); … … 63 63 } 64 64 65 EncodedJSValue JSC_HOST_CALL Interpreter::callErrorConstructor(ExecState* exec)65 EncodedJSValue JSC_HOST_CALL callErrorConstructor(ExecState* exec) 66 66 { 67 67 JSValue message = exec->argument(0); … … 80 80 effectiveLimit = std::max(0., effectiveLimit); 81 81 effectiveLimit = std::min(effectiveLimit, static_cast<double>(std::numeric_limits<unsigned>::max())); 82 thisObject-> m_stackTraceLimit = static_cast<unsigned>(effectiveLimit);82 thisObject->globalObject(vm)->setStackTraceLimit(static_cast<unsigned>(effectiveLimit)); 83 83 } else 84 thisObject-> m_stackTraceLimit = { };84 thisObject->globalObject(vm)->setStackTraceLimit(WTF::nullopt); 85 85 } 86 86 … … 94 94 95 95 if (propertyName == vm.propertyNames->stackTraceLimit) 96 thisObject-> m_stackTraceLimit = { };96 thisObject->globalObject(vm)->setStackTraceLimit(WTF::nullopt); 97 97 98 98 return Base::deleteProperty(thisObject, exec, propertyName); -
trunk/Source/JavaScriptCore/runtime/ErrorConstructor.h
r239427 r240465 30 30 class ErrorConstructor final : public InternalFunction { 31 31 public: 32 typedef InternalFunction Base; 33 34 template<typename CellType> 35 static IsoSubspace* subspaceFor(VM& vm) 36 { 37 return &vm.errorConstructorSpace; 38 } 32 using Base = InternalFunction; 39 33 40 34 static ErrorConstructor* create(VM& vm, Structure* structure, ErrorPrototype* errorPrototype, GetterSetter*) … … 52 46 } 53 47 54 Optional<unsigned> stackTraceLimit() const { return m_stackTraceLimit; }55 56 48 protected: 57 49 void finishCreation(VM&, ErrorPrototype*); … … 63 55 ErrorConstructor(VM&, Structure*); 64 56 65 Optional<unsigned> m_stackTraceLimit;66 57 }; 67 58 59 static_assert(sizeof(ErrorConstructor) == sizeof(InternalFunction), ""); 60 68 61 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r240456 r240465 361 361 , m_numberToStringWatchpoint(IsWatched) 362 362 , m_runtimeFlags() 363 , m_stackTraceLimit(Options::defaultErrorStackTraceLimit()) 363 364 , m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable) 364 365 { … … 701 702 #undef CREATE_CONSTRUCTOR_FOR_SIMPLE_TYPE 702 703 703 m_errorConstructor.set(vm, this, errorConstructor);704 704 m_promiseConstructor.set(vm, this, promiseConstructor); 705 705 m_internalPromiseConstructor.set(vm, this, internalPromiseConstructor); … … 879 879 GlobalPropertyInfo(vm.propertyNames->builtinNames().importModulePrivateName(), privateFuncImportModule, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 880 880 GlobalPropertyInfo(vm.propertyNames->builtinNames().enqueueJobPrivateName(), JSFunction::create(vm, this, 0, String(), enqueueJob), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 881 GlobalPropertyInfo(vm.propertyNames->builtinNames().ErrorPrivateName(), m_errorConstructor.get(), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),881 GlobalPropertyInfo(vm.propertyNames->builtinNames().ErrorPrivateName(), errorConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 882 882 GlobalPropertyInfo(vm.propertyNames->builtinNames().RangeErrorPrivateName(), m_rangeErrorConstructor.get(), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), 883 883 GlobalPropertyInfo(vm.propertyNames->builtinNames().TypeErrorPrivateName(), m_typeErrorConstructor.get(), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), … … 1549 1549 visitor.append(thisObject->m_stackOverflowFrameCallee); 1550 1550 visitor.append(thisObject->m_regExpConstructor); 1551 visitor.append(thisObject->m_errorConstructor);1552 1551 visitor.append(thisObject->m_nativeErrorPrototypeStructure); 1553 1552 visitor.append(thisObject->m_nativeErrorStructure); -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r240456 r240465 260 260 WriteBarrier<JSCallee> m_stackOverflowFrameCallee; 261 261 WriteBarrier<RegExpConstructor> m_regExpConstructor; 262 WriteBarrier<ErrorConstructor> m_errorConstructor;263 262 WriteBarrier<Structure> m_nativeErrorPrototypeStructure; 264 263 WriteBarrier<Structure> m_nativeErrorStructure; … … 499 498 RuntimeFlags m_runtimeFlags; 500 499 ConsoleClient* m_consoleClient { nullptr }; 500 Optional<unsigned> m_stackTraceLimit; 501 501 502 502 #if !ASSERT_DISABLED … … 531 531 #endif 532 532 533 Optional<unsigned> stackTraceLimit() const { return m_stackTraceLimit; } 534 void setStackTraceLimit(Optional<unsigned> value) { m_stackTraceLimit = value; } 535 533 536 protected: 534 537 JS_EXPORT_PRIVATE explicit JSGlobalObject(VM&, Structure*, const GlobalObjectMethodTable* = nullptr); … … 574 577 RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); } 575 578 576 ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); }577 579 ArrayConstructor* arrayConstructor() const { return m_arrayConstructor.get(); } 578 580 ObjectConstructor* objectConstructor() const { return m_objectConstructor.get(); } -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r240456 r240465 298 298 , callbackFunctionSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), JSCallbackFunction) 299 299 , customGetterSetterFunctionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSCustomGetterSetterFunction) 300 , errorConstructorSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), ErrorConstructor)301 300 , executableToCodeBlockEdgeSpace ISO_SUBSPACE_INIT(heap, cellDangerousBitsHeapCellType.get(), ExecutableToCodeBlockEdge) 302 301 , functionSpace ISO_SUBSPACE_INIT(heap, cellJSValueOOBHeapCellType.get(), JSFunction) -
trunk/Source/JavaScriptCore/runtime/VM.h
r240456 r240465 373 373 IsoSubspace callbackFunctionSpace; 374 374 IsoSubspace customGetterSetterFunctionSpace; 375 IsoSubspace errorConstructorSpace;376 375 IsoSubspace executableToCodeBlockEdgeSpace; 377 376 IsoSubspace functionSpace;
Note: See TracChangeset
for help on using the changeset viewer.