Changeset 233917 in webkit
- Timestamp:
- Jul 18, 2018 11:27:08 AM (6 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r233911 r233917 1 2018-07-18 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [JSC] Root wrapper object in JSON.stringify is not necessary if replacer is not callable 4 https://bugs.webkit.org/show_bug.cgi?id=187752 5 6 Reviewed by Mark Lam. 7 8 JSON.stringify has an implicit root wrapper object since we would like to call replacer 9 with a wrapper object and a property name. While we always create this wrapper object, 10 it is unnecessary if the given replacer is not callable. 11 12 This patch removes wrapper object creation when a replacer is not callable to avoid unnecessary 13 allocations. This change slightly improves the performance of Kraken/json-stringify-tinderbox. 14 15 baseline patched 16 17 json-stringify-tinderbox 39.730+-0.590 ^ 38.853+-0.266 ^ definitely 1.0226x faster 18 19 * runtime/JSONObject.cpp: 20 (JSC::Stringifier::isCallableReplacer const): 21 (JSC::Stringifier::Stringifier): 22 (JSC::Stringifier::stringify): 23 (JSC::Stringifier::appendStringifiedValue): 24 1 25 2018-07-18 Carlos Garcia Campos <cgarcia@igalia.com> 2 26 -
trunk/Source/JavaScriptCore/runtime/JSONObject.cpp
r233122 r233917 121 121 void unindent(); 122 122 void startNewLine(StringBuilder&) const; 123 bool isCallableReplacer() const { return m_replacerCallType != CallType::None; } 123 124 124 125 ExecState* const m_exec; 125 126 JSValue m_replacer; 126 bool m_usingArrayReplacer ;127 bool m_usingArrayReplacer { false }; 127 128 PropertyNameArray m_arrayReplacerPropertyNames; 128 CallType m_replacerCallType ;129 CallType m_replacerCallType { CallType::None }; 129 130 CallData m_replacerCallData; 130 131 String m_gap; … … 221 222 : m_exec(exec) 222 223 , m_replacer(replacer) 223 , m_usingArrayReplacer(false)224 224 , m_arrayReplacerPropertyNames(&exec->vm(), PropertyNameMode::Strings, PrivateSymbolMode::Exclude) 225 , m_replacerCallType(CallType::None)226 225 { 227 226 VM& vm = exec->vm(); … … 265 264 VM& vm = m_exec->vm(); 266 265 auto scope = DECLARE_THROW_SCOPE(vm); 267 JSObject* object = constructEmptyObject(m_exec);268 RETURN_IF_EXCEPTION(scope, jsNull());269 266 270 267 PropertyNameForFunctionCall emptyPropertyName(vm.propertyNames->emptyIdentifier); 271 object->putDirect(vm, vm.propertyNames->emptyIdentifier, value); 268 269 // If the replacer is not callable, root object wrapper is non-user-observable. 270 // We can skip creating this wrapper object. 271 JSObject* object = nullptr; 272 if (isCallableReplacer()) { 273 object = constructEmptyObject(m_exec); 274 RETURN_IF_EXCEPTION(scope, jsNull()); 275 object->putDirect(vm, vm.propertyNames->emptyIdentifier, value); 276 } 272 277 273 278 StringBuilder result; … … 326 331 327 332 // Call the replacer function. 328 if ( m_replacerCallType != CallType::None) {333 if (isCallableReplacer()) { 329 334 MarkedArgumentBuffer args; 330 335 args.append(propertyName.value(m_exec)); 331 336 args.append(value); 332 337 ASSERT(!args.hasOverflowed()); 338 ASSERT(holder.object()); 333 339 value = call(m_exec, m_replacer, m_replacerCallType, m_replacerCallData, holder.object(), args); 334 340 RETURN_IF_EXCEPTION(scope, StringifyFailed);
Note: See TracChangeset
for help on using the changeset viewer.