Diff
Modified: trunk/Source/_javascript_Core/API/JSAPIWrapperObject.mm (179727 => 179728)
--- trunk/Source/_javascript_Core/API/JSAPIWrapperObject.mm 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/API/JSAPIWrapperObject.mm 2015-02-06 01:12:00 UTC (rev 179728)
@@ -26,7 +26,6 @@
#include "config.h"
#include "JSAPIWrapperObject.h"
-#include "DelayedReleaseScope.h"
#include "JSCInlines.h"
#include "JSCallbackObject.h"
#include "JSVirtualMachineInternal.h"
Modified: trunk/Source/_javascript_Core/API/ObjCCallbackFunction.mm (179727 => 179728)
--- trunk/Source/_javascript_Core/API/ObjCCallbackFunction.mm 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/API/ObjCCallbackFunction.mm 2015-02-06 01:12:00 UTC (rev 179728)
@@ -30,7 +30,6 @@
#import "APICallbackFunction.h"
#import "APICast.h"
-#import "DelayedReleaseScope.h"
#import "Error.h"
#import "JSCJSValueInlines.h"
#import "JSCell.h"
Modified: trunk/Source/_javascript_Core/ChangeLog (179727 => 179728)
--- trunk/Source/_javascript_Core/ChangeLog 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-02-06 01:12:00 UTC (rev 179728)
@@ -1,3 +1,77 @@
+2015-02-05 Michael Saboff <msab...@apple.com>
+
+ CodeCache is not thread safe when adding the same source from two different threads
+ https://bugs.webkit.org/show_bug.cgi?id=141275
+
+ Reviewed by Mark Lam.
+
+ The issue for this bug is that one thread, takes a cache miss in CodeCache::getGlobalCodeBlock,
+ but in the process creates a cache entry with a nullptr UnlinkedCodeBlockType* which it
+ will fill in later in the function. During the body of that function, it allocates
+ objects that may garbage collect. During that garbage collection, we drop the all locks.
+ While the locks are released by the first thread, another thread can enter the VM and might
+ have exactly the same source and enter CodeCache::getGlobalCodeBlock() itself. When it
+ looks up the code block, it sees it as a cache it and uses the nullptr UnlinkedCodeBlockType*
+ and crashes. This fixes the problem by not dropping the locks during garbage collection.
+ There are other likely scenarios where we have a data structure like this code cache in an
+ unsafe state for arbitrary reentrance.
+
+ Moved the functionality of DelayedReleaseScope directly into Heap. Changed it into
+ a simple list that is cleared with the new function Heap::releaseDelayedReleasedObjects.
+ Now we accumulate objects to be released and release them when all locks are dropped or
+ when destroying the Heap. This eliminated the dropping and reaquiring of locks associated
+ with the old scope form of this list.
+
+ Given that all functionality of DelayedReleaseScope is now used and referenced by Heap
+ and the lock management no longer needs to be done, just made the list a member of Heap.
+ We do need to guard against the case that releasing an object can create more objects
+ by calling into JS. That is why releaseDelayedReleasedObjects() is written to remove
+ an object to release so that we aren't recursively in Vector code. The other thing we
+ do in releaseDelayedReleasedObjects() is to guard against recursive calls to itself using
+ the m_delayedReleaseRecursionCount. We only release at the first entry into the function.
+ This case is already tested by testapi.mm.
+
+ * heap/DelayedReleaseScope.h: Removed file
+
+ * API/JSAPIWrapperObject.mm:
+ * API/ObjCCallbackFunction.mm:
+ * _javascript_Core.vcxproj/_javascript_Core.vcxproj:
+ * _javascript_Core.vcxproj/_javascript_Core.vcxproj.filters:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * heap/IncrementalSweeper.cpp:
+ (JSC::IncrementalSweeper::doSweep):
+ * heap/MarkedAllocator.cpp:
+ (JSC::MarkedAllocator::tryAllocateHelper):
+ (JSC::MarkedAllocator::tryAllocate):
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::sweep):
+ * heap/MarkedSpace.cpp:
+ (JSC::MarkedSpace::MarkedSpace):
+ (JSC::MarkedSpace::lastChanceToFinalize):
+ (JSC::MarkedSpace::didFinishIterating):
+ * heap/MarkedSpace.h:
+ * heap/Heap.cpp:
+ (JSC::Heap::collectAllGarbage):
+ (JSC::Heap::zombifyDeadObjects):
+ Removed references to DelayedReleaseScope and DelayedReleaseScope.h.
+
+ * heap/Heap.cpp:
+ (JSC::Heap::Heap): Initialized m_delayedReleaseRecursionCount.
+ (JSC::Heap::lastChanceToFinalize): Call releaseDelayedObjectsNow() as the VM is going away.
+ (JSC::Heap::releaseDelayedReleasedObjects): New function that released the accumulated
+ delayed release objects.
+
+ * heap/Heap.h:
+ (JSC::Heap::m_delayedReleaseObjects): List of objects to be released later.
+ (JSC::Heap::m_delayedReleaseRecursionCount): Counter to indicate that
+ releaseDelayedReleasedObjects is being called recursively.
+ * heap/HeapInlines.h:
+ (JSC::Heap::releaseSoon): Changed location of list to add delayed release objects.
+
+ * runtime/JSLock.cpp:
+ (JSC::JSLock::willReleaseLock):
+ Call Heap::releaseDelayedObjectsNow() when releasing the lock.
+
2015-02-05 Youenn Fablet <youenn.fab...@crf.canon.fr> and Xabier Rodriguez Calvar <calva...@igalia.com>
[Streams API] Implement a barebone ReadableStream interface
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj (179727 => 179728)
--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj 2015-02-06 01:12:00 UTC (rev 179728)
@@ -1230,7 +1230,6 @@
<ClInclude Include="..\heap\CopyWorkList.h" />
<ClInclude Include="..\heap\CopyWriteBarrier.h" />
<ClInclude Include="..\heap\DeferGC.h" />
- <ClInclude Include="..\heap\DelayedReleaseScope.h" />
<ClInclude Include="..\heap\EdenGCActivityCallback.h" />
<ClInclude Include="..\heap\FullGCActivityCallback.h" />
<ClInclude Include="..\heap\GCActivityCallback.h" />
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters (179727 => 179728)
--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters 2015-02-06 01:12:00 UTC (rev 179728)
@@ -3768,9 +3768,6 @@
<ClInclude Include="..\runtime\StackAlignment.h">
<Filter>runtime</Filter>
</ClInclude>
- <ClInclude Include="..\heap\DelayedReleaseScope.h">
- <Filter>heap</Filter>
- </ClInclude>
<ClInclude Include="..\bytecode\VariableWatchpointSet.h">
<Filter>bytecode</Filter>
</ClInclude>
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (179727 => 179728)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-02-06 01:12:00 UTC (rev 179728)
@@ -864,7 +864,6 @@
2A05ABD61961DF2400341750 /* JSPropertyNameEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A05ABD41961DF2400341750 /* JSPropertyNameEnumerator.h */; };
2A111245192FCE79005EE18D /* CustomGetterSetter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A111243192FCE79005EE18D /* CustomGetterSetter.cpp */; };
2A111246192FCE79005EE18D /* CustomGetterSetter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A111244192FCE79005EE18D /* CustomGetterSetter.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 2A2825D018341F2D0087FBA9 /* DelayedReleaseScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */; };
2A48D1911772365B00C65A5F /* APICallbackFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = C211B574176A224D000E2A23 /* APICallbackFunction.h */; };
2A4BB7F318A41179008A0FCD /* JSManagedValueInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A4BB7F218A41179008A0FCD /* JSManagedValueInternal.h */; };
2A4EC90B1860D6C20094F782 /* WriteBarrierBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A4EC9091860D6C20094F782 /* WriteBarrierBuffer.cpp */; };
@@ -2499,7 +2498,6 @@
2A05ABD41961DF2400341750 /* JSPropertyNameEnumerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPropertyNameEnumerator.h; sourceTree = "<group>"; };
2A111243192FCE79005EE18D /* CustomGetterSetter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CustomGetterSetter.cpp; sourceTree = "<group>"; };
2A111244192FCE79005EE18D /* CustomGetterSetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomGetterSetter.h; sourceTree = "<group>"; };
- 2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DelayedReleaseScope.h; sourceTree = "<group>"; };
2A343F7418A1748B0039B085 /* GCSegmentedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCSegmentedArray.h; sourceTree = "<group>"; };
2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCSegmentedArrayInlines.h; sourceTree = "<group>"; };
2A4BB7F218A41179008A0FCD /* JSManagedValueInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSManagedValueInternal.h; sourceTree = "<group>"; };
@@ -3848,7 +3846,6 @@
2A68295A1875F80500B6C3E2 /* CopyWriteBarrier.h */,
2A7A58EE1808A4C40020BDF7 /* DeferGC.cpp */,
0F136D4B174AD69B0075B354 /* DeferGC.h */,
- 2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */,
BCBE2CAD14E985AA000593AD /* GCAssertions.h */,
0F2B66A817B6B53D00A7AE3F /* GCIncomingRefCounted.h */,
0F2B66A917B6B53D00A7AE3F /* GCIncomingRefCountedInlines.h */,
@@ -5535,7 +5532,6 @@
FEA08621182B7A0400F6D851 /* DebuggerPrimitives.h in Headers */,
0F136D4D174AD69E0075B354 /* DeferGC.h in Headers */,
0FC712DF17CD877C008CC93C /* DeferredCompilationCallback.h in Headers */,
- 2A2825D018341F2D0087FBA9 /* DelayedReleaseScope.h in Headers */,
A77A423E17A0BBFD00A8DB81 /* DFGAbstractHeap.h in Headers */,
A5EA70E819F5B1010098F5EC /* AugmentableInspectorControllerClient.h in Headers */,
A704D90317A0BAA8006BA554 /* DFGAbstractInterpreter.h in Headers */,
Deleted: trunk/Source/_javascript_Core/heap/DelayedReleaseScope.h (179727 => 179728)
--- trunk/Source/_javascript_Core/heap/DelayedReleaseScope.h 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/heap/DelayedReleaseScope.h 2015-02-06 01:12:00 UTC (rev 179728)
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DelayedReleaseScope_h
-#define DelayedReleaseScope_h
-
-#include "Heap.h"
-#include "JSLock.h"
-#include "MarkedSpace.h"
-
-namespace JSC {
-
-#if USE(CF)
-
-class DelayedReleaseScope {
-public:
- DelayedReleaseScope(MarkedSpace& markedSpace)
- : m_markedSpace(markedSpace)
- {
- ASSERT(!m_markedSpace.m_currentDelayedReleaseScope);
- m_markedSpace.m_currentDelayedReleaseScope = this;
- }
-
- ~DelayedReleaseScope()
- {
- ASSERT(m_markedSpace.m_currentDelayedReleaseScope == this);
- m_markedSpace.m_currentDelayedReleaseScope = nullptr;
-
- HeapOperation operationInProgress = NoOperation;
- std::swap(operationInProgress, m_markedSpace.m_heap->m_operationInProgress);
-
- {
- JSLock::DropAllLocks dropAllLocks(*m_markedSpace.m_heap->vm());
- m_delayedReleaseObjects.clear();
- }
-
- std::swap(operationInProgress, m_markedSpace.m_heap->m_operationInProgress);
- }
-
- template <typename T>
- void releaseSoon(RetainPtr<T>&& object)
- {
- m_delayedReleaseObjects.append(WTF::move(object));
- }
-
- static bool isInEffectFor(MarkedSpace& markedSpace)
- {
- return markedSpace.m_currentDelayedReleaseScope;
- }
-
-private:
- MarkedSpace& m_markedSpace;
- Vector<RetainPtr<CFTypeRef>> m_delayedReleaseObjects;
-};
-
-template <typename T>
-inline void MarkedSpace::releaseSoon(RetainPtr<T>&& object)
-{
- ASSERT(m_currentDelayedReleaseScope);
- m_currentDelayedReleaseScope->releaseSoon(WTF::move(object));
-}
-
-#else // USE(CF)
-
-class DelayedReleaseScope {
-public:
- DelayedReleaseScope(MarkedSpace&)
- {
- }
-
- static bool isInEffectFor(MarkedSpace&)
- {
- return true;
- }
-};
-
-#endif // USE(CF)
-
-} // namespace JSC
-
-#endif // DelayedReleaseScope_h
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (179727 => 179728)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2015-02-06 01:12:00 UTC (rev 179728)
@@ -27,7 +27,6 @@
#include "CopiedSpaceInlines.h"
#include "CopyVisitorInlines.h"
#include "DFGWorklist.h"
-#include "DelayedReleaseScope.h"
#include "EdenGCActivityCallback.h"
#include "FullGCActivityCallback.h"
#include "GCActivityCallback.h"
@@ -337,6 +336,9 @@
, m_sweeper(std::make_unique<IncrementalSweeper>(this->vm()))
#endif
, m_deferralDepth(0)
+#if USE(CF)
+ , m_delayedReleaseRecursionCount(0)
+#endif
{
m_storageSpace.init();
if (Options::verifyHeap())
@@ -360,8 +362,22 @@
RELEASE_ASSERT(m_operationInProgress == NoOperation);
m_objectSpace.lastChanceToFinalize();
+ releaseDelayedReleasedObjects();
}
+void Heap::releaseDelayedReleasedObjects()
+{
+#if USE(CF)
+ if (!m_delayedReleaseRecursionCount++) {
+ while (!m_delayedReleaseObjects.isEmpty()) {
+ RetainPtr<CFTypeRef> objectToRelease = m_delayedReleaseObjects.takeLast();
+ objectToRelease.clear();
+ }
+ }
+ m_delayedReleaseRecursionCount--;
+#endif
+}
+
void Heap::reportExtraMemoryCostSlowCase(size_t cost)
{
// Our frequency of garbage collection tries to balance memory use against speed
@@ -966,7 +982,6 @@
collect(FullCollection);
SamplingRegion samplingRegion("Garbage Collection: Sweeping");
- DelayedReleaseScope delayedReleaseScope(m_objectSpace);
m_objectSpace.sweep();
m_objectSpace.shrink();
}
@@ -1378,7 +1393,6 @@
// Sweep now because destructors will crash once we're zombified.
{
SamplingRegion samplingRegion("Garbage Collection: Sweeping");
- DelayedReleaseScope delayedReleaseScope(m_objectSpace);
m_objectSpace.zombifySweep();
}
HeapIterationScope iterationScope(*this);
Modified: trunk/Source/_javascript_Core/heap/Heap.h (179727 => 179728)
--- trunk/Source/_javascript_Core/heap/Heap.h 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/heap/Heap.h 2015-02-06 01:12:00 UTC (rev 179728)
@@ -115,6 +115,7 @@
Heap(VM*, HeapType);
~Heap();
JS_EXPORT_PRIVATE void lastChanceToFinalize();
+ void releaseDelayedReleasedObjects();
VM* vm() const { return m_vm; }
MarkedSpace& objectSpace() { return m_objectSpace; }
@@ -231,7 +232,6 @@
friend class CopiedBlock;
friend class DeferGC;
friend class DeferGCForAWhile;
- friend class DelayedReleaseScope;
friend class GCAwareJITStubRoutine;
friend class GCLogging;
friend class HandleSet;
@@ -387,6 +387,10 @@
Vector<DFG::Worklist*> m_suspendedCompilerWorklists;
std::unique_ptr<HeapVerifier> m_verifier;
+#if USE(CF)
+ Vector<RetainPtr<CFTypeRef>> m_delayedReleaseObjects;
+ unsigned m_delayedReleaseRecursionCount;
+#endif
};
} // namespace JSC
Modified: trunk/Source/_javascript_Core/heap/HeapInlines.h (179727 => 179728)
--- trunk/Source/_javascript_Core/heap/HeapInlines.h 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/heap/HeapInlines.h 2015-02-06 01:12:00 UTC (rev 179728)
@@ -249,7 +249,7 @@
template <typename T>
inline void Heap::releaseSoon(RetainPtr<T>&& object)
{
- m_objectSpace.releaseSoon(WTF::move(object));
+ m_delayedReleaseObjects.append(WTF::move(object));
}
#endif
Modified: trunk/Source/_javascript_Core/heap/IncrementalSweeper.cpp (179727 => 179728)
--- trunk/Source/_javascript_Core/heap/IncrementalSweeper.cpp 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/heap/IncrementalSweeper.cpp 2015-02-06 01:12:00 UTC (rev 179728)
@@ -26,7 +26,6 @@
#include "config.h"
#include "IncrementalSweeper.h"
-#include "DelayedReleaseScope.h"
#include "Heap.h"
#include "JSObject.h"
#include "JSString.h"
@@ -68,7 +67,6 @@
void IncrementalSweeper::doSweep(double sweepBeginTime)
{
- DelayedReleaseScope scope(m_vm->heap.m_objectSpace);
while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) {
sweepNextBlock();
Modified: trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp (179727 => 179728)
--- trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp 2015-02-06 01:12:00 UTC (rev 179728)
@@ -26,7 +26,6 @@
#include "config.h"
#include "MarkedAllocator.h"
-#include "DelayedReleaseScope.h"
#include "GCActivityCallback.h"
#include "Heap.h"
#include "IncrementalSweeper.h"
@@ -62,47 +61,41 @@
inline void* MarkedAllocator::tryAllocateHelper(size_t bytes)
{
- // We need a while loop to check the free list because the DelayedReleaseScope
- // could cause arbitrary code to execute and exhaust the free list that we
- // thought had elements in it.
- while (!m_freeList.head) {
- DelayedReleaseScope delayedReleaseScope(*m_markedSpace);
- if (m_currentBlock) {
- ASSERT(m_currentBlock == m_nextBlockToSweep);
- m_currentBlock->didConsumeFreeList();
- m_nextBlockToSweep = m_currentBlock->next();
- }
+ if (m_currentBlock) {
+ ASSERT(m_currentBlock == m_nextBlockToSweep);
+ m_currentBlock->didConsumeFreeList();
+ m_nextBlockToSweep = m_currentBlock->next();
+ }
- MarkedBlock* next;
- for (MarkedBlock*& block = m_nextBlockToSweep; block; block = next) {
- next = block->next();
+ MarkedBlock* next;
+ for (MarkedBlock*& block = m_nextBlockToSweep; block; block = next) {
+ next = block->next();
- MarkedBlock::FreeList freeList = block->sweep(MarkedBlock::SweepToFreeList);
-
- double utilization = ((double)MarkedBlock::blockSize - (double)freeList.bytes) / (double)MarkedBlock::blockSize;
- if (utilization >= Options::minMarkedBlockUtilization()) {
- ASSERT(freeList.bytes || !freeList.head);
- m_blockList.remove(block);
- m_retiredBlocks.push(block);
- block->didRetireBlock(freeList);
- continue;
- }
-
- if (bytes > block->cellSize()) {
- block->stopAllocating(freeList);
- continue;
- }
-
- m_currentBlock = block;
- m_freeList = freeList;
- break;
- }
+ MarkedBlock::FreeList freeList = block->sweep(MarkedBlock::SweepToFreeList);
- if (!m_freeList.head) {
- m_currentBlock = 0;
- return 0;
+ double utilization = ((double)MarkedBlock::blockSize - (double)freeList.bytes) / (double)MarkedBlock::blockSize;
+ if (utilization >= Options::minMarkedBlockUtilization()) {
+ ASSERT(freeList.bytes || !freeList.head);
+ m_blockList.remove(block);
+ m_retiredBlocks.push(block);
+ block->didRetireBlock(freeList);
+ continue;
}
+
+ if (bytes > block->cellSize()) {
+ block->stopAllocating(freeList);
+ continue;
+ }
+
+ m_currentBlock = block;
+ m_freeList = freeList;
+ break;
}
+
+ if (!m_freeList.head) {
+ m_currentBlock = 0;
+ return 0;
+ }
ASSERT(m_freeList.head);
void* head = tryPopFreeList(bytes);
@@ -128,17 +121,6 @@
m_heap->m_operationInProgress = Allocation;
void* result = tryAllocateHelper(bytes);
- // Due to the DelayedReleaseScope in tryAllocateHelper, some other thread might have
- // created a new block after we thought we didn't find any free cells.
- while (!result && m_currentBlock) {
- // A new block was added by another thread so try popping the free list.
- result = tryPopFreeList(bytes);
- if (result)
- break;
- // The free list was empty, so call tryAllocateHelper to do the normal sweeping stuff.
- result = tryAllocateHelper(bytes);
- }
-
m_heap->m_operationInProgress = NoOperation;
ASSERT(result || !m_currentBlock);
return result;
Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.cpp (179727 => 179728)
--- trunk/Source/_javascript_Core/heap/MarkedBlock.cpp 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.cpp 2015-02-06 01:12:00 UTC (rev 179728)
@@ -26,7 +26,6 @@
#include "config.h"
#include "MarkedBlock.h"
-#include "DelayedReleaseScope.h"
#include "IncrementalSweeper.h"
#include "JSCell.h"
#include "JSDestructibleObject.h"
@@ -110,7 +109,6 @@
MarkedBlock::FreeList MarkedBlock::sweep(SweepMode sweepMode)
{
- ASSERT(DelayedReleaseScope::isInEffectFor(heap()->m_objectSpace));
HEAP_LOG_BLOCK_STATE_TRANSITION(this);
m_weakSet.sweep();
Modified: trunk/Source/_javascript_Core/heap/MarkedSpace.cpp (179727 => 179728)
--- trunk/Source/_javascript_Core/heap/MarkedSpace.cpp 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/heap/MarkedSpace.cpp 2015-02-06 01:12:00 UTC (rev 179728)
@@ -21,7 +21,6 @@
#include "config.h"
#include "MarkedSpace.h"
-#include "DelayedReleaseScope.h"
#include "IncrementalSweeper.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
@@ -82,7 +81,6 @@
: m_heap(heap)
, m_capacity(0)
, m_isIterating(false)
- , m_currentDelayedReleaseScope(nullptr)
{
for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
allocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::None);
@@ -114,7 +112,6 @@
void MarkedSpace::lastChanceToFinalize()
{
- DelayedReleaseScope delayedReleaseScope(*this);
stopAllocating();
forEachAllocator<LastChanceToFinalize>();
}
@@ -362,7 +359,6 @@
void MarkedSpace::didFinishIterating()
{
ASSERT(isIterating());
- DelayedReleaseScope scope(*this);
resumeAllocating();
m_isIterating = false;
}
Modified: trunk/Source/_javascript_Core/heap/MarkedSpace.h (179727 => 179728)
--- trunk/Source/_javascript_Core/heap/MarkedSpace.h 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/heap/MarkedSpace.h 2015-02-06 01:12:00 UTC (rev 179728)
@@ -36,7 +36,6 @@
namespace JSC {
-class DelayedReleaseScope;
class Heap;
class HeapIterationScope;
class JSCell;
@@ -161,7 +160,6 @@
#endif
private:
- friend class DelayedReleaseScope;
friend class LLIntOffsetsExtractor;
friend class JIT;
@@ -177,8 +175,6 @@
bool m_isIterating;
MarkedBlockSet m_blocks;
Vector<MarkedBlock*> m_blocksWithNewObjects;
-
- DelayedReleaseScope* m_currentDelayedReleaseScope;
};
template<typename Functor> inline typename Functor::ReturnType MarkedSpace::forEachLiveCell(HeapIterationScope&, Functor& functor)
Modified: trunk/Source/_javascript_Core/runtime/JSLock.cpp (179727 => 179728)
--- trunk/Source/_javascript_Core/runtime/JSLock.cpp 2015-02-06 01:07:51 UTC (rev 179727)
+++ trunk/Source/_javascript_Core/runtime/JSLock.cpp 2015-02-06 01:12:00 UTC (rev 179728)
@@ -171,8 +171,10 @@
void JSLock::willReleaseLock()
{
- if (m_vm)
+ if (m_vm) {
+ m_vm->heap.releaseDelayedReleasedObjects();
m_vm->setStackPointerAtVMEntry(nullptr);
+ }
if (m_entryAtomicStringTable) {
wtfThreadData().setCurrentAtomicStringTable(m_entryAtomicStringTable);