Diff
Modified: trunk/Source/WTF/wtf/Lock.cpp (274988 => 274989)
--- trunk/Source/WTF/wtf/Lock.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WTF/wtf/Lock.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -42,11 +42,19 @@
void Lock::unlockSlow()
{
+ // Heap allocations are forbidden on the certain threads (e.g. audio rendering thread) for performance reasons so we need to
+ // explicitly allow the following allocation(s). In some rare cases, the unlockSlow() algorith may cause allocations.
+ DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
+
DefaultLockAlgorithm::unlockSlow(m_byte, DefaultLockAlgorithm::Unfair);
}
void Lock::unlockFairlySlow()
{
+ // Heap allocations are forbidden on the certain threads (e.g. audio rendering thread) for performance reasons so we need to
+ // explicitly allow the following allocation(s). In some rare cases, the unlockSlow() algorith may cause allocations.
+ DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
+
DefaultLockAlgorithm::unlockSlow(m_byte, DefaultLockAlgorithm::Fair);
}
Modified: trunk/Source/WebCore/ChangeLog (274988 => 274989)
--- trunk/Source/WebCore/ChangeLog 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/ChangeLog 2021-03-25 00:46:39 UTC (rev 274989)
@@ -1,5 +1,28 @@
2021-03-24 Chris Dumez <[email protected]>
+ Extend WebAudio heap allocation assertions to cover the pre & post-rendering phases
+ https://bugs.webkit.org/show_bug.cgi?id=223640
+
+ Reviewed by Sam Weinig.
+
+ Extend WebAudio heap allocation assertions to cover the pre & post-rendering phases. I had to add
+ exceptions for some heap allocations that are currently happening during this phase but I
+ will work to reduce the number of exceptions in follow-ups.
+
+ * Modules/webaudio/AudioDestinationNode.cpp:
+ (WebCore::AudioDestinationNode::render):
+ * Modules/webaudio/AudioNodeInput.cpp:
+ (WebCore::AudioNodeInput::updateInternalBus):
+ * Modules/webaudio/AudioNodeOutput.cpp:
+ (WebCore::AudioNodeOutput::updateInternalBus):
+ * Modules/webaudio/BaseAudioContext.cpp:
+ (WebCore::BaseAudioContext::addAutomaticPullNode):
+ (WebCore::BaseAudioContext::updateAutomaticPullNodes):
+ * platform/audio/AudioDSPKernelProcessor.cpp:
+ (WebCore::AudioDSPKernelProcessor::initialize):
+
+2021-03-24 Chris Dumez <[email protected]>
+
Unreviewed build fix after r274983.
* Modules/mediasession/MediaSession.h:
Modified: trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.cpp (274988 => 274989)
--- trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -63,6 +63,11 @@
DenormalDisabler denormalDisabler;
context().setAudioThread(Thread::current());
+
+ // For performance reasons, we forbid heap allocations while doing rendering on the audio thread.
+ // Heap allocations that cannot be avoided or have not been fixed yet can be allowed using
+ // DisableMallocRestrictionsForCurrentThreadScope scope variables.
+ ForbidMallocUseForCurrentThreadScope forbidMallocUse;
if (!context().isInitialized()) {
destinationBus->zero();
@@ -86,24 +91,20 @@
if (workletGlobalScope)
workletGlobalScope->handlePreRenderTasks();
- {
- ForbidMallocUseForCurrentThreadScope forbidMallocUse;
+ // This will cause the node(s) connected to us to process, which in turn will pull on their input(s),
+ // all the way backwards through the rendering graph.
+ AudioBus* renderedBus = input(0)->pull(destinationBus, numberOfFrames);
- // This will cause the node(s) connected to us to process, which in turn will pull on their input(s),
- // all the way backwards through the rendering graph.
- AudioBus* renderedBus = input(0)->pull(destinationBus, numberOfFrames);
+ if (!renderedBus)
+ destinationBus->zero();
+ else if (renderedBus != destinationBus) {
+ // in-place processing was not possible - so copy
+ destinationBus->copyFrom(*renderedBus);
+ }
- if (!renderedBus)
- destinationBus->zero();
- else if (renderedBus != destinationBus) {
- // in-place processing was not possible - so copy
- destinationBus->copyFrom(*renderedBus);
- }
+ // Process nodes which need a little extra help because they are not connected to anything, but still need to process.
+ context().processAutomaticPullNodes(numberOfFrames);
- // Process nodes which need a little extra help because they are not connected to anything, but still need to process.
- context().processAutomaticPullNodes(numberOfFrames);
- }
-
// Let the context take care of any business at the end of each render quantum.
context().handlePostRenderTasks();
Modified: trunk/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp (274988 => 274989)
--- trunk/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -103,6 +103,9 @@
if (numberOfInputChannels == m_internalSummingBus->numberOfChannels())
return;
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
+ DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
m_internalSummingBus = AudioBus::create(numberOfInputChannels, AudioUtilities::renderQuantumSize);
}
Modified: trunk/Source/WebCore/Modules/webaudio/AudioNodeOutput.cpp (274988 => 274989)
--- trunk/Source/WebCore/Modules/webaudio/AudioNodeOutput.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/Modules/webaudio/AudioNodeOutput.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -68,6 +68,9 @@
if (numberOfChannels() == m_internalBus->numberOfChannels())
return;
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
+ DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
m_internalBus = AudioBus::create(numberOfChannels(), AudioUtilities::renderQuantumSize);
}
Modified: trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp (274988 => 274989)
--- trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -197,7 +197,8 @@
m_playbackState = FINISHED_STATE;
context().decrementActiveSourceCount();
- // Dispatching a Function to the main thread requires heap allocations.
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
callOnMainThread([this, protectedThis = makeRef(*this)] {
auto release = makeScopeExit([&] () {
Modified: trunk/Source/WebCore/Modules/webaudio/AudioSummingJunction.cpp (274988 => 274989)
--- trunk/Source/WebCore/Modules/webaudio/AudioSummingJunction.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/Modules/webaudio/AudioSummingJunction.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -129,9 +129,12 @@
void AudioSummingJunction::outputEnabledStateChanged(AudioNodeOutput& output)
{
ASSERT(context().isGraphOwner());
- if (!m_pendingRenderingOutputs)
+ if (!m_pendingRenderingOutputs) {
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
+ DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
m_pendingRenderingOutputs.emplace(m_outputs);
- else
+ } else
m_pendingRenderingOutputs->updatedEnabledState(output);
markRenderingStateAsDirty();
}
Modified: trunk/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.cpp (274988 => 274989)
--- trunk/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -187,8 +187,13 @@
{
m_currentFrame = currentFrame;
- // This takes care of processing the MicroTask queue after rendering.
- m_lockDuringRendering = WTF::nullopt;
+ {
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
+ DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
+ // This takes care of processing the MicroTask queue after rendering.
+ m_lockDuringRendering = WTF::nullopt;
+ }
}
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/webaudio/AudioWorkletNode.cpp (274988 => 274989)
--- trunk/Source/WebCore/Modules/webaudio/AudioWorkletNode.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/Modules/webaudio/AudioWorkletNode.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -276,7 +276,8 @@
{
ASSERT(!isMainThread());
- // Dispatching a Function to the main thread requires heap allocations.
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
callOnMainThread([this, protectedThis = makeRef(*this), error]() mutable {
String errorMessage;
Modified: trunk/Source/WebCore/Modules/webaudio/AudioWorkletProcessor.cpp (274988 => 274989)
--- trunk/Source/WebCore/Modules/webaudio/AudioWorkletProcessor.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/Modules/webaudio/AudioWorkletProcessor.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -231,7 +231,10 @@
bool AudioWorkletProcessor::process(const Vector<RefPtr<AudioBus>>& inputs, Vector<Ref<AudioBus>>& outputs, const HashMap<String, std::unique_ptr<AudioFloatArray>>& paramValuesMap, bool& threwException)
{
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
+
ASSERT(m_processCallback);
auto& globalObject = *m_processCallback->globalObject();
ASSERT(globalObject.scriptExecutionContext());
Modified: trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp (274988 => 274989)
--- trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -782,6 +782,10 @@
// Make sure to call deleteMarkedNodes() on main thread.
if (m_nodesMarkedForDeletion.size() && !m_isDeletionScheduled) {
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
+ DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
+
m_nodesToDelete.appendVector(m_nodesMarkedForDeletion);
m_nodesMarkedForDeletion.clear();
@@ -824,7 +828,10 @@
void BaseAudioContext::markSummingJunctionDirty(AudioSummingJunction* summingJunction)
{
- ASSERT(isGraphOwner());
+ ASSERT(isGraphOwner());
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
+ DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
m_dirtySummingJunctions.add(summingJunction);
}
@@ -870,6 +877,9 @@
{
ASSERT(isGraphOwner());
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
+ DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
if (m_automaticPullNodes.add(&node).isNewEntry)
m_automaticPullNodesNeedUpdating = true;
}
@@ -887,6 +897,10 @@
ASSERT(isGraphOwner());
if (m_automaticPullNodesNeedUpdating) {
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
+ DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
+
// Copy from m_automaticPullNodes to m_renderingAutomaticPullNodes.
m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size());
@@ -913,6 +927,10 @@
void BaseAudioContext::isPlayingAudioDidChange()
{
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
+ DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
+
// Make sure to call Document::updateIsPlayingMedia() on the main thread, since
// we could be on the audio I/O thread here and the call into WebCore could block.
callOnMainThread([protectedThis = makeRef(*this)] {
Modified: trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceCocoa.cpp (274988 => 274989)
--- trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceCocoa.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceCocoa.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -79,7 +79,8 @@
auto description = streamDescription(m_currentSettings.sampleRate(), bus.numberOfChannels());
if (!audioBuffer || audioBuffer->channelCount() != bus.numberOfChannels()) {
- // FIXME: We should avoid this WebAudioBufferList allocation on the audio thread.
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
m_audioBuffer = makeUnique<WebAudioBufferList>(description, WTF::safeCast<uint32_t>(numberOfFrames));
audioBuffer = &downcast<WebAudioBufferList>(*m_audioBuffer);
Modified: trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp (274988 => 274989)
--- trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -210,7 +210,8 @@
// m_bufferReadWriteIndex will wrap back around to 0 when the current input and output buffers are full.
// When this happens, fire an event and swap buffers.
if (!m_bufferReadWriteIndex) {
- // Dispatching a Function to the main thread requires heap allocations.
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
// Reference ourself so we don't accidentally get deleted before fireProcessEvent() gets called.
Modified: trunk/Source/WebCore/platform/audio/AudioDSPKernelProcessor.cpp (274988 => 274989)
--- trunk/Source/WebCore/platform/audio/AudioDSPKernelProcessor.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/platform/audio/AudioDSPKernelProcessor.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -50,11 +50,15 @@
return;
ASSERT(!m_kernels.size());
+ {
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
+ DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
- // Create processing kernels, one per channel.
- for (unsigned i = 0; i < numberOfChannels(); ++i)
- m_kernels.append(createKernel());
-
+ // Create processing kernels, one per channel.
+ for (unsigned i = 0; i < numberOfChannels(); ++i)
+ m_kernels.append(createKernel());
+ }
m_initialized = true;
m_hasJustReset = true;
}
Modified: trunk/Source/WebCore/platform/audio/cocoa/AudioSampleDataSource.mm (274988 => 274989)
--- trunk/Source/WebCore/platform/audio/cocoa/AudioSampleDataSource.mm 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/platform/audio/cocoa/AudioSampleDataSource.mm 2021-03-25 00:46:39 UTC (rev 274989)
@@ -112,7 +112,8 @@
m_outputDescription = CAAudioStreamDescription { format };
{
- // FIXME: This does heap allocations on the audio thread.
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
m_ringBuffer->allocate(format, static_cast<size_t>(m_maximumSampleCount));
m_scratchBuffer = AudioSampleBufferList::create(m_outputDescription->streamDescription(), m_maximumSampleCount);
Modified: trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateMock.cpp (274988 => 274989)
--- trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateMock.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateMock.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -77,6 +77,8 @@
void MediaRecorderPrivateMock::audioSamplesAvailable(const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t)
{
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
auto locker = holdLock(m_bufferLock);
m_buffer.append("Audio Track ID: ");
Modified: trunk/Source/WebCore/platform/mediarecorder/cocoa/AudioSampleBufferCompressor.mm (274988 => 274989)
--- trunk/Source/WebCore/platform/mediarecorder/cocoa/AudioSampleBufferCompressor.mm 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/platform/mediarecorder/cocoa/AudioSampleBufferCompressor.mm 2021-03-25 00:46:39 UTC (rev 274989)
@@ -509,6 +509,8 @@
void AudioSampleBufferCompressor::addSampleBuffer(CMSampleBufferRef buffer)
{
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
m_serialDispatchQueue->dispatchSync([this, buffer] {
if (m_isEncoding)
Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp (274988 => 274989)
--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -175,7 +175,8 @@
if (m_hasStartedProducingData)
return;
- // Dispatching a Function to the main thread requires heap allocations.
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
callOnMainThread([protectedThis = makeRef(*this)] {
if (protectedThis->m_hasStartedProducingData)
Modified: trunk/Source/WebCore/platform/mediastream/mac/RealtimeOutgoingAudioSourceCocoa.cpp (274988 => 274989)
--- trunk/Source/WebCore/platform/mediastream/mac/RealtimeOutgoingAudioSourceCocoa.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebCore/platform/mediastream/mac/RealtimeOutgoingAudioSourceCocoa.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -118,6 +118,8 @@
if (!hasBufferedEnoughData())
return;
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
LibWebRTCProvider::callOnWebRTCSignalingThread([protectedThis = makeRef(*this)] {
protectedThis->pullAudioData();
Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp (274988 => 274989)
--- trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp 2021-03-25 00:33:19 UTC (rev 274988)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp 2021-03-25 00:46:39 UTC (rev 274989)
@@ -118,7 +118,8 @@
void MediaRecorderPrivate::audioSamplesAvailable(const MediaTime& time, const PlatformAudioData& audioData, const AudioStreamDescription& description, size_t numberOfFrames)
{
- // FIXME: This does heap allocations on the audio thread.
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
if (m_description != description) {
@@ -147,7 +148,8 @@
void MediaRecorderPrivate::storageChanged(SharedMemory* storage, const WebCore::CAAudioStreamDescription& format, size_t frameCount)
{
- // FIXME: This does heap allocations on the audio thread.
+ // Heap allocations are forbidden on the audio thread for performance reasons so we need to
+ // explicitly allow the following allocation(s).
DisableMallocRestrictionsForCurrentThreadScope disableMallocRestrictions;
SharedMemory::Handle handle;