Commit 76215811 authored by ggaren@apple.com's avatar ggaren@apple.com

First step toward incremental Weak<T> finalization

https://bugs.webkit.org/show_bug.cgi?id=82670

Reviewed by Filip Pizlo.

Source/JavaScriptCore: 

This patch implements a Weak<T> heap that is compatible with incremental
finalization, while making as few behavior changes as possible. The behavior
changes it makes are:

(*) Weak<T>'s raw JSValue no longer reverts to JSValue() automatically --
instead, a separate flag indicates that the JSValue is no longer valid.
(This is required so that the JSValue can be preserved for later finalization.)
Objects dealing with WeakImpls directly must change to check the flag.

(*) Weak<T> is no longer a subclass of Handle<T>.

(*) DOM GC performance is different -- 9% faster in the geometric mean,
but 15% slower in one specific case:
        gc-dom1.html: 6%  faster
        gc-dom2.html: 23% faster
        gc-dom3.html: 17% faster
        gc-dom4.html: 15% *slower*

The key features of this new heap are:

(*) Each block knows its own state, independent of any other blocks.

(*) Each block caches its own sweep result.

(*) The heap visits dead Weak<T>s at the end of GC. (It doesn't
mark them yet, since that would be a behavior change.)

* API/JSCallbackObject.cpp:
(JSC::JSCallbackObjectData::finalize):
* API/JSCallbackObjectFunctions.h:
(JSC::::init): Updated to use the new WeakHeap API.

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.gypi:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri: Paid the build system tax since I added some new files.

* heap/Handle.h: Made WeakBlock a friend and exposed slot() as public,
so we can keep passing a Handle<T> to finalizers, to avoid more surface
area change in this patch. A follow-up patch should change the type we
pass to finalizers.

* heap/HandleHeap.cpp:
(JSC):
(JSC::HandleHeap::writeBarrier):
(JSC::HandleHeap::isLiveNode):
* heap/HandleHeap.h:
(JSC):
(HandleHeap):
(Node):
(JSC::HandleHeap::Node::Node): Removed all code related to Weak<T>, since
we have a separate WeakHeap now.

* heap/Heap.cpp:
(JSC::Heap::Heap): Removed m_extraCost because extra cost is accounted
for through our watermark now. Removed m_waterMark because it was unused.

(JSC::Heap::destroy): Updated for addition of WeakHeap.

(JSC::Heap::reportExtraMemoryCostSlowCase): Changed from using its own
variable to participating in the watermark strategy. I wanted to standardize
WeakHeap and all other Heap clients on this strategy, to make sure it's
accurate.
 
(JSC::Heap::markRoots): Updated for addition of WeakHeap. Added WeakHeap
dead visit pass, as explained above.

(JSC::Heap::collect):
(JSC::Heap::resetAllocators): Updated for addition of WeakHeap.

(JSC::Heap::addFinalizer):
(JSC::Heap::FinalizerOwner::finalize): Updated for new Weak<T> API.

* heap/Heap.h:
(JSC::Heap::weakHeap):
(Heap):
(JSC::Heap::addToWaterMark): Added a way to participate in the watermarking
strategy, since this is the best way for WeakHeap to report its memory
cost. (I plan to update this in a follow-up patch to make it more accurate,
but for now it is not less accurate than it used to be.)

* heap/MarkedSpace.cpp:
(JSC::MarkedSpace::MarkedSpace):
(JSC::MarkedSpace::resetAllocators):
* heap/MarkedSpace.h:
(MarkedSpace):
(JSC::MarkedSpace::addToWaterMark):
(JSC::MarkedSpace::didConsumeFreeList): Removed m_nurseryWaterMark because
it was unused, and I didn't want to update WeakHeap to keep an usused
variable working. Added API for above.

* heap/PassWeak.h:
(JSC):
(WeakImplAccessor):
(PassWeak):
(JSC::::operator):
(JSC::::get):
(JSC::::was):
(JSC::::PassWeak):
(JSC::::~PassWeak):
(JSC::UnspecifiedBoolType):
(JSC::::leakImpl):
(JSC::adoptWeak):
* heap/Strong.h:
(JSC::Strong::operator!):
(Strong):
(JSC::Strong::operator UnspecifiedBoolType*):
(JSC::Strong::get):
* heap/Weak.h:
(Weak):
(JSC::::Weak):
(JSC):
(JSC::::isHashTableDeletedValue):
(JSC::::~Weak):
(JSC::::swap):
(JSC::=):
(JSC::::operator):
(JSC::UnspecifiedBoolType):
(JSC::::release):
(JSC::::clear):
(JSC::::hashTableDeletedValue): Lots of code changes here, but they boil
down to two things:

(*) Allocate WeakImpls from the WeakHeap instead of Handles from the HandleHeap.

