Diff
Modified: branches/safari-612-branch/JSTests/ChangeLog (282942 => 282943)
--- branches/safari-612-branch/JSTests/ChangeLog 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/JSTests/ChangeLog 2021-09-23 05:14:29 UTC (rev 282943)
@@ -1,3 +1,133 @@
+2021-09-22 Alan Coon <alanc...@apple.com>
+
+ Cherry-pick r282707. rdar://problem/83429953
+
+ [JSC] Add fast property enumeration mode for JSON.stringify
+ https://bugs.webkit.org/show_bug.cgi?id=230393
+
+ Reviewed by Mark Lam.
+
+ JSTests:
+
+ * stress/json-stringify-object-modify.js: Added.
+ (shouldBe):
+ (throw.new.Error.let.object.hello.get inner):
+ (throw.new.Error):
+ (shouldBe.let.object.hello.get inner):
+
+ Source/_javascript_Core:
+
+ We collected profiles and found several subtests are using JSON.stringify enough. And generated strings are many serialized leaf objects.
+
+ This patch adds fast object property enumeration. When we know that source object meets some conditions, we can say that,
+ as long as structure is not changed, we can continue using property names and offset collected from the structure.
+ This way removes non observable [[Get]] operations to accelerate JSON.stringify performance for major object iteration cases.
+
+ We also extend MarkedArgumentBuffer: introducing MarkedArgumentBufferWithSize which can take default inline capacity as a template
+ parameter. This is used in JSON.stringify to increase the buffer because now we also need to record structures in MarkedArgumentBuffer.
+
+ This offers 0.4% improvement in Speedometer2 (EmberJS-TodoMVC, Vanilla-XXX, EmberJS-Debug-TodoMVC, they have enough amount of JSON.stringify
+ time).
+
+ ----------------------------------------------------------------------------------------------------------------------------------
+ | subtest | ms | ms | b / a | pValue (significance using False Discovery Rate) |
+ ----------------------------------------------------------------------------------------------------------------------------------
+ | Elm-TodoMVC |117.710000 |117.751667 |1.000354 | 0.883246 |
+ | VueJS-TodoMVC |24.500000 |24.311667 |0.992313 | 0.365130 |
+ | EmberJS-TodoMVC |126.646667 |125.738333 |0.992828 | 0.002587 (significant) |
+ | BackboneJS-TodoMVC |47.873333 |47.911667 |1.000801 | 0.762509 |
+ | Preact-TodoMVC |17.020000 |17.070000 |1.002938 | 0.786799 |
+ | AngularJS-TodoMVC |129.856667 |129.353333 |0.996124 | 0.177632 |
+ | Vanilla-ES2015-TodoMVC |61.698333 |61.120000 |0.990626 | 0.000003 (significant) |
+ | Inferno-TodoMVC |62.840000 |62.496667 |0.994536 | 0.312340 |
+ | Flight-TodoMVC |77.095000 |76.936667 |0.997946 | 0.702724 |
+ | Angular2-TypeScript-TodoMVC |39.740000 |39.191667 |0.986202 | 0.053485 |
+ | VanillaJS-TodoMVC |49.008333 |48.346667 |0.986499 | 0.000638 (significant) |
+ | jQuery-TodoMVC |216.785000 |217.188333 |1.001861 | 0.270747 |
+ | EmberJS-Debug-TodoMVC |344.230000 |342.993333 |0.996407 | 0.012262 (significant) |
+ | React-TodoMVC |85.461667 |85.411667 |0.999415 | 0.758049 |
+ | React-Redux-TodoMVC |140.681667 |140.640000 |0.999704 | 0.871277 |
+ | Vanilla-ES2015-Babel-Webpack-TodoMVC |59.928333 |59.351667 |0.990377 | 0.000000 (significant) |
+ ----------------------------------------------------------------------------------------------------------------------------------
+ a mean = 264.40650
+ b mean = 265.51533
+ pValue = 0.0005567357
+ (Bigger means are better.)
+ 1.004 times better
+ Results ARE significant
+
+ * heap/Heap.cpp:
+ (JSC::Heap::addCoreConstraints):
+ * heap/Heap.h:
+ * heap/HeapInlines.h:
+ * runtime/ArgList.cpp:
+ (JSC::MarkedArgumentBufferBase::addMarkSet):
+ (JSC::MarkedArgumentBufferBase::markLists):
+ (JSC::MarkedArgumentBufferBase::slowEnsureCapacity):
+ (JSC::MarkedArgumentBufferBase::expandCapacity):
+ (JSC::MarkedArgumentBufferBase::slowAppend):
+ (JSC::MarkedArgumentBuffer::addMarkSet): Deleted.
+ (JSC::MarkedArgumentBuffer::markLists): Deleted.
+ (JSC::MarkedArgumentBuffer::slowEnsureCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::expandCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::slowAppend): Deleted.
+ * runtime/ArgList.h:
+ (JSC::MarkedArgumentBufferWithSize::MarkedArgumentBufferWithSize):
+ (JSC::MarkedArgumentBuffer::MarkedArgumentBuffer): Deleted.
+ (JSC::MarkedArgumentBuffer::~MarkedArgumentBuffer): Deleted.
+ (JSC::MarkedArgumentBuffer::size const): Deleted.
+ (JSC::MarkedArgumentBuffer::isEmpty const): Deleted.
+ (JSC::MarkedArgumentBuffer::at const): Deleted.
+ (JSC::MarkedArgumentBuffer::clear): Deleted.
+ (JSC::MarkedArgumentBuffer::appendWithAction): Deleted.
+ (JSC::MarkedArgumentBuffer::append): Deleted.
+ (JSC::MarkedArgumentBuffer::appendWithCrashOnOverflow): Deleted.
+ (JSC::MarkedArgumentBuffer::removeLast): Deleted.
+ (JSC::MarkedArgumentBuffer::last): Deleted.
+ (JSC::MarkedArgumentBuffer::takeLast): Deleted.
+ (JSC::MarkedArgumentBuffer::ensureCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::hasOverflowed): Deleted.
+ (JSC::MarkedArgumentBuffer::overflowCheckNotNeeded): Deleted.
+ (JSC::MarkedArgumentBuffer::fill): Deleted.
+ (JSC::MarkedArgumentBuffer::slotFor const): Deleted.
+ (JSC::MarkedArgumentBuffer::mallocBase): Deleted.
+ (JSC::MarkedArgumentBuffer::setNeedsOverflowCheck): Deleted.
+ (JSC::MarkedArgumentBuffer::clearNeedsOverflowCheck): Deleted.
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::Holder::hasFastObjectProperties const):
+ (JSC::Stringifier::appendStringifiedValue):
+ (JSC::Stringifier::Holder::Holder):
+ (JSC::Stringifier::Holder::appendNextProperty):
+ * runtime/ObjectConstructorInlines.h:
+ (JSC::canPerformFastPropertyEnumerationForJSONStringify):
+
+ Source/WebCore:
+
+ * Modules/webaudio/AudioWorkletProcessor.cpp:
+ (WebCore::AudioWorkletProcessor::buildJSArguments):
+ * Modules/webaudio/AudioWorkletProcessor.h:
+
+ Source/WebKitLegacy/mac:
+
+ * Plugins/Hosted/NetscapePluginInstanceProxy.h:
+ * Plugins/Hosted/NetscapePluginInstanceProxy.mm:
+ (WebKit::NetscapePluginInstanceProxy::demarshalValues):
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@282707 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2021-09-17 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Add fast property enumeration mode for JSON.stringify
+ https://bugs.webkit.org/show_bug.cgi?id=230393
+
+ Reviewed by Mark Lam.
+
+ * stress/json-stringify-object-modify.js: Added.
+ (shouldBe):
+ (throw.new.Error.let.object.hello.get inner):
+ (throw.new.Error):
+ (shouldBe.let.object.hello.get inner):
+
2021-09-16 Russell Epstein <repst...@apple.com>
Cherry-pick r282239. rdar://problem/83183776
Added: branches/safari-612-branch/JSTests/stress/json-stringify-object-modify.js (0 => 282943)
--- branches/safari-612-branch/JSTests/stress/json-stringify-object-modify.js (rev 0)
+++ branches/safari-612-branch/JSTests/stress/json-stringify-object-modify.js 2021-09-23 05:14:29 UTC (rev 282943)
@@ -0,0 +1,35 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+{
+ let object = {
+ hello: {
+ get inner() {
+ $vm.toUncacheableDictionary(object);
+ object.world = 0;
+ return 33;
+ }
+ },
+ world: 42,
+ test: null,
+ };
+
+ shouldBe(JSON.stringify(object), `{"hello":{"inner":33},"world":0,"test":null}`);
+}
+{
+ let object = {
+ hello: {
+ get inner() {
+ delete object.world;
+ object.testing = 33;
+ return 33;
+ }
+ },
+ world: 42,
+ test: null,
+ };
+
+ shouldBe(JSON.stringify(object), `{"hello":{"inner":33},"test":null}`);
+}
Modified: branches/safari-612-branch/Source/_javascript_Core/ChangeLog (282942 => 282943)
--- branches/safari-612-branch/Source/_javascript_Core/ChangeLog 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/_javascript_Core/ChangeLog 2021-09-23 05:14:29 UTC (rev 282943)
@@ -1,5 +1,213 @@
2021-09-22 Alan Coon <alanc...@apple.com>
+ Cherry-pick r282707. rdar://problem/83429953
+
+ [JSC] Add fast property enumeration mode for JSON.stringify
+ https://bugs.webkit.org/show_bug.cgi?id=230393
+
+ Reviewed by Mark Lam.
+
+ JSTests:
+
+ * stress/json-stringify-object-modify.js: Added.
+ (shouldBe):
+ (throw.new.Error.let.object.hello.get inner):
+ (throw.new.Error):
+ (shouldBe.let.object.hello.get inner):
+
+ Source/_javascript_Core:
+
+ We collected profiles and found several subtests are using JSON.stringify enough. And generated strings are many serialized leaf objects.
+
+ This patch adds fast object property enumeration. When we know that source object meets some conditions, we can say that,
+ as long as structure is not changed, we can continue using property names and offset collected from the structure.
+ This way removes non observable [[Get]] operations to accelerate JSON.stringify performance for major object iteration cases.
+
+ We also extend MarkedArgumentBuffer: introducing MarkedArgumentBufferWithSize which can take default inline capacity as a template
+ parameter. This is used in JSON.stringify to increase the buffer because now we also need to record structures in MarkedArgumentBuffer.
+
+ This offers 0.4% improvement in Speedometer2 (EmberJS-TodoMVC, Vanilla-XXX, EmberJS-Debug-TodoMVC, they have enough amount of JSON.stringify
+ time).
+
+ ----------------------------------------------------------------------------------------------------------------------------------
+ | subtest | ms | ms | b / a | pValue (significance using False Discovery Rate) |
+ ----------------------------------------------------------------------------------------------------------------------------------
+ | Elm-TodoMVC |117.710000 |117.751667 |1.000354 | 0.883246 |
+ | VueJS-TodoMVC |24.500000 |24.311667 |0.992313 | 0.365130 |
+ | EmberJS-TodoMVC |126.646667 |125.738333 |0.992828 | 0.002587 (significant) |
+ | BackboneJS-TodoMVC |47.873333 |47.911667 |1.000801 | 0.762509 |
+ | Preact-TodoMVC |17.020000 |17.070000 |1.002938 | 0.786799 |
+ | AngularJS-TodoMVC |129.856667 |129.353333 |0.996124 | 0.177632 |
+ | Vanilla-ES2015-TodoMVC |61.698333 |61.120000 |0.990626 | 0.000003 (significant) |
+ | Inferno-TodoMVC |62.840000 |62.496667 |0.994536 | 0.312340 |
+ | Flight-TodoMVC |77.095000 |76.936667 |0.997946 | 0.702724 |
+ | Angular2-TypeScript-TodoMVC |39.740000 |39.191667 |0.986202 | 0.053485 |
+ | VanillaJS-TodoMVC |49.008333 |48.346667 |0.986499 | 0.000638 (significant) |
+ | jQuery-TodoMVC |216.785000 |217.188333 |1.001861 | 0.270747 |
+ | EmberJS-Debug-TodoMVC |344.230000 |342.993333 |0.996407 | 0.012262 (significant) |
+ | React-TodoMVC |85.461667 |85.411667 |0.999415 | 0.758049 |
+ | React-Redux-TodoMVC |140.681667 |140.640000 |0.999704 | 0.871277 |
+ | Vanilla-ES2015-Babel-Webpack-TodoMVC |59.928333 |59.351667 |0.990377 | 0.000000 (significant) |
+ ----------------------------------------------------------------------------------------------------------------------------------
+ a mean = 264.40650
+ b mean = 265.51533
+ pValue = 0.0005567357
+ (Bigger means are better.)
+ 1.004 times better
+ Results ARE significant
+
+ * heap/Heap.cpp:
+ (JSC::Heap::addCoreConstraints):
+ * heap/Heap.h:
+ * heap/HeapInlines.h:
+ * runtime/ArgList.cpp:
+ (JSC::MarkedArgumentBufferBase::addMarkSet):
+ (JSC::MarkedArgumentBufferBase::markLists):
+ (JSC::MarkedArgumentBufferBase::slowEnsureCapacity):
+ (JSC::MarkedArgumentBufferBase::expandCapacity):
+ (JSC::MarkedArgumentBufferBase::slowAppend):
+ (JSC::MarkedArgumentBuffer::addMarkSet): Deleted.
+ (JSC::MarkedArgumentBuffer::markLists): Deleted.
+ (JSC::MarkedArgumentBuffer::slowEnsureCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::expandCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::slowAppend): Deleted.
+ * runtime/ArgList.h:
+ (JSC::MarkedArgumentBufferWithSize::MarkedArgumentBufferWithSize):
+ (JSC::MarkedArgumentBuffer::MarkedArgumentBuffer): Deleted.
+ (JSC::MarkedArgumentBuffer::~MarkedArgumentBuffer): Deleted.
+ (JSC::MarkedArgumentBuffer::size const): Deleted.
+ (JSC::MarkedArgumentBuffer::isEmpty const): Deleted.
+ (JSC::MarkedArgumentBuffer::at const): Deleted.
+ (JSC::MarkedArgumentBuffer::clear): Deleted.
+ (JSC::MarkedArgumentBuffer::appendWithAction): Deleted.
+ (JSC::MarkedArgumentBuffer::append): Deleted.
+ (JSC::MarkedArgumentBuffer::appendWithCrashOnOverflow): Deleted.
+ (JSC::MarkedArgumentBuffer::removeLast): Deleted.
+ (JSC::MarkedArgumentBuffer::last): Deleted.
+ (JSC::MarkedArgumentBuffer::takeLast): Deleted.
+ (JSC::MarkedArgumentBuffer::ensureCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::hasOverflowed): Deleted.
+ (JSC::MarkedArgumentBuffer::overflowCheckNotNeeded): Deleted.
+ (JSC::MarkedArgumentBuffer::fill): Deleted.
+ (JSC::MarkedArgumentBuffer::slotFor const): Deleted.
+ (JSC::MarkedArgumentBuffer::mallocBase): Deleted.
+ (JSC::MarkedArgumentBuffer::setNeedsOverflowCheck): Deleted.
+ (JSC::MarkedArgumentBuffer::clearNeedsOverflowCheck): Deleted.
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::Holder::hasFastObjectProperties const):
+ (JSC::Stringifier::appendStringifiedValue):
+ (JSC::Stringifier::Holder::Holder):
+ (JSC::Stringifier::Holder::appendNextProperty):
+ * runtime/ObjectConstructorInlines.h:
+ (JSC::canPerformFastPropertyEnumerationForJSONStringify):
+
+ Source/WebCore:
+
+ * Modules/webaudio/AudioWorkletProcessor.cpp:
+ (WebCore::AudioWorkletProcessor::buildJSArguments):
+ * Modules/webaudio/AudioWorkletProcessor.h:
+
+ Source/WebKitLegacy/mac:
+
+ * Plugins/Hosted/NetscapePluginInstanceProxy.h:
+ * Plugins/Hosted/NetscapePluginInstanceProxy.mm:
+ (WebKit::NetscapePluginInstanceProxy::demarshalValues):
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@282707 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2021-09-17 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Add fast property enumeration mode for JSON.stringify
+ https://bugs.webkit.org/show_bug.cgi?id=230393
+
+ Reviewed by Mark Lam.
+
+ We collected profiles and found several subtests are using JSON.stringify enough. And generated strings are many serialized leaf objects.
+
+ This patch adds fast object property enumeration. When we know that source object meets some conditions, we can say that,
+ as long as structure is not changed, we can continue using property names and offset collected from the structure.
+ This way removes non observable [[Get]] operations to accelerate JSON.stringify performance for major object iteration cases.
+
+ We also extend MarkedArgumentBuffer: introducing MarkedArgumentBufferWithSize which can take default inline capacity as a template
+ parameter. This is used in JSON.stringify to increase the buffer because now we also need to record structures in MarkedArgumentBuffer.
+
+ This offers 0.4% improvement in Speedometer2 (EmberJS-TodoMVC, Vanilla-XXX, EmberJS-Debug-TodoMVC, they have enough amount of JSON.stringify
+ time).
+
+ ----------------------------------------------------------------------------------------------------------------------------------
+ | subtest | ms | ms | b / a | pValue (significance using False Discovery Rate) |
+ ----------------------------------------------------------------------------------------------------------------------------------
+ | Elm-TodoMVC |117.710000 |117.751667 |1.000354 | 0.883246 |
+ | VueJS-TodoMVC |24.500000 |24.311667 |0.992313 | 0.365130 |
+ | EmberJS-TodoMVC |126.646667 |125.738333 |0.992828 | 0.002587 (significant) |
+ | BackboneJS-TodoMVC |47.873333 |47.911667 |1.000801 | 0.762509 |
+ | Preact-TodoMVC |17.020000 |17.070000 |1.002938 | 0.786799 |
+ | AngularJS-TodoMVC |129.856667 |129.353333 |0.996124 | 0.177632 |
+ | Vanilla-ES2015-TodoMVC |61.698333 |61.120000 |0.990626 | 0.000003 (significant) |
+ | Inferno-TodoMVC |62.840000 |62.496667 |0.994536 | 0.312340 |
+ | Flight-TodoMVC |77.095000 |76.936667 |0.997946 | 0.702724 |
+ | Angular2-TypeScript-TodoMVC |39.740000 |39.191667 |0.986202 | 0.053485 |
+ | VanillaJS-TodoMVC |49.008333 |48.346667 |0.986499 | 0.000638 (significant) |
+ | jQuery-TodoMVC |216.785000 |217.188333 |1.001861 | 0.270747 |
+ | EmberJS-Debug-TodoMVC |344.230000 |342.993333 |0.996407 | 0.012262 (significant) |
+ | React-TodoMVC |85.461667 |85.411667 |0.999415 | 0.758049 |
+ | React-Redux-TodoMVC |140.681667 |140.640000 |0.999704 | 0.871277 |
+ | Vanilla-ES2015-Babel-Webpack-TodoMVC |59.928333 |59.351667 |0.990377 | 0.000000 (significant) |
+ ----------------------------------------------------------------------------------------------------------------------------------
+ a mean = 264.40650
+ b mean = 265.51533
+ pValue = 0.0005567357
+ (Bigger means are better.)
+ 1.004 times better
+ Results ARE significant
+
+ * heap/Heap.cpp:
+ (JSC::Heap::addCoreConstraints):
+ * heap/Heap.h:
+ * heap/HeapInlines.h:
+ * runtime/ArgList.cpp:
+ (JSC::MarkedArgumentBufferBase::addMarkSet):
+ (JSC::MarkedArgumentBufferBase::markLists):
+ (JSC::MarkedArgumentBufferBase::slowEnsureCapacity):
+ (JSC::MarkedArgumentBufferBase::expandCapacity):
+ (JSC::MarkedArgumentBufferBase::slowAppend):
+ (JSC::MarkedArgumentBuffer::addMarkSet): Deleted.
+ (JSC::MarkedArgumentBuffer::markLists): Deleted.
+ (JSC::MarkedArgumentBuffer::slowEnsureCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::expandCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::slowAppend): Deleted.
+ * runtime/ArgList.h:
+ (JSC::MarkedArgumentBufferWithSize::MarkedArgumentBufferWithSize):
+ (JSC::MarkedArgumentBuffer::MarkedArgumentBuffer): Deleted.
+ (JSC::MarkedArgumentBuffer::~MarkedArgumentBuffer): Deleted.
+ (JSC::MarkedArgumentBuffer::size const): Deleted.
+ (JSC::MarkedArgumentBuffer::isEmpty const): Deleted.
+ (JSC::MarkedArgumentBuffer::at const): Deleted.
+ (JSC::MarkedArgumentBuffer::clear): Deleted.
+ (JSC::MarkedArgumentBuffer::appendWithAction): Deleted.
+ (JSC::MarkedArgumentBuffer::append): Deleted.
+ (JSC::MarkedArgumentBuffer::appendWithCrashOnOverflow): Deleted.
+ (JSC::MarkedArgumentBuffer::removeLast): Deleted.
+ (JSC::MarkedArgumentBuffer::last): Deleted.
+ (JSC::MarkedArgumentBuffer::takeLast): Deleted.
+ (JSC::MarkedArgumentBuffer::ensureCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::hasOverflowed): Deleted.
+ (JSC::MarkedArgumentBuffer::overflowCheckNotNeeded): Deleted.
+ (JSC::MarkedArgumentBuffer::fill): Deleted.
+ (JSC::MarkedArgumentBuffer::slotFor const): Deleted.
+ (JSC::MarkedArgumentBuffer::mallocBase): Deleted.
+ (JSC::MarkedArgumentBuffer::setNeedsOverflowCheck): Deleted.
+ (JSC::MarkedArgumentBuffer::clearNeedsOverflowCheck): Deleted.
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::Holder::hasFastObjectProperties const):
+ (JSC::Stringifier::appendStringifiedValue):
+ (JSC::Stringifier::Holder::Holder):
+ (JSC::Stringifier::Holder::appendNextProperty):
+ * runtime/ObjectConstructorInlines.h:
+ (JSC::canPerformFastPropertyEnumerationForJSONStringify):
+
+2021-09-22 Alan Coon <alanc...@apple.com>
+
Cherry-pick r282663. rdar://problem/83429716
PutByVal and PutPrivateName ICs should emit a write barrier if a butterfly might be allocated
Modified: branches/safari-612-branch/Source/_javascript_Core/heap/Heap.cpp (282942 => 282943)
--- branches/safari-612-branch/Source/_javascript_Core/heap/Heap.cpp 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/_javascript_Core/heap/Heap.cpp 2021-09-23 05:14:29 UTC (rev 282943)
@@ -2767,7 +2767,7 @@
if (m_markListSet && m_markListSet->size()) {
SetRootMarkReasonScope rootScope(visitor, RootMarkReason::ConservativeScan);
- MarkedArgumentBuffer::markLists(visitor, *m_markListSet);
+ MarkedArgumentBufferBase::markLists(visitor, *m_markListSet);
}
{
Modified: branches/safari-612-branch/Source/_javascript_Core/heap/Heap.h (282942 => 282943)
--- branches/safari-612-branch/Source/_javascript_Core/heap/Heap.h 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/_javascript_Core/heap/Heap.h 2021-09-23 05:14:29 UTC (rev 282943)
@@ -77,7 +77,7 @@
class MarkStackMergingConstraint;
class MarkedJSValueRefArray;
class BlockDirectory;
-class MarkedArgumentBuffer;
+class MarkedArgumentBufferBase;
class MarkingConstraint;
class MarkingConstraintSet;
class MutatorScheduler;
@@ -245,7 +245,7 @@
JS_EXPORT_PRIVATE std::unique_ptr<TypeCountSet> protectedObjectTypeCounts();
JS_EXPORT_PRIVATE std::unique_ptr<TypeCountSet> objectTypeCounts();
- HashSet<MarkedArgumentBuffer*>& markListSet();
+ HashSet<MarkedArgumentBufferBase*>& markListSet();
void addMarkedJSValueRefArray(MarkedJSValueRefArray*);
template<typename Functor> void forEachProtectedCell(const Functor&);
@@ -624,7 +624,7 @@
HashSet<const JSCell*> m_copyingRememberedSet;
ProtectCountSet m_protectedValues;
- std::unique_ptr<HashSet<MarkedArgumentBuffer*>> m_markListSet;
+ std::unique_ptr<HashSet<MarkedArgumentBufferBase*>> m_markListSet;
SentinelLinkedList<MarkedJSValueRefArray, BasicRawSentinelNode<MarkedJSValueRefArray>> m_markedJSValueRefArrays;
std::unique_ptr<MachineThreads> m_machineThreads;
Modified: branches/safari-612-branch/Source/_javascript_Core/heap/HeapInlines.h (282942 => 282943)
--- branches/safari-612-branch/Source/_javascript_Core/heap/HeapInlines.h 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/_javascript_Core/heap/HeapInlines.h 2021-09-23 05:14:29 UTC (rev 282943)
@@ -215,10 +215,10 @@
}
}
-inline HashSet<MarkedArgumentBuffer*>& Heap::markListSet()
+inline HashSet<MarkedArgumentBufferBase*>& Heap::markListSet()
{
if (!m_markListSet)
- m_markListSet = makeUnique<HashSet<MarkedArgumentBuffer*>>();
+ m_markListSet = makeUnique<HashSet<MarkedArgumentBufferBase*>>();
return *m_markListSet;
}
Modified: branches/safari-612-branch/Source/_javascript_Core/runtime/ArgList.cpp (282942 => 282943)
--- branches/safari-612-branch/Source/_javascript_Core/runtime/ArgList.cpp 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/_javascript_Core/runtime/ArgList.cpp 2021-09-23 05:14:29 UTC (rev 282943)
@@ -27,7 +27,7 @@
namespace JSC {
-void MarkedArgumentBuffer::addMarkSet(JSValue v)
+void MarkedArgumentBufferBase::addMarkSet(JSValue v)
{
if (m_markSet)
return;
@@ -52,20 +52,20 @@
}
template<typename Visitor>
-void MarkedArgumentBuffer::markLists(Visitor& visitor, ListSet& markSet)
+void MarkedArgumentBufferBase::markLists(Visitor& visitor, ListSet& markSet)
{
ListSet::iterator end = markSet.end();
for (ListSet::iterator it = markSet.begin(); it != end; ++it) {
- MarkedArgumentBuffer* list = *it;
+ MarkedArgumentBufferBase* list = *it;
for (int i = 0; i < list->m_size; ++i)
visitor.appendUnbarriered(JSValue::decode(list->slotFor(i)));
}
}
-template void MarkedArgumentBuffer::markLists(AbstractSlotVisitor&, ListSet&);
-template void MarkedArgumentBuffer::markLists(SlotVisitor&, ListSet&);
+template void MarkedArgumentBufferBase::markLists(AbstractSlotVisitor&, ListSet&);
+template void MarkedArgumentBufferBase::markLists(SlotVisitor&, ListSet&);
-void MarkedArgumentBuffer::slowEnsureCapacity(size_t requestedCapacity)
+void MarkedArgumentBufferBase::slowEnsureCapacity(size_t requestedCapacity)
{
setNeedsOverflowCheck();
auto checkedNewCapacity = CheckedInt32(requestedCapacity);
@@ -74,7 +74,7 @@
expandCapacity(checkedNewCapacity);
}
-void MarkedArgumentBuffer::expandCapacity()
+void MarkedArgumentBufferBase::expandCapacity()
{
setNeedsOverflowCheck();
auto checkedNewCapacity = CheckedInt32(m_capacity) * 2;
@@ -83,7 +83,7 @@
expandCapacity(checkedNewCapacity);
}
-void MarkedArgumentBuffer::expandCapacity(int newCapacity)
+void MarkedArgumentBufferBase::expandCapacity(int newCapacity)
{
setNeedsOverflowCheck();
ASSERT(m_capacity < newCapacity);
@@ -105,7 +105,7 @@
m_capacity = newCapacity;
}
-void MarkedArgumentBuffer::slowAppend(JSValue v)
+void MarkedArgumentBufferBase::slowAppend(JSValue v)
{
ASSERT(m_size <= m_capacity);
if (m_size == m_capacity)
Modified: branches/safari-612-branch/Source/_javascript_Core/runtime/ArgList.h (282942 => 282943)
--- branches/safari-612-branch/Source/_javascript_Core/runtime/ArgList.h 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/_javascript_Core/runtime/ArgList.h 2021-09-23 05:14:29 UTC (rev 282943)
@@ -28,9 +28,9 @@
namespace JSC {
-class MarkedArgumentBuffer : public RecordOverflow {
- WTF_MAKE_NONCOPYABLE(MarkedArgumentBuffer);
- WTF_MAKE_NONMOVABLE(MarkedArgumentBuffer);
+class alignas(alignof(EncodedJSValue)) MarkedArgumentBufferBase : public RecordOverflow {
+ WTF_MAKE_NONCOPYABLE(MarkedArgumentBufferBase);
+ WTF_MAKE_NONMOVABLE(MarkedArgumentBufferBase);
WTF_FORBID_HEAP_ALLOCATION;
friend class VM;
friend class ArgList;
@@ -37,21 +37,10 @@
public:
using Base = RecordOverflow;
- static constexpr size_t inlineCapacity = 8;
- typedef HashSet<MarkedArgumentBuffer*> ListSet;
+ typedef HashSet<MarkedArgumentBufferBase*> ListSet;
- // Constructor for a read-write list, to which you may append values.
- // FIXME: Remove all clients of this API, then remove this API.
- MarkedArgumentBuffer()
- : m_size(0)
- , m_capacity(inlineCapacity)
- , m_buffer(m_inlineBuffer)
- , m_markSet(nullptr)
+ ~MarkedArgumentBufferBase()
{
- }
-
- ~MarkedArgumentBuffer()
- {
ASSERT(!m_needsOverflowCheck);
if (m_markSet)
m_markSet->remove(this);
@@ -145,6 +134,22 @@
func(reinterpret_cast<JSValue*>(&slotFor(0)));
}
+protected:
+ // Constructor for a read-write list, to which you may append values.
+ // FIXME: Remove all clients of this API, then remove this API.
+ MarkedArgumentBufferBase(size_t capacity)
+ : m_size(0)
+ , m_capacity(capacity)
+ , m_buffer(inlineBuffer())
+ , m_markSet(nullptr)
+ {
+ }
+
+ EncodedJSValue* inlineBuffer()
+ {
+ return bitwise_cast<EncodedJSValue*>(bitwise_cast<uint8_t*>(this) + sizeof(MarkedArgumentBufferBase));
+ }
+
private:
void expandCapacity();
void expandCapacity(int newCapacity);
@@ -161,7 +166,7 @@
EncodedJSValue* mallocBase()
{
- if (m_buffer == m_inlineBuffer)
+ if (m_buffer == inlineBuffer())
return nullptr;
return &slotFor(0);
}
@@ -177,11 +182,27 @@
#endif // ASSERT_ENABLED
int m_size;
int m_capacity;
- EncodedJSValue m_inlineBuffer[inlineCapacity];
EncodedJSValue* m_buffer;
ListSet* m_markSet;
};
+template<size_t passedInlineCapacity = 8>
+class MarkedArgumentBufferWithSize : public MarkedArgumentBufferBase {
+public:
+ static constexpr size_t inlineCapacity = passedInlineCapacity;
+
+ MarkedArgumentBufferWithSize()
+ : MarkedArgumentBufferBase(inlineCapacity)
+ {
+ ASSERT(inlineBuffer() == m_inlineBuffer);
+ }
+
+private:
+ EncodedJSValue m_inlineBuffer[inlineCapacity] { };
+};
+
+using MarkedArgumentBuffer = MarkedArgumentBufferWithSize<>;
+
class ArgList {
WTF_MAKE_FAST_ALLOCATED;
friend class Interpreter;
Modified: branches/safari-612-branch/Source/_javascript_Core/runtime/JSONObject.cpp (282942 => 282943)
--- branches/safari-612-branch/Source/_javascript_Core/runtime/JSONObject.cpp 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/_javascript_Core/runtime/JSONObject.cpp 2021-09-23 05:14:29 UTC (rev 282943)
@@ -33,7 +33,7 @@
#include "JSArrayInlines.h"
#include "JSCInlines.h"
#include "LiteralParser.h"
-#include "ObjectConstructor.h"
+#include "ObjectConstructorInlines.h"
#include "PropertyNameArray.h"
#include "VMInlines.h"
#include <wtf/text/StringBuilder.h>
@@ -88,21 +88,25 @@
class Holder {
public:
enum RootHolderTag { RootHolder };
- Holder(JSGlobalObject*, JSObject*);
+ Holder(JSGlobalObject*, JSObject*, Structure*);
Holder(RootHolderTag, JSObject*);
JSObject* object() const { return m_object; }
bool isArray() const { return m_isArray; }
+ bool hasFastObjectProperties() const { return m_hasFastObjectProperties; }
bool appendNextProperty(Stringifier&, StringBuilder&);
private:
- JSObject* m_object;
- const bool m_isJSArray;
- const bool m_isArray;
+ JSObject* m_object { nullptr };
+ Structure* m_structure { nullptr };
+ const bool m_isJSArray { false };
+ const bool m_isArray { false };
+ bool m_hasFastObjectProperties { false };
unsigned m_index { 0 };
unsigned m_size { 0 };
RefPtr<PropertyNameArrayData> m_propertyNames;
+ Vector<std::tuple<Identifier, unsigned>, 8> m_propertiesAndOffsets;
};
friend class Holder;
@@ -125,7 +129,7 @@
CallData m_replacerCallData;
String m_gap;
- MarkedArgumentBuffer m_objectStack;
+ MarkedArgumentBufferWithSize<16> m_objectStack;
Vector<Holder, 16, UnsafeVectorOverflow> m_holderStack;
String m_repeatedGap;
String m_indent;
@@ -408,8 +412,10 @@
}
bool holderStackWasEmpty = m_holderStack.isEmpty();
- m_holderStack.append(Holder(m_globalObject, object));
+ Structure* structure = object->structure(vm);
+ m_holderStack.append(Holder(m_globalObject, object, structure));
m_objectStack.appendWithCrashOnOverflow(object);
+ m_objectStack.appendWithCrashOnOverflow(structure);
RETURN_IF_EXCEPTION(scope, StringifyFailed);
if (!holderStackWasEmpty)
return StringifySucceeded;
@@ -422,6 +428,7 @@
return StringifyFailed;
m_holderStack.removeLast();
m_objectStack.removeLast();
+ m_objectStack.removeLast();
} while (!m_holderStack.isEmpty());
return StringifySucceeded;
}
@@ -455,8 +462,9 @@
builder.append(m_indent);
}
-inline Stringifier::Holder::Holder(JSGlobalObject* globalObject, JSObject* object)
+inline Stringifier::Holder::Holder(JSGlobalObject* globalObject, JSObject* object, Structure* structure)
: m_object(object)
+ , m_structure(structure)
, m_isJSArray(isJSArray(object))
, m_isArray(JSC::isArray(globalObject, object))
{
@@ -464,8 +472,6 @@
inline Stringifier::Holder::Holder(RootHolderTag, JSObject* object)
: m_object(object)
- , m_isJSArray(false)
- , m_isArray(false)
{
}
@@ -490,15 +496,29 @@
RETURN_IF_EXCEPTION(scope, false);
builder.append('[');
} else {
- if (stringifier.m_usingArrayReplacer)
+ if (stringifier.m_usingArrayReplacer) {
m_propertyNames = stringifier.m_arrayReplacerPropertyNames.data();
- else {
+ m_size = m_propertyNames->propertyNameVector().size();
+ } else if (m_structure && m_object->structureID() == m_structure->id() && canPerformFastPropertyEnumerationForJSONStringify(m_structure)) {
+ m_structure->forEachProperty(vm, [&](const PropertyMapEntry& entry) -> bool {
+ if (entry.attributes & PropertyAttribute::DontEnum)
+ return true;
+
+ PropertyName propertyName(entry.key);
+ if (propertyName.isSymbol())
+ return true;
+ m_propertiesAndOffsets.constructAndAppend(Identifier::fromUid(vm, entry.key), entry.offset);
+ return true;
+ });
+ m_hasFastObjectProperties = true;
+ m_size = m_propertiesAndOffsets.size();
+ } else {
PropertyNameArray objectPropertyNames(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
m_object->methodTable(vm)->getOwnPropertyNames(m_object, globalObject, objectPropertyNames, DontEnumPropertiesMode::Exclude);
RETURN_IF_EXCEPTION(scope, false);
m_propertyNames = objectPropertyNames.releaseData();
+ m_size = m_propertyNames->propertyNameVector().size();
}
- m_size = m_propertyNames->propertyNameVector().size();
builder.append('{');
}
stringifier.indent();
@@ -538,10 +558,22 @@
stringifyResult = stringifier.appendStringifiedValue(builder, value, *this, index);
ASSERT(stringifyResult != StringifyFailedDueToUndefinedOrSymbolValue);
} else {
- // Get the value.
- Identifier& propertyName = m_propertyNames->propertyNameVector()[index];
- JSValue value = m_object->get(globalObject, propertyName);
- RETURN_IF_EXCEPTION(scope, false);
+ Identifier propertyName;
+ JSValue value;
+ if (m_hasFastObjectProperties) {
+ propertyName = std::get<0>(m_propertiesAndOffsets[index]);
+ if (m_object->structureID() == m_structure->id()) {
+ unsigned offset = std::get<1>(m_propertiesAndOffsets[index]);
+ value = m_object->getDirect(offset);
+ } else {
+ value = m_object->get(globalObject, propertyName);
+ RETURN_IF_EXCEPTION(scope, false);
+ }
+ } else {
+ propertyName = m_propertyNames->propertyNameVector()[index];
+ value = m_object->get(globalObject, propertyName);
+ RETURN_IF_EXCEPTION(scope, false);
+ }
rollBackPoint = builder.length();
Modified: branches/safari-612-branch/Source/_javascript_Core/runtime/ObjectConstructorInlines.h (282942 => 282943)
--- branches/safari-612-branch/Source/_javascript_Core/runtime/ObjectConstructorInlines.h 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/_javascript_Core/runtime/ObjectConstructorInlines.h 2021-09-23 05:14:29 UTC (rev 282943)
@@ -53,6 +53,11 @@
return true;
}
+ALWAYS_INLINE bool canPerformFastPropertyEnumerationForJSONStringify(Structure* structure)
+{
+ return canPerformFastPropertyEnumerationForObjectAssign(structure);
+}
+
ALWAYS_INLINE void objectAssignFast(VM& vm, JSObject* target, JSObject* source, Vector<RefPtr<UniquedStringImpl>, 8>& properties, MarkedArgumentBuffer& values)
{
// |source| Structure does not have any getters. And target can perform fast put.
Modified: branches/safari-612-branch/Source/WebCore/ChangeLog (282942 => 282943)
--- branches/safari-612-branch/Source/WebCore/ChangeLog 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/WebCore/ChangeLog 2021-09-23 05:14:29 UTC (rev 282943)
@@ -1,5 +1,133 @@
2021-09-22 Alan Coon <alanc...@apple.com>
+ Cherry-pick r282707. rdar://problem/83429953
+
+ [JSC] Add fast property enumeration mode for JSON.stringify
+ https://bugs.webkit.org/show_bug.cgi?id=230393
+
+ Reviewed by Mark Lam.
+
+ JSTests:
+
+ * stress/json-stringify-object-modify.js: Added.
+ (shouldBe):
+ (throw.new.Error.let.object.hello.get inner):
+ (throw.new.Error):
+ (shouldBe.let.object.hello.get inner):
+
+ Source/_javascript_Core:
+
+ We collected profiles and found several subtests are using JSON.stringify enough. And generated strings are many serialized leaf objects.
+
+ This patch adds fast object property enumeration. When we know that source object meets some conditions, we can say that,
+ as long as structure is not changed, we can continue using property names and offset collected from the structure.
+ This way removes non observable [[Get]] operations to accelerate JSON.stringify performance for major object iteration cases.
+
+ We also extend MarkedArgumentBuffer: introducing MarkedArgumentBufferWithSize which can take default inline capacity as a template
+ parameter. This is used in JSON.stringify to increase the buffer because now we also need to record structures in MarkedArgumentBuffer.
+
+ This offers 0.4% improvement in Speedometer2 (EmberJS-TodoMVC, Vanilla-XXX, EmberJS-Debug-TodoMVC, they have enough amount of JSON.stringify
+ time).
+
+ ----------------------------------------------------------------------------------------------------------------------------------
+ | subtest | ms | ms | b / a | pValue (significance using False Discovery Rate) |
+ ----------------------------------------------------------------------------------------------------------------------------------
+ | Elm-TodoMVC |117.710000 |117.751667 |1.000354 | 0.883246 |
+ | VueJS-TodoMVC |24.500000 |24.311667 |0.992313 | 0.365130 |
+ | EmberJS-TodoMVC |126.646667 |125.738333 |0.992828 | 0.002587 (significant) |
+ | BackboneJS-TodoMVC |47.873333 |47.911667 |1.000801 | 0.762509 |
+ | Preact-TodoMVC |17.020000 |17.070000 |1.002938 | 0.786799 |
+ | AngularJS-TodoMVC |129.856667 |129.353333 |0.996124 | 0.177632 |
+ | Vanilla-ES2015-TodoMVC |61.698333 |61.120000 |0.990626 | 0.000003 (significant) |
+ | Inferno-TodoMVC |62.840000 |62.496667 |0.994536 | 0.312340 |
+ | Flight-TodoMVC |77.095000 |76.936667 |0.997946 | 0.702724 |
+ | Angular2-TypeScript-TodoMVC |39.740000 |39.191667 |0.986202 | 0.053485 |
+ | VanillaJS-TodoMVC |49.008333 |48.346667 |0.986499 | 0.000638 (significant) |
+ | jQuery-TodoMVC |216.785000 |217.188333 |1.001861 | 0.270747 |
+ | EmberJS-Debug-TodoMVC |344.230000 |342.993333 |0.996407 | 0.012262 (significant) |
+ | React-TodoMVC |85.461667 |85.411667 |0.999415 | 0.758049 |
+ | React-Redux-TodoMVC |140.681667 |140.640000 |0.999704 | 0.871277 |
+ | Vanilla-ES2015-Babel-Webpack-TodoMVC |59.928333 |59.351667 |0.990377 | 0.000000 (significant) |
+ ----------------------------------------------------------------------------------------------------------------------------------
+ a mean = 264.40650
+ b mean = 265.51533
+ pValue = 0.0005567357
+ (Bigger means are better.)
+ 1.004 times better
+ Results ARE significant
+
+ * heap/Heap.cpp:
+ (JSC::Heap::addCoreConstraints):
+ * heap/Heap.h:
+ * heap/HeapInlines.h:
+ * runtime/ArgList.cpp:
+ (JSC::MarkedArgumentBufferBase::addMarkSet):
+ (JSC::MarkedArgumentBufferBase::markLists):
+ (JSC::MarkedArgumentBufferBase::slowEnsureCapacity):
+ (JSC::MarkedArgumentBufferBase::expandCapacity):
+ (JSC::MarkedArgumentBufferBase::slowAppend):
+ (JSC::MarkedArgumentBuffer::addMarkSet): Deleted.
+ (JSC::MarkedArgumentBuffer::markLists): Deleted.
+ (JSC::MarkedArgumentBuffer::slowEnsureCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::expandCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::slowAppend): Deleted.
+ * runtime/ArgList.h:
+ (JSC::MarkedArgumentBufferWithSize::MarkedArgumentBufferWithSize):
+ (JSC::MarkedArgumentBuffer::MarkedArgumentBuffer): Deleted.
+ (JSC::MarkedArgumentBuffer::~MarkedArgumentBuffer): Deleted.
+ (JSC::MarkedArgumentBuffer::size const): Deleted.
+ (JSC::MarkedArgumentBuffer::isEmpty const): Deleted.
+ (JSC::MarkedArgumentBuffer::at const): Deleted.
+ (JSC::MarkedArgumentBuffer::clear): Deleted.
+ (JSC::MarkedArgumentBuffer::appendWithAction): Deleted.
+ (JSC::MarkedArgumentBuffer::append): Deleted.
+ (JSC::MarkedArgumentBuffer::appendWithCrashOnOverflow): Deleted.
+ (JSC::MarkedArgumentBuffer::removeLast): Deleted.
+ (JSC::MarkedArgumentBuffer::last): Deleted.
+ (JSC::MarkedArgumentBuffer::takeLast): Deleted.
+ (JSC::MarkedArgumentBuffer::ensureCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::hasOverflowed): Deleted.
+ (JSC::MarkedArgumentBuffer::overflowCheckNotNeeded): Deleted.
+ (JSC::MarkedArgumentBuffer::fill): Deleted.
+ (JSC::MarkedArgumentBuffer::slotFor const): Deleted.
+ (JSC::MarkedArgumentBuffer::mallocBase): Deleted.
+ (JSC::MarkedArgumentBuffer::setNeedsOverflowCheck): Deleted.
+ (JSC::MarkedArgumentBuffer::clearNeedsOverflowCheck): Deleted.
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::Holder::hasFastObjectProperties const):
+ (JSC::Stringifier::appendStringifiedValue):
+ (JSC::Stringifier::Holder::Holder):
+ (JSC::Stringifier::Holder::appendNextProperty):
+ * runtime/ObjectConstructorInlines.h:
+ (JSC::canPerformFastPropertyEnumerationForJSONStringify):
+
+ Source/WebCore:
+
+ * Modules/webaudio/AudioWorkletProcessor.cpp:
+ (WebCore::AudioWorkletProcessor::buildJSArguments):
+ * Modules/webaudio/AudioWorkletProcessor.h:
+
+ Source/WebKitLegacy/mac:
+
+ * Plugins/Hosted/NetscapePluginInstanceProxy.h:
+ * Plugins/Hosted/NetscapePluginInstanceProxy.mm:
+ (WebKit::NetscapePluginInstanceProxy::demarshalValues):
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@282707 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2021-09-17 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Add fast property enumeration mode for JSON.stringify
+ https://bugs.webkit.org/show_bug.cgi?id=230393
+
+ Reviewed by Mark Lam.
+
+ * Modules/webaudio/AudioWorkletProcessor.cpp:
+ (WebCore::AudioWorkletProcessor::buildJSArguments):
+ * Modules/webaudio/AudioWorkletProcessor.h:
+
+2021-09-22 Alan Coon <alanc...@apple.com>
+
Cherry-pick r282615. rdar://problem/83429940
Throttle a couple of editing-related timers in cases where the user has not interacted with subframes
Modified: branches/safari-612-branch/Source/WebCore/Modules/webaudio/AudioWorkletProcessor.cpp (282942 => 282943)
--- branches/safari-612-branch/Source/WebCore/Modules/webaudio/AudioWorkletProcessor.cpp 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/WebCore/Modules/webaudio/AudioWorkletProcessor.cpp 2021-09-23 05:14:29 UTC (rev 282943)
@@ -213,7 +213,7 @@
ASSERT(!isMainThread());
}
-void AudioWorkletProcessor::buildJSArguments(VM& vm, JSGlobalObject& globalObject, MarkedArgumentBuffer& args, const Vector<RefPtr<AudioBus>>& inputs, Vector<Ref<AudioBus>>& outputs, const HashMap<String, std::unique_ptr<AudioFloatArray>>& paramValuesMap)
+void AudioWorkletProcessor::buildJSArguments(VM& vm, JSGlobalObject& globalObject, MarkedArgumentBufferBase& args, const Vector<RefPtr<AudioBus>>& inputs, Vector<Ref<AudioBus>>& outputs, const HashMap<String, std::unique_ptr<AudioFloatArray>>& paramValuesMap)
{
// For performance reasons, we cache the arrays passed to JS and reconstruct them only when the topology changes.
if (!copyDataFromBusesToJSArray(vm, globalObject, inputs, toJSArray(m_jsInputs)))
Modified: branches/safari-612-branch/Source/WebCore/Modules/webaudio/AudioWorkletProcessor.h (282942 => 282943)
--- branches/safari-612-branch/Source/WebCore/Modules/webaudio/AudioWorkletProcessor.h 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/WebCore/Modules/webaudio/AudioWorkletProcessor.h 2021-09-23 05:14:29 UTC (rev 282943)
@@ -38,7 +38,7 @@
namespace JSC {
class JSArray;
-class MarkedArgumentBuffer;
+class MarkedArgumentBufferBase;
}
namespace WebCore {
@@ -67,7 +67,7 @@
private:
explicit AudioWorkletProcessor(const AudioWorkletProcessorConstructionData&);
- void buildJSArguments(JSC::VM&, JSC::JSGlobalObject&, JSC::MarkedArgumentBuffer&, const Vector<RefPtr<AudioBus>>& inputs, Vector<Ref<AudioBus>>& outputs, const HashMap<String, std::unique_ptr<AudioFloatArray>>& paramValuesMap);
+ void buildJSArguments(JSC::VM&, JSC::JSGlobalObject&, JSC::MarkedArgumentBufferBase&, const Vector<RefPtr<AudioBus>>& inputs, Vector<Ref<AudioBus>>& outputs, const HashMap<String, std::unique_ptr<AudioFloatArray>>& paramValuesMap);
String m_name;
Ref<MessagePort> m_port;
Modified: branches/safari-612-branch/Source/WebKitLegacy/mac/ChangeLog (282942 => 282943)
--- branches/safari-612-branch/Source/WebKitLegacy/mac/ChangeLog 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/WebKitLegacy/mac/ChangeLog 2021-09-23 05:14:29 UTC (rev 282943)
@@ -1,5 +1,133 @@
2021-09-22 Alan Coon <alanc...@apple.com>
+ Cherry-pick r282707. rdar://problem/83429953
+
+ [JSC] Add fast property enumeration mode for JSON.stringify
+ https://bugs.webkit.org/show_bug.cgi?id=230393
+
+ Reviewed by Mark Lam.
+
+ JSTests:
+
+ * stress/json-stringify-object-modify.js: Added.
+ (shouldBe):
+ (throw.new.Error.let.object.hello.get inner):
+ (throw.new.Error):
+ (shouldBe.let.object.hello.get inner):
+
+ Source/_javascript_Core:
+
+ We collected profiles and found several subtests are using JSON.stringify enough. And generated strings are many serialized leaf objects.
+
+ This patch adds fast object property enumeration. When we know that source object meets some conditions, we can say that,
+ as long as structure is not changed, we can continue using property names and offset collected from the structure.
+ This way removes non observable [[Get]] operations to accelerate JSON.stringify performance for major object iteration cases.
+
+ We also extend MarkedArgumentBuffer: introducing MarkedArgumentBufferWithSize which can take default inline capacity as a template
+ parameter. This is used in JSON.stringify to increase the buffer because now we also need to record structures in MarkedArgumentBuffer.
+
+ This offers 0.4% improvement in Speedometer2 (EmberJS-TodoMVC, Vanilla-XXX, EmberJS-Debug-TodoMVC, they have enough amount of JSON.stringify
+ time).
+
+ ----------------------------------------------------------------------------------------------------------------------------------
+ | subtest | ms | ms | b / a | pValue (significance using False Discovery Rate) |
+ ----------------------------------------------------------------------------------------------------------------------------------
+ | Elm-TodoMVC |117.710000 |117.751667 |1.000354 | 0.883246 |
+ | VueJS-TodoMVC |24.500000 |24.311667 |0.992313 | 0.365130 |
+ | EmberJS-TodoMVC |126.646667 |125.738333 |0.992828 | 0.002587 (significant) |
+ | BackboneJS-TodoMVC |47.873333 |47.911667 |1.000801 | 0.762509 |
+ | Preact-TodoMVC |17.020000 |17.070000 |1.002938 | 0.786799 |
+ | AngularJS-TodoMVC |129.856667 |129.353333 |0.996124 | 0.177632 |
+ | Vanilla-ES2015-TodoMVC |61.698333 |61.120000 |0.990626 | 0.000003 (significant) |
+ | Inferno-TodoMVC |62.840000 |62.496667 |0.994536 | 0.312340 |
+ | Flight-TodoMVC |77.095000 |76.936667 |0.997946 | 0.702724 |
+ | Angular2-TypeScript-TodoMVC |39.740000 |39.191667 |0.986202 | 0.053485 |
+ | VanillaJS-TodoMVC |49.008333 |48.346667 |0.986499 | 0.000638 (significant) |
+ | jQuery-TodoMVC |216.785000 |217.188333 |1.001861 | 0.270747 |
+ | EmberJS-Debug-TodoMVC |344.230000 |342.993333 |0.996407 | 0.012262 (significant) |
+ | React-TodoMVC |85.461667 |85.411667 |0.999415 | 0.758049 |
+ | React-Redux-TodoMVC |140.681667 |140.640000 |0.999704 | 0.871277 |
+ | Vanilla-ES2015-Babel-Webpack-TodoMVC |59.928333 |59.351667 |0.990377 | 0.000000 (significant) |
+ ----------------------------------------------------------------------------------------------------------------------------------
+ a mean = 264.40650
+ b mean = 265.51533
+ pValue = 0.0005567357
+ (Bigger means are better.)
+ 1.004 times better
+ Results ARE significant
+
+ * heap/Heap.cpp:
+ (JSC::Heap::addCoreConstraints):
+ * heap/Heap.h:
+ * heap/HeapInlines.h:
+ * runtime/ArgList.cpp:
+ (JSC::MarkedArgumentBufferBase::addMarkSet):
+ (JSC::MarkedArgumentBufferBase::markLists):
+ (JSC::MarkedArgumentBufferBase::slowEnsureCapacity):
+ (JSC::MarkedArgumentBufferBase::expandCapacity):
+ (JSC::MarkedArgumentBufferBase::slowAppend):
+ (JSC::MarkedArgumentBuffer::addMarkSet): Deleted.
+ (JSC::MarkedArgumentBuffer::markLists): Deleted.
+ (JSC::MarkedArgumentBuffer::slowEnsureCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::expandCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::slowAppend): Deleted.
+ * runtime/ArgList.h:
+ (JSC::MarkedArgumentBufferWithSize::MarkedArgumentBufferWithSize):
+ (JSC::MarkedArgumentBuffer::MarkedArgumentBuffer): Deleted.
+ (JSC::MarkedArgumentBuffer::~MarkedArgumentBuffer): Deleted.
+ (JSC::MarkedArgumentBuffer::size const): Deleted.
+ (JSC::MarkedArgumentBuffer::isEmpty const): Deleted.
+ (JSC::MarkedArgumentBuffer::at const): Deleted.
+ (JSC::MarkedArgumentBuffer::clear): Deleted.
+ (JSC::MarkedArgumentBuffer::appendWithAction): Deleted.
+ (JSC::MarkedArgumentBuffer::append): Deleted.
+ (JSC::MarkedArgumentBuffer::appendWithCrashOnOverflow): Deleted.
+ (JSC::MarkedArgumentBuffer::removeLast): Deleted.
+ (JSC::MarkedArgumentBuffer::last): Deleted.
+ (JSC::MarkedArgumentBuffer::takeLast): Deleted.
+ (JSC::MarkedArgumentBuffer::ensureCapacity): Deleted.
+ (JSC::MarkedArgumentBuffer::hasOverflowed): Deleted.
+ (JSC::MarkedArgumentBuffer::overflowCheckNotNeeded): Deleted.
+ (JSC::MarkedArgumentBuffer::fill): Deleted.
+ (JSC::MarkedArgumentBuffer::slotFor const): Deleted.
+ (JSC::MarkedArgumentBuffer::mallocBase): Deleted.
+ (JSC::MarkedArgumentBuffer::setNeedsOverflowCheck): Deleted.
+ (JSC::MarkedArgumentBuffer::clearNeedsOverflowCheck): Deleted.
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::Holder::hasFastObjectProperties const):
+ (JSC::Stringifier::appendStringifiedValue):
+ (JSC::Stringifier::Holder::Holder):
+ (JSC::Stringifier::Holder::appendNextProperty):
+ * runtime/ObjectConstructorInlines.h:
+ (JSC::canPerformFastPropertyEnumerationForJSONStringify):
+
+ Source/WebCore:
+
+ * Modules/webaudio/AudioWorkletProcessor.cpp:
+ (WebCore::AudioWorkletProcessor::buildJSArguments):
+ * Modules/webaudio/AudioWorkletProcessor.h:
+
+ Source/WebKitLegacy/mac:
+
+ * Plugins/Hosted/NetscapePluginInstanceProxy.h:
+ * Plugins/Hosted/NetscapePluginInstanceProxy.mm:
+ (WebKit::NetscapePluginInstanceProxy::demarshalValues):
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@282707 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2021-09-17 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Add fast property enumeration mode for JSON.stringify
+ https://bugs.webkit.org/show_bug.cgi?id=230393
+
+ Reviewed by Mark Lam.
+
+ * Plugins/Hosted/NetscapePluginInstanceProxy.h:
+ * Plugins/Hosted/NetscapePluginInstanceProxy.mm:
+ (WebKit::NetscapePluginInstanceProxy::demarshalValues):
+
+2021-09-22 Alan Coon <alanc...@apple.com>
+
Cherry-pick r282393. rdar://problem/83429703
[Hardening] Validate IDBValue's blob paths in WebIDBServer::putOrAdd()
Modified: branches/safari-612-branch/Source/WebKitLegacy/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h (282942 => 282943)
--- branches/safari-612-branch/Source/WebKitLegacy/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/WebKitLegacy/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h 2021-09-23 05:14:29 UTC (rev 282943)
@@ -310,7 +310,7 @@
void addValueToArray(NSMutableArray *, JSC::JSGlobalObject* exec, JSC::JSValue value);
bool demarshalValueFromArray(JSC::JSGlobalObject*, NSArray *array, NSUInteger& index, JSC::JSValue& result);
- void demarshalValues(JSC::JSGlobalObject*, data_t valuesData, mach_msg_type_number_t valuesLength, JSC::MarkedArgumentBuffer& result);
+ void demarshalValues(JSC::JSGlobalObject*, data_t valuesData, mach_msg_type_number_t valuesLength, JSC::MarkedArgumentBufferBase& result);
class LocalObjectMap {
WTF_MAKE_NONCOPYABLE(LocalObjectMap);
Modified: branches/safari-612-branch/Source/WebKitLegacy/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm (282942 => 282943)
--- branches/safari-612-branch/Source/WebKitLegacy/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm 2021-09-23 05:14:23 UTC (rev 282942)
+++ branches/safari-612-branch/Source/WebKitLegacy/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm 2021-09-23 05:14:29 UTC (rev 282943)
@@ -1433,7 +1433,7 @@
return value;
}
-void NetscapePluginInstanceProxy::demarshalValues(JSGlobalObject* lexicalGlobalObject, data_t valuesData, mach_msg_type_number_t valuesLength, MarkedArgumentBuffer& result)
+void NetscapePluginInstanceProxy::demarshalValues(JSGlobalObject* lexicalGlobalObject, data_t valuesData, mach_msg_type_number_t valuesLength, MarkedArgumentBufferBase& result)
{
RetainPtr<NSData> data = "" alloc] initWithBytesNoCopy:valuesData length:valuesLength freeWhenDone:NO]);