(*) Explicitly check WeakImpl::state() for non-liveness before returning
a value (explained above).

These files implement the new Weak<T> heap behavior described above:

* heap/WeakBlock.cpp: Added.
* heap/WeakBlock.h: Added.
* heap/WeakHandleOwner.cpp: Added.
* heap/WeakHandleOwner.h: Added.
* heap/WeakHeap.cpp: Added.
* heap/WeakHeap.h: Added.
* heap/WeakImpl.h: Added.

One interesting difference from the old heap is that we don't allow
clients to overwrite a WeakImpl after allocating it, and we don't recycle
WeakImpls prior to garbage collection. This is required for lazy finalization,
but it will also help us esablish a useful invariant in the future: allocating
a WeakImpl will be a binding contract to run a finalizer at some point in the
future, even if the WeakImpl is later deallocated.

* jit/JITStubs.cpp:
(JSC::JITThunks::hostFunctionStub): Check the Weak<T> for ! instead of
its JSValue, since that's our API contract now, and the JSValue might
be stale.

* runtime/JSCell.h:
(JSC::jsCast): Allow casting NULL pointers because it's useful and harmless.

* runtime/Structure.cpp:
(JSC::StructureTransitionTable::add): I can't remember why I did this.

* runtime/StructureTransitionTable.h:
* runtime/WeakGCMap.h: I had to update these classes because they allocate
and deallocate weak pointers manually. They should probably stop doing that.

Source/WebCore: 

Updated WebCore for Weak<T> API changes.

* bindings/js/DOMWrapperWorld.cpp:
(WebCore::JSStringOwner::finalize): We're not allowed to get() a dead Weak<T>
anymore, so use the debug-only was() helper function instead.

* bindings/js/JSDOMBinding.h:
(WebCore::uncacheWrapper): Ditto.

* bindings/js/JSNodeCustom.h:
(WebCore::setInlineCachedWrapper):
(WebCore::clearInlineCachedWrapper): We're not allowed to get() a dead
Weak<T>, so I had to push down these ASSERTs into ScriptWrappable.

* bindings/js/JSNodeFilterCondition.cpp:
(WebCore::JSNodeFilterCondition::acceptNode): Updated for non-Handle-ness
of Weak<T>.

* bindings/js/ScriptWrappable.h:
(WebCore::ScriptWrappable::setWrapper):
(WebCore::ScriptWrappable::clearWrapper): Use was(), as above.

Source/WebKit2: 

Updated for API change.

* WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp:
(WebKit::NPRuntimeObjectMap::finalize):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@113141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 5eff11be
......@@ -65,8 +65,7 @@ void JSCallbackObjectData::finalize(Handle<Unknown> handle, void* context)
for (; jsClass; jsClass = jsClass->parentClass)
if (JSObjectFinalizeCallback finalize = jsClass->finalize)
finalize(thisRef);
HandleSlot slot = handle.slot();
HandleHeap::heapFor(slot)->deallocate(slot);
WeakHeap::deallocate(WeakImpl::asWeakImpl(handle.slot()));
}
} // namespace JSC
......@@ -102,14 +102,11 @@ void JSCallbackObject<Parent>::init(ExecState* exec)
initialize(toRef(exec), toRef(this));
}
bool needsFinalizer = false;
for (JSClassRef jsClassPtr = classRef(); jsClassPtr && !needsFinalizer; jsClassPtr = jsClassPtr->parentClass)
needsFinalizer = jsClassPtr->finalize;
if (needsFinalizer) {
HandleSlot slot = exec->globalData().heap.handleHeap()->allocate();
HandleHeap::heapFor(slot)->makeWeak(slot, m_callbackObjectData.get(), classRef());
HandleHeap::heapFor(slot)->writeBarrier(slot, this);
*slot = this;
for (JSClassRef jsClassPtr = classRef(); jsClassPtr; jsClassPtr = jsClassPtr->parentClass) {
if (jsClassPtr->finalize) {
exec->globalData().heap.weakHeap()->allocate(this, m_callbackObjectData.get(), classRef());
break;
}
}
}
......
......@@ -86,16 +86,19 @@ SET(JavaScriptCore_SOURCES
dfg/DFGVirtualRegisterAllocationPhase.cpp
heap/CopiedSpace.cpp
heap/ConservativeRoots.cpp
heap/DFGCodeBlocks.cpp
heap/Heap.cpp
heap/HandleHeap.cpp
heap/HandleStack.cpp
heap/Heap.cpp
heap/MachineStackMarker.cpp
heap/MarkedAllocator.cpp
heap/MarkedBlock.cpp
heap/MarkedSpace.cpp
heap/ConservativeRoots.cpp
heap/MarkStack.cpp
heap/WeakHeap.cpp
heap/WeakHandleOwner.cpp
heap/WeakBlock.cpp
debugger/Debugger.cpp
debugger/DebuggerActivation.cpp
......
2012-03-29 Geoffrey Garen <ggaren@apple.com>
First step toward incremental Weak<T> finalization
https://bugs.webkit.org/show_bug.cgi?id=82670
Reviewed by Filip Pizlo.
This patch implements a Weak<T> heap that is compatible with incremental
finalization, while making as few behavior changes as possible. The behavior
changes it makes are:
(*) Weak<T>'s raw JSValue no longer reverts to JSValue() automatically --
instead, a separate flag indicates that the JSValue is no longer valid.
(This is required so that the JSValue can be preserved for later finalization.)
Objects dealing with WeakImpls directly must change to check the flag.
(*) Weak<T> is no longer a subclass of Handle<T>.
(*) DOM GC performance is different -- 9% faster in the geometric mean,
but 15% slower in one specific case:
gc-dom1.html: 6% faster
gc-dom2.html: 23% faster
gc-dom3.html: 17% faster
gc-dom4.html: 15% *slower*
The key features of this new heap are:
(*) Each block knows its own state, independent of any other blocks.
(*) Each block caches its own sweep result.
(*) The heap visits dead Weak<T>s at the end of GC. (It doesn't
mark them yet, since that would be a behavior change.)
* API/JSCallbackObject.cpp:
(JSC::JSCallbackObjectData::finalize):
* API/JSCallbackObjectFunctions.h:
(JSC::::init): Updated to use the new WeakHeap API.
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.gypi:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri: Paid the build system tax since I added some new files.
* heap/Handle.h: Made WeakBlock a friend and exposed slot() as public,
so we can keep passing a Handle<T> to finalizers, to avoid more surface
area change in this patch. A follow-up patch should change the type we
pass to finalizers.
* heap/HandleHeap.cpp:
(JSC):
(JSC::HandleHeap::writeBarrier):
(JSC::HandleHeap::isLiveNode):
* heap/HandleHeap.h:
(JSC):
(HandleHeap):
(Node):
(JSC::HandleHeap::Node::Node): Removed all code related to Weak<T>, since
we have a separate WeakHeap now.
* heap/Heap.cpp:
(JSC::Heap::Heap): Removed m_extraCost because extra cost is accounted
for through our watermark now. Removed m_waterMark because it was unused.
(JSC::Heap::destroy): Updated for addition of WeakHeap.
(JSC::Heap::reportExtraMemoryCostSlowCase): Changed from using its own
variable to participating in the watermark strategy. I wanted to standardize
WeakHeap and all other Heap clients on this strategy, to make sure it's
accurate.
(JSC::Heap::markRoots): Updated for addition of WeakHeap. Added WeakHeap
dead visit pass, as explained above.
(JSC::Heap::collect):
(JSC::Heap::resetAllocators): Updated for addition of WeakHeap.
(JSC::Heap::addFinalizer):
(JSC::Heap::FinalizerOwner::finalize): Updated for new Weak<T> API.
* heap/Heap.h:
(JSC::Heap::weakHeap):
(Heap):
(JSC::Heap::addToWaterMark): Added a way to participate in the watermarking
strategy, since this is the best way for WeakHeap to report its memory
cost. (I plan to update this in a follow-up patch to make it more accurate,
but for now it is not less accurate than it used to be.)
* heap/MarkedSpace.cpp:
(JSC::MarkedSpace::MarkedSpace):
(JSC::MarkedSpace::resetAllocators):
* heap/MarkedSpace.h:
(MarkedSpace):
(JSC::MarkedSpace::addToWaterMark):
(JSC::MarkedSpace::didConsumeFreeList): Removed m_nurseryWaterMark because
it was unused, and I didn't want to update WeakHeap to keep an usused
variable working. Added API for above.
* heap/PassWeak.h:
(JSC):
(WeakImplAccessor):
(PassWeak):
(JSC::::operator):
(JSC::::get):
(JSC::::was):
(JSC::::PassWeak):
(JSC::::~PassWeak):
(JSC::UnspecifiedBoolType):
(JSC::::leakImpl):
(JSC::adoptWeak):
* heap/Strong.h:
(JSC::Strong::operator!):
(Strong):
(JSC::Strong::operator UnspecifiedBoolType*):
(JSC::Strong::get):
* heap/Weak.h:
(Weak):
(JSC::::Weak):
(JSC):
(JSC::::isHashTableDeletedValue):
(JSC::::~Weak):
(JSC::::swap):
(JSC::=):
(JSC::::operator):
(JSC::UnspecifiedBoolType):
(JSC::::release):
(JSC::::clear):
(JSC::::hashTableDeletedValue): Lots of code changes here, but they boil
down to two things:
(*) Allocate WeakImpls from the WeakHeap instead of Handles from the HandleHeap.
(*) Explicitly check WeakImpl::state() for non-liveness before returning
a value (explained above).
These files implement the new Weak<T> heap behavior described above:
* heap/WeakBlock.cpp: Added.
* heap/WeakBlock.h: Added.
* heap/WeakHandleOwner.cpp: Added.
* heap/WeakHandleOwner.h: Added.
* heap/WeakHeap.cpp: Added.
* heap/WeakHeap.h: Added.
* heap/WeakImpl.h: Added.
One interesting difference from the old heap is that we don't allow
clients to overwrite a WeakImpl after allocating it, and we don't recycle
WeakImpls prior to garbage collection. This is required for lazy finalization,
but it will also help us esablish a useful invariant in the future: allocating
a WeakImpl will be a binding contract to run a finalizer at some point in the
future, even if the WeakImpl is later deallocated.
* jit/JITStubs.cpp:
(JSC::JITThunks::hostFunctionStub): Check the Weak<T> for ! instead of
its JSValue, since that's our API contract now, and the JSValue might
be stale.
* runtime/JSCell.h:
(JSC::jsCast): Allow casting NULL pointers because it's useful and harmless.
* runtime/Structure.cpp:
(JSC::StructureTransitionTable::add): I can't remember why I did this.
* runtime/StructureTransitionTable.h:
* runtime/WeakGCMap.h: I had to update these classes because they allocate
and deallocate weak pointers manually. They should probably stop doing that.
2012-04-03 Keishi Hattori <keishi@webkit.org>
Disable ENABLE_DATALIST for now
......@@ -250,6 +250,9 @@ javascriptcore_sources += \
Source/JavaScriptCore/heap/VTableSpectrum.cpp \
Source/JavaScriptCore/heap/VTableSpectrum.h \
Source/JavaScriptCore/heap/Weak.h \
Source/JavaScriptCore/heap/WeakBlock.cpp \
Source/JavaScriptCore/heap/WeakHeap.cpp \
Source/JavaScriptCore/heap/WeakHandleOwner.cpp \
Source/JavaScriptCore/heap/WeakReferenceHarvester.h \
Source/JavaScriptCore/heap/WriteBarrierSupport.cpp \
Source/JavaScriptCore/heap/WriteBarrierSupport.h \
......
......@@ -217,6 +217,9 @@
'bytecompiler/NodesCodegen.cpp',
'bytecompiler/RegisterID.h',
'heap/ConservativeRoots.cpp',
'heap/WeakHeap.cpp',
'heap/WeakHandleOwner.cpp',
'heap/WeakBlock.cpp',
'heap/HandleHeap.cpp',
'heap/HandleStack.cpp',
'heap/Heap.cpp',
......
......@@ -5,9 +5,9 @@ EXPORTS
??$strtod@$0A@$00@WTF@@YANPBDPAPAD@Z
??$strtod@$0A@$0A@@WTF@@YANPBDPAPAD@Z
??0ArrayBufferView@WTF@@IAE@V?$PassRefPtr@VArrayBuffer@WTF@@@1@I@Z
??0Collator@WTF@@QAE@PBD@Z
??0CString@WTF@@QAE@PBD@Z
??0CString@WTF@@QAE@PBDI@Z
??0Collator@WTF@@QAE@PBD@Z
??0DateInstance@JSC@@IAE@PAVExecState@1@PAVStructure@1@@Z
??0DefaultGCActivityCallback@JSC@@QAE@PAVHeap@1@@Z
??0DropAllLocks@JSLock@JSC@@QAE@W4JSLockBehavior@2@@Z
......@@ -25,10 +25,10 @@ EXPORTS
??0StringObject@JSC@@IAE@AAVJSGlobalData@1@PAVStructure@1@@Z
??0Structure@JSC@@AAE@AAVJSGlobalData@1@PAVJSGlobalObject@1@VJSValue@1@ABVTypeInfo@1@PBUClassInfo@1@@Z
??0ThreadCondition@WTF@@QAE@XZ
??0UString@JSC@@QAE@PBD@Z
??0UString@JSC@@QAE@PBDI@Z
??0UString@JSC@@QAE@PB_W@Z
??0UString@JSC@@QAE@PB_WI@Z
??0UString@JSC@@QAE@PBD@Z
??0UString@JSC@@QAE@PBDI@Z
??0WTFThreadData@WTF@@QAE@XZ
??0YarrPattern@Yarr@JSC@@QAE@ABVUString@2@_N1PAPBD@Z
??1ArrayBufferView@WTF@@UAE@XZ
......@@ -42,15 +42,10 @@ EXPORTS
??1RefCountedLeakCounter@WTF@@QAE@XZ
??1SourceProviderCache@JSC@@QAE@XZ
??1ThreadCondition@WTF@@QAE@XZ
??1WTFThreadData@WTF@@QAE@XZ
??1WeakHandleOwner@JSC@@UAE@XZ
??1WTFThreadData@WTF@@QAE@XZ
??8JSC@@YA_NABVUString@0@0@Z
??8WTF@@YA_NABVCString@0@0@Z
?EcmaScriptConverter@DoubleToStringConverter@double_conversion@WTF@@SAABV123@XZ
?ToExponential@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z
?ToFixed@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z
?ToPrecision@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z
?ToShortest@DoubleToStringConverter@double_conversion@WTF@@QBE_NNPAVStringBuilder@23@@Z
?absoluteTimeToWaitTimeoutInterval@WTF@@YAKN@Z
?activityCallback@Heap@JSC@@QAEPAVGCActivityCallback@2@XZ
?add@AtomicString@WTF@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@2@PBD@Z
......@@ -69,8 +64,8 @@ EXPORTS
?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z
?allocatePropertyStorage@JSObject@JSC@@QAEXAAVJSGlobalData@2@II@Z
?allocateSlowCase@MarkedAllocator@JSC@@AAEPAXXZ
?append@StringBuilder@WTF@@QAEXPBEI@Z
?append@StringBuilder@WTF@@QAEXPB_WI@Z
?append@StringBuilder@WTF@@QAEXPBEI@Z
?ascii@UString@JSC@@QBE?AVCString@WTF@@XZ
?attach@Debugger@JSC@@QAEXPAVJSGlobalObject@2@@Z
?broadcast@ThreadCondition@WTF@@QAEXXZ
......@@ -78,10 +73,10 @@ EXPORTS
?bufferLengthForStringExponential@DecimalNumber@WTF@@QBEIXZ
?byteCompile@Yarr@JSC@@YA?AV?$PassOwnPtr@UBytecodePattern@Yarr@JSC@@@WTF@@AAUYarrPattern@12@PAVBumpPointerAllocator@4@@Z
?byteSize@SourceProviderCache@JSC@@QBEIXZ
?calculatedFunctionName@DebuggerCallFrame@JSC@@QBE?AVUString@2@XZ
?calculateDSTOffset@WTF@@YANNN@Z
?calculateStringHashAndLengthFromUTF8@Unicode@WTF@@YAIPBD0AAI1@Z
?calculateUTCOffset@WTF@@YAHXZ
?calculatedFunctionName@DebuggerCallFrame@JSC@@QBE?AVUString@2@XZ
?call@JSC@@YA?AVJSValue@1@PAVExecState@1@V21@W4CallType@1@ABTCallData@1@1ABVArgList@1@@Z
?callHostFunctionAsConstructor@JSC@@YI_JPAVExecState@1@@Z
?callOnMainThread@WTF@@YAXP6AXPAX@Z0@Z
......@@ -91,8 +86,8 @@ EXPORTS
?changePrototypeTransition@Structure@JSC@@SAPAV12@AAVJSGlobalData@2@PAV12@VJSValue@2@@Z
?checkCurrentIdentifierTable@Identifier@JSC@@CAXPAVExecState@2@@Z
?checkCurrentIdentifierTable@Identifier@JSC@@CAXPAVJSGlobalData@2@@Z
?checkSyntax@JSC@@YA_NPAVExecState@1@ABVSourceCode@1@PAVJSValue@1@@Z
?checksum@MD5@WTF@@QAEXAAV?$Vector@E$0BA@@2@@Z
?checkSyntax@JSC@@YA_NPAVExecState@1@ABVSourceCode@1@PAVJSValue@1@@Z
?className@JSObject@JSC@@SA?AVUString@2@PBV12@@Z
?clear@SourceProviderCache@JSC@@QAEXXZ
?clearBuiltinStructures@JSGlobalData@JSC@@QAEXXZ
......@@ -164,6 +159,7 @@ EXPORTS
?displayName@JSFunction@JSC@@QAE?BVUString@2@PAVExecState@2@@Z
?dtoa@WTF@@YAXQADNAA_NAAHAAI@Z
?dumpSampleData@JSGlobalData@JSC@@QAEXPAVExecState@2@@Z
?EcmaScriptConverter@DoubleToStringConverter@double_conversion@WTF@@SAABV123@XZ
?empty@StringImpl@WTF@@SAPAV12@XZ
?enumerable@PropertyDescriptor@JSC@@QBE_NXZ
?equalUTF16WithUTF8@Unicode@WTF@@YA_NPB_W0PBD1@Z
......@@ -183,6 +179,7 @@ EXPORTS
?fastZeroedMalloc@WTF@@YAPAXI@Z
?fillGetterPropertySlot@JSObject@JSC@@AAEXAAVPropertySlot@2@PAV?$WriteBarrierBase@W4Unknown@JSC@@@2@@Z
?finalize@WeakHandleOwner@JSC@@UAEXV?$Handle@W4Unknown@JSC@@@2@PAX@Z
?findAllocator@WeakHeap@JSC@@AAEPAUFreeCell@WeakBlock@2@XZ
?finishCreation@DateInstance@JSC@@IAEXAAVJSGlobalData@2@N@Z
?finishCreation@InternalFunction@JSC@@IAEXAAVJSGlobalData@2@ABVIdentifier@2@@Z
?finishCreation@JSArray@JSC@@IAEXAAVJSGlobalData@2@I@Z
......@@ -220,10 +217,10 @@ EXPORTS
?globalExec@JSGlobalObject@JSC@@QAEPAVExecState@2@XZ
?globalObjectCount@Heap@JSC@@QAEIXZ
?grow@HandleHeap@JSC@@AAEXXZ
?hashSlowCase@StringImpl@WTF@@ABEIXZ
?hasInstance@JSObject@JSC@@SA_NPAV12@PAVExecState@2@VJSValue@2@2@Z
?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@ABVIdentifier@2@@Z
?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@I@Z
?hashSlowCase@StringImpl@WTF@@ABEIXZ
?heap@Heap@JSC@@SAPAV12@VJSValue@2@@Z
?increment@RefCountedLeakCounter@WTF@@QAEXXZ
?init@AtomicString@WTF@@SAXXZ
......@@ -311,10 +308,10 @@ EXPORTS
?setOrderLowerFirst@Collator@WTF@@QAEX_N@Z
?setPrototype@JSObject@JSC@@QAEXAAVJSGlobalData@2@VJSValue@2@@Z
?setSetter@PropertyDescriptor@JSC@@QAEXVJSValue@2@@Z
?setter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ
?setUndefined@PropertyDescriptor@JSC@@QAEXXZ
?setUpStaticFunctionSlot@JSC@@YA_NPAVExecState@1@PBVHashEntry@1@PAVJSObject@1@ABVIdentifier@1@AAVPropertySlot@1@@Z
?setWritable@PropertyDescriptor@JSC@@QAEX_N@Z
?setter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ
?shrinkToFit@StringBuilder@WTF@@QAEXXZ
?signal@ThreadCondition@WTF@@QAEXXZ
?singleCharacterStringRep@SmallStrings@JSC@@QAEPAVStringImpl@WTF@@E@Z
......@@ -340,11 +337,15 @@ EXPORTS
?tlsKeyCount@WTF@@YAAAJXZ
?tlsKeys@WTF@@YAPAKXZ
?toBoolean@JSString@JSC@@QBE_NPAVExecState@2@@Z
?ToExponential@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z
?ToFixed@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z
?toInt32@JSC@@YAHN@Z
?toInteger@JSValue@JSC@@QBENPAVExecState@2@@Z
?toNumberSlowCase@JSValue@JSC@@ABENPAVExecState@2@@Z
?toObject@JSCell@JSC@@QBEPAVJSObject@2@PAVExecState@2@PAVJSGlobalObject@2@@Z
?toObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@PAVJSGlobalObject@2@@Z
?ToPrecision@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z
?ToShortest@DoubleToStringConverter@double_conversion@WTF@@QBE_NNPAVStringBuilder@23@@Z
?toString@JSObject@JSC@@QBEPAVJSString@2@PAVExecState@2@@Z
?toStringDecimal@DecimalNumber@WTF@@QBEIPA_WI@Z
?toStringExponential@DecimalNumber@WTF@@QBEIPA_WI@Z
......
......@@ -2129,6 +2129,34 @@
RelativePath="..\..\heap\HandleHeap.h"
>
</File>
<File
RelativePath="..\..\heap\WeakBlock.cpp"
>
</File>
<File
RelativePath="..\..\heap\WeakBlock.h"
>
</File>
<File
RelativePath="..\..\heap\WeakHeap.cpp"
>
</File>
<File
RelativePath="..\..\heap\WeakHeap.h"
>
</File>
<File
RelativePath="..\..\heap\WeakImpl.h"
>
</File>
<File
RelativePath="..\..\heap\WeakHandleOwner.cpp"
>
</File>
<File
RelativePath="..\..\heap\WeakHandleOwner.h"
>
</File>
<File
RelativePath="..\..\heap\HandleStack.cpp"
>
......
......@@ -323,7 +323,14 @@
14C5242B0F5355E900BA3D04 /* JITStubs.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A6581A0F4E36F4000150FD /* JITStubs.h */; settings = {ATTRIBUTES = (Private, ); }; };
14D2F3DA139F4BE200491031 /* MarkedSpace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14D2F3D8139F4BE200491031 /* MarkedSpace.cpp */; };
14D2F3DB139F4BE200491031 /* MarkedSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D2F3D9139F4BE200491031 /* MarkedSpace.h */; settings = {ATTRIBUTES = (Private, ); }; };
14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14E84F9914EE1ACC00D6D5D4 /* WeakBlock.cpp */; };
14E84F9F14EE1ACC00D6D5D4 /* WeakBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 14E84F9A14EE1ACC00D6D5D4 /* WeakBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
14E84FA014EE1ACC00D6D5D4 /* WeakHeap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14E84F9B14EE1ACC00D6D5D4 /* WeakHeap.cpp */; };
14E84FA114EE1ACC00D6D5D4 /* WeakHeap.h in Headers */ = {isa = PBXBuildFile; fileRef = 14E84F9C14EE1ACC00D6D5D4 /* WeakHeap.h */; settings = {ATTRIBUTES = (Private, ); }; };
14E84FA214EE1ACC00D6D5D4 /* WeakImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 14E84F9D14EE1ACC00D6D5D4 /* WeakImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
14E9D17B107EC469004DDA21 /* JSGlobalObjectFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */; };
14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14F7256314EE265E00B1652B /* WeakHandleOwner.cpp */; };
14F7256614EE265E00B1652B /* WeakHandleOwner.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F7256414EE265E00B1652B /* WeakHandleOwner.h */; settings = {ATTRIBUTES = (Private, ); }; };
14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F97446138C853E00DA1C67 /* HeapRootVisitor.h */; settings = {ATTRIBUTES = (Private, ); }; };
41359CF30FDD89AD00206180 /* DateConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = D21202290AD4310C00ED79B6 /* DateConversion.h */; };
451539B912DC994500EF7AC4 /* Yarr.h in Headers */ = {isa = PBXBuildFile; fileRef = 451539B812DC994500EF7AC4 /* Yarr.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -943,7 +950,14 @@
14DA818E0D99FD2000B0A4FB /* JSActivation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSActivation.h; sourceTree = "<group>"; };
14DA818F0D99FD2000B0A4FB /* JSActivation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSActivation.cpp; sourceTree = "<group>"; };
14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObject.cpp; sourceTree = "<group>"; };
14E84F9914EE1ACC00D6D5D4 /* WeakBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakBlock.cpp; sourceTree = "<group>"; };
14E84F9A14EE1ACC00D6D5D4 /* WeakBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakBlock.h; sourceTree = "<group>"; };
14E84F9B14EE1ACC00D6D5D4 /* WeakHeap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakHeap.cpp; sourceTree = "<group>"; };
14E84F9C14EE1ACC00D6D5D4 /* WeakHeap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakHeap.h; sourceTree = "<group>"; };
14E84F9D14EE1ACC00D6D5D4 /* WeakImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakImpl.h; sourceTree = "<group>"; };
14F252560D08DD8D004ECFFF /* JSVariableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVariableObject.h; sourceTree = "<group>"; };
14F7256314EE265E00B1652B /* WeakHandleOwner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakHandleOwner.cpp; sourceTree = "<group>"; };
14F7256414EE265E00B1652B /* WeakHandleOwner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakHandleOwner.h; sourceTree = "<group>"; };
14F97446138C853E00DA1C67 /* HeapRootVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapRootVisitor.h; sourceTree = "<group>"; };
1C9051420BA9E8A70081E9D0 /* Version.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = "<group>"; };
1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = JavaScriptCore.xcconfig; sourceTree = "<group>"; };
......@@ -1586,6 +1600,13 @@
0FC815121405118600CFA603 /* VTableSpectrum.cpp */,
0FC815141405118D00CFA603 /* VTableSpectrum.h */,
142E3133134FF0A600AFADB5 /* Weak.h */,
14E84F9914EE1ACC00D6D5D4 /* WeakBlock.cpp */,
14E84F9A14EE1ACC00D6D5D4 /* WeakBlock.h */,
14F7256314EE265E00B1652B /* WeakHandleOwner.cpp */,
14F7256414EE265E00B1652B /* WeakHandleOwner.h */,
14E84F9B14EE1ACC00D6D5D4 /* WeakHeap.cpp */,
14E84F9C14EE1ACC00D6D5D4 /* WeakHeap.h */,
14E84F9D14EE1ACC00D6D5D4 /* WeakImpl.h */,
0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */,
0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */,
0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */,
......@@ -2523,6 +2544,10 @@
0FFFC95E14EF90B700C72532 /* DFGPredictionPropagationPhase.h in Headers */,
0FFFC96014EF90BD00C72532 /* DFGVirtualRegisterAllocationPhase.h in Headers */,
1497209114EB831500FEB1B7 /* PassWeak.h in Headers */,
14E84F9F14EE1ACC00D6D5D4 /* WeakBlock.h in Headers */,
14E84FA114EE1ACC00D6D5D4 /* WeakHeap.h in Headers */,
14E84FA214EE1ACC00D6D5D4 /* WeakImpl.h in Headers */,
14F7256614EE265E00B1652B /* WeakHandleOwner.h in Headers */,
0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */,
0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */,
0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */,
......@@ -3079,6 +3104,9 @@
86B5826914D2797000A9C306 /* CodeProfiling.cpp in Sources */,
C2B916C514DA040C00CBAC86 /* MarkedAllocator.cpp in Sources */,
0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
14E84FA014EE1ACC00D6D5D4 /* WeakHeap.cpp in Sources */,
14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */,
0FFFC95914EF90A600C72532 /* DFGCSEPhase.cpp in Sources */,
0FFFC95B14EF90AD00C72532 /* DFGPhase.cpp in Sources */,
......
......@@ -71,6 +71,9 @@ SOURCES += \
heap/CopiedSpace.cpp \
heap/ConservativeRoots.cpp \
heap/DFGCodeBlocks.cpp \
heap/WeakHeap.cpp \
heap/WeakHandleOwner.cpp \
heap/WeakBlock.cpp \
heap/HandleHeap.cpp \
heap/HandleStack.cpp \
heap/Heap.cpp \
......
......@@ -59,6 +59,8 @@ public:
typedef JSValue (HandleBase::*UnspecifiedBoolType);
operator UnspecifiedBoolType*() const { return (m_slot && *m_slot) ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
HandleSlot slot() const { return m_slot; }
protected:
HandleBase(HandleSlot slot)
: m_slot(slot)
......@@ -67,7 +69,6 @@ protected:
void swap(HandleBase& other) { std::swap(m_slot, other.m_slot); }
HandleSlot slot() const { return m_slot; }
void setSlot(HandleSlot slot)
{
m_slot = slot;
......@@ -133,6 +134,7 @@ protected:
private:
friend class HandleHeap;
friend class WeakBlock;
static Handle<T> wrapSlot(HandleSlot slot)
{
......
......@@ -31,19 +31,6 @@
namespace JSC {
WeakHandleOwner::~WeakHandleOwner()
{
}
bool WeakHandleOwner::isReachableFromOpaqueRoots(Handle<Unknown>, void*, SlotVisitor&)
{
return false;
}
void WeakHandleOwner::finalize(Handle<Unknown>, void*)
{
}
HandleHeap::HandleHeap(JSGlobalData* globalData)
: m_globalData(globalData)
, m_nextToFinalize(0)
......@@ -73,62 +60,6 @@ void HandleHeap::visitStrongHandles(HeapRootVisitor& heapRootVisitor)
}
}
void HandleHeap::visitWeakHandles(HeapRootVisitor& heapRootVisitor)
{
SlotVisitor& visitor = heapRootVisitor.visitor();
Node* end = m_weakList.end();
for (Node* node = m_weakList.begin(); node != end; node = node->next()) {
#if ENABLE(GC_VALIDATION)
if (!isValidWeakNode(node))
CRASH();
#endif
JSCell* cell = node->slot()->asCell();
if (Heap::isMarked(cell))
continue;
WeakHandleOwner* weakOwner = node->weakOwner();
if (!weakOwner)
continue;
if (!weakOwner->isReachableFromOpaqueRoots(Handle<Unknown>::wrapSlot(node->slot()), node->weakOwnerContext(), visitor))
continue;
heapRootVisitor.visit(node->slot());
}
}
void HandleHeap::finalizeWeakHandles()
{
Node* end = m_weakList.end();
for (Node* node = m_weakList.begin(); node != end; node = m_nextToFinalize) {
m_nextToFinalize = node->next();
#if ENABLE(GC_VALIDATION)
if (!isValidWeakNode(node))
CRASH();
#endif
JSCell* cell = node->slot()->asCell();
if (Heap::isMarked(cell))
continue;
if (WeakHandleOwner* weakOwner = node->weakOwner()) {
weakOwner->finalize(Handle<Unknown>::wrapSlot(node->slot()), node->weakOwnerContext());
if (m_nextToFinalize != node->next()) // Owner deallocated node.
continue;
}
#if ENABLE(GC_VALIDATION)
if (!isLiveNode(node))
CRASH();
#endif
*node->slot() = JSValue();
SentinelLinkedList<Node>::remove(node);
m_immediateList.push(node);
}
m_nextToFinalize = 0;
}
void HandleHeap::writeBarrier(HandleSlot slot, const JSValue& value)
{
// Forbid assignment to handles during the finalization phase, since it would violate many GC invariants.
......@@ -150,15 +81,6 @@ void HandleHeap::writeBarrier(HandleSlot slot, const JSValue& value)
return;
}
if (node->isWeak()) {
m_weakList.push(node);
#if ENABLE(GC_VALIDATION)
if (!isLiveNode(node))
CRASH();
#endif
return;
}
m_strongList.push(node);
#if ENABLE(GC_VALIDATION)
if (!isLiveNode(node))
......@@ -188,24 +110,6 @@ bool HandleHeap::isLiveNode(Node* node)
return true;