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

2011-03-15 Geoffrey Garen <ggaren@apple.com>

        Reviewed by Oliver Hunt.

        Removed a few more deprecatedAppends, and removed HeapRoot<T>
        https://bugs.webkit.org/show_bug.cgi?id=56422
        
        Added HeapRootMarker, a privileged class for marking direct heap roots
        that are iterated during each garbage collection. This is easier to use
        and more reliable than HeapRoot<T>, so I've removed HeapRoot<T>.

        * debugger/Debugger.cpp:
        (JSC::evaluateInGlobalCallFrame):
        * debugger/DebuggerCallFrame.cpp:
        (JSC::DebuggerCallFrame::evaluate):
        * interpreter/CallFrame.h:
        (JSC::ExecState::exception):
        * jit/JITStubs.cpp:
        (JSC::DEFINE_STUB_FUNCTION):
        * runtime/Completion.cpp:
        (JSC::evaluate): exception is no longer a HeapRoot<T>, so no need to
        call .get() on it.

        * runtime/Heap.cpp:
        (JSC::Heap::markProtectedObjects):
        (JSC::Heap::markTempSortVectors):
        (JSC::Heap::markRoots):
        * runtime/Heap.h: Updated to use HeapRootMarker.

        * runtime/JSCell.h:
        (JSC::JSCell::MarkStack::append): Added private functions for
        HeapRootMarker to use.

        * runtime/JSGlobalData.h: exception is no longer a HeapRoot<T>.

        * runtime/MarkStack.h:
        (JSC::HeapRootMarker::HeapRootMarker):
        (JSC::HeapRootMarker::mark): Added private functions for
        HeapRootMarker to use.

        * runtime/SmallStrings.cpp:
        (JSC::SmallStrings::markChildren): Updated to use HeapRootMarker.

        * runtime/SmallStrings.h:
        (JSC::SmallStrings::emptyString):
        (JSC::SmallStrings::singleCharacterString):
        (JSC::SmallStrings::singleCharacterStrings): Updated to use HeapRootMarker.

        * runtime/WriteBarrier.h: Removed HeapRoot<T>.


git-svn-id: svn://svn.chromium.org/blink/trunk@81191 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 697b8ca8
2011-03-15 Geoffrey Garen <ggaren@apple.com>
Reviewed by Oliver Hunt.
Removed a few more deprecatedAppends, and removed HeapRoot<T>
https://bugs.webkit.org/show_bug.cgi?id=56422
Added HeapRootMarker, a privileged class for marking direct heap roots
that are iterated during each garbage collection. This is easier to use
and more reliable than HeapRoot<T>, so I've removed HeapRoot<T>.
* debugger/Debugger.cpp:
(JSC::evaluateInGlobalCallFrame):
* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::evaluate):
* interpreter/CallFrame.h:
(JSC::ExecState::exception):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* runtime/Completion.cpp:
(JSC::evaluate): exception is no longer a HeapRoot<T>, so no need to
call .get() on it.
* runtime/Heap.cpp:
(JSC::Heap::markProtectedObjects):
(JSC::Heap::markTempSortVectors):
(JSC::Heap::markRoots):
* runtime/Heap.h: Updated to use HeapRootMarker.
* runtime/JSCell.h:
(JSC::JSCell::MarkStack::append): Added private functions for
HeapRootMarker to use.
* runtime/JSGlobalData.h: exception is no longer a HeapRoot<T>.
* runtime/MarkStack.h:
(JSC::HeapRootMarker::HeapRootMarker):
(JSC::HeapRootMarker::mark): Added private functions for
HeapRootMarker to use.
* runtime/SmallStrings.cpp:
(JSC::SmallStrings::markChildren): Updated to use HeapRootMarker.
* runtime/SmallStrings.h:
(JSC::SmallStrings::emptyString):
(JSC::SmallStrings::singleCharacterString):
(JSC::SmallStrings::singleCharacterStrings): Updated to use HeapRootMarker.
* runtime/WriteBarrier.h: Removed HeapRoot<T>.
2011-03-14 Geoffrey Garen <ggaren@apple.com>
Reviewed by Oliver Hunt.
Made the global object moving-GC-safe
https://bugs.webkit.org/show_bug.cgi?id=56348
SunSpider reports no change.
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::markChildren): Removed a dubious comment that
suggested we do not need to visit all our references during GC, since
that is not true in a moving GC.
Re-sorted data members by type, removed one duplicate, and added back
the one missing mark I found.
* runtime/JSGlobalObject.h: Re-sorted data members by type.
2011-03-15 Oliver Hunt <oliver@apple.com> 2011-03-15 Oliver Hunt <oliver@apple.com>
Reviewed by Geoffrey Garen. Reviewed by Geoffrey Garen.
......
...@@ -2638,7 +2638,6 @@ ...@@ -2638,7 +2638,6 @@
}; };
buildConfigurationList = 149C277108902AFE008A9EFC /* Build configuration list for PBXProject "JavaScriptCore" */; buildConfigurationList = 149C277108902AFE008A9EFC /* Build configuration list for PBXProject "JavaScriptCore" */;
compatibilityVersion = "Xcode 3.1"; compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
hasScannedForEncodings = 1; hasScannedForEncodings = 1;
knownRegions = ( knownRegions = (
English, English,
......
...@@ -122,7 +122,7 @@ JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSG ...@@ -122,7 +122,7 @@ JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSG
EvalExecutable* eval = EvalExecutable::create(globalCallFrame, makeSource(script), false); EvalExecutable* eval = EvalExecutable::create(globalCallFrame, makeSource(script), false);
if (!eval) { if (!eval) {
exception = globalData.exception.get(); exception = globalData.exception;
globalData.exception = JSValue(); globalData.exception = JSValue();
return exception; return exception;
} }
...@@ -132,7 +132,7 @@ JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSG ...@@ -132,7 +132,7 @@ JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSG
JSValue result = globalData.interpreter->execute(eval, globalCallFrame, globalObject, globalCallFrame->scopeChain()); JSValue result = globalData.interpreter->execute(eval, globalCallFrame, globalObject, globalCallFrame->scopeChain());
if (globalData.exception) { if (globalData.exception) {
exception = globalData.exception.get(); exception = globalData.exception;
globalData.exception = JSValue(); globalData.exception = JSValue();
} }
ASSERT(result); ASSERT(result);
......
...@@ -91,7 +91,7 @@ JSValue DebuggerCallFrame::evaluate(const UString& script, JSValue& exception) c ...@@ -91,7 +91,7 @@ JSValue DebuggerCallFrame::evaluate(const UString& script, JSValue& exception) c
JSGlobalData& globalData = m_callFrame->globalData(); JSGlobalData& globalData = m_callFrame->globalData();
EvalExecutable* eval = EvalExecutable::create(m_callFrame, makeSource(script), m_callFrame->codeBlock()->isStrictMode()); EvalExecutable* eval = EvalExecutable::create(m_callFrame, makeSource(script), m_callFrame->codeBlock()->isStrictMode());
if (globalData.exception) { if (globalData.exception) {
exception = globalData.exception.get(); exception = globalData.exception;
globalData.exception = JSValue(); globalData.exception = JSValue();
} }
...@@ -101,7 +101,7 @@ JSValue DebuggerCallFrame::evaluate(const UString& script, JSValue& exception) c ...@@ -101,7 +101,7 @@ JSValue DebuggerCallFrame::evaluate(const UString& script, JSValue& exception) c
JSValue result = globalData.interpreter->execute(eval, m_callFrame, thisObject(), m_callFrame->scopeChain()); JSValue result = globalData.interpreter->execute(eval, m_callFrame, thisObject(), m_callFrame->scopeChain());
if (globalData.exception) { if (globalData.exception) {
exception = globalData.exception.get(); exception = globalData.exception;
globalData.exception = JSValue(); globalData.exception = JSValue();
} }
ASSERT(result); ASSERT(result);
......
...@@ -65,7 +65,7 @@ namespace JSC { ...@@ -65,7 +65,7 @@ namespace JSC {
// But they're used in many places in legacy code, so they're not going away any time soon. // But they're used in many places in legacy code, so they're not going away any time soon.
void clearException() { globalData().exception = JSValue(); } void clearException() { globalData().exception = JSValue(); }
JSValue exception() const { return globalData().exception.get(); } JSValue exception() const { return globalData().exception; }
bool hadException() const { return globalData().exception; } bool hadException() const { return globalData().exception; }
const CommonIdentifiers& propertyNames() const { return *globalData().propertyNames; } const CommonIdentifiers& propertyNames() const { return *globalData().propertyNames; }
......
...@@ -943,17 +943,17 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD ...@@ -943,17 +943,17 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD
#define CHECK_FOR_EXCEPTION() \ #define CHECK_FOR_EXCEPTION() \
do { \ do { \
if (UNLIKELY(stackFrame.globalData->exception.get())) \ if (UNLIKELY(stackFrame.globalData->exception)) \
VM_THROW_EXCEPTION(); \ VM_THROW_EXCEPTION(); \
} while (0) } while (0)
#define CHECK_FOR_EXCEPTION_AT_END() \ #define CHECK_FOR_EXCEPTION_AT_END() \
do { \ do { \
if (UNLIKELY(stackFrame.globalData->exception.get())) \ if (UNLIKELY(stackFrame.globalData->exception)) \
VM_THROW_EXCEPTION_AT_END(); \ VM_THROW_EXCEPTION_AT_END(); \
} while (0) } while (0)
#define CHECK_FOR_EXCEPTION_VOID() \ #define CHECK_FOR_EXCEPTION_VOID() \
do { \ do { \
if (UNLIKELY(stackFrame.globalData->exception.get())) { \ if (UNLIKELY(stackFrame.globalData->exception)) { \
VM_THROW_EXCEPTION_AT_END(); \ VM_THROW_EXCEPTION_AT_END(); \
return; \ return; \
} \ } \
...@@ -3472,7 +3472,7 @@ DEFINE_STUB_FUNCTION(void*, vm_throw) ...@@ -3472,7 +3472,7 @@ DEFINE_STUB_FUNCTION(void*, vm_throw)
{ {
STUB_INIT_STACK_FRAME(stackFrame); STUB_INIT_STACK_FRAME(stackFrame);
JSGlobalData* globalData = stackFrame.globalData; JSGlobalData* globalData = stackFrame.globalData;
ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception.get(), globalData->exceptionLocation); ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception, globalData->exceptionLocation);
STUB_SET_RETURN_ADDRESS(handler.catchRoutine); STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
return handler.callFrame; return handler.callFrame;
} }
......
...@@ -54,7 +54,7 @@ Completion evaluate(ExecState* exec, ScopeChainNode* scopeChain, const SourceCod ...@@ -54,7 +54,7 @@ Completion evaluate(ExecState* exec, ScopeChainNode* scopeChain, const SourceCod
ProgramExecutable* program = ProgramExecutable::create(exec, source); ProgramExecutable* program = ProgramExecutable::create(exec, source);
if (!program) { if (!program) {
JSValue exception = exec->globalData().exception.get(); JSValue exception = exec->globalData().exception;
exec->globalData().exception = JSValue(); exec->globalData().exception = JSValue();
return Completion(Throw, exception); return Completion(Throw, exception);
} }
......
...@@ -151,11 +151,11 @@ bool Heap::unprotect(JSValue k) ...@@ -151,11 +151,11 @@ bool Heap::unprotect(JSValue k)
return m_protectedValues.remove(k.asCell()); return m_protectedValues.remove(k.asCell());
} }
void Heap::markProtectedObjects(MarkStack& markStack) void Heap::markProtectedObjects(HeapRootMarker& heapRootMarker)
{ {
ProtectCountSet::iterator end = m_protectedValues.end(); ProtectCountSet::iterator end = m_protectedValues.end();
for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
markStack.deprecatedAppend(&it->first); heapRootMarker.mark(&it->first);
} }
void Heap::pushTempSortVector(Vector<ValueStringPair>* tempVector) void Heap::pushTempSortVector(Vector<ValueStringPair>* tempVector)
...@@ -169,7 +169,7 @@ void Heap::popTempSortVector(Vector<ValueStringPair>* tempVector) ...@@ -169,7 +169,7 @@ void Heap::popTempSortVector(Vector<ValueStringPair>* tempVector)
m_tempSortingVectors.removeLast(); m_tempSortingVectors.removeLast();
} }
void Heap::markTempSortVectors(MarkStack& markStack) void Heap::markTempSortVectors(HeapRootMarker& heapRootMarker)
{ {
typedef Vector<Vector<ValueStringPair>* > VectorOfValueStringVectors; typedef Vector<Vector<ValueStringPair>* > VectorOfValueStringVectors;
...@@ -180,7 +180,7 @@ void Heap::markTempSortVectors(MarkStack& markStack) ...@@ -180,7 +180,7 @@ void Heap::markTempSortVectors(MarkStack& markStack)
Vector<ValueStringPair>::iterator vectorEnd = tempSortingVector->end(); Vector<ValueStringPair>::iterator vectorEnd = tempSortingVector->end();
for (Vector<ValueStringPair>::iterator vectorIt = tempSortingVector->begin(); vectorIt != vectorEnd; ++vectorIt) { for (Vector<ValueStringPair>::iterator vectorIt = tempSortingVector->begin(); vectorIt != vectorEnd; ++vectorIt) {
if (vectorIt->first) if (vectorIt->first)
markStack.deprecatedAppend(&vectorIt->first); heapRootMarker.mark(&vectorIt->first);
} }
} }
} }
...@@ -215,29 +215,28 @@ void Heap::markRoots() ...@@ -215,29 +215,28 @@ void Heap::markRoots()
m_markedSpace.clearMarks(); m_markedSpace.clearMarks();
MarkStack& markStack = m_markStack; MarkStack& markStack = m_markStack;
HeapRootMarker heapRootMarker(markStack);
markStack.append(conservativeRoots); markStack.append(conservativeRoots);
markStack.drain(); markStack.drain();
// Mark explicitly registered roots. markProtectedObjects(heapRootMarker);
markProtectedObjects(markStack);
markStack.drain(); markStack.drain();
// Mark temporary vector for Array sorting markTempSortVectors(heapRootMarker);
markTempSortVectors(markStack);
markStack.drain(); markStack.drain();
// Mark misc. other roots.
if (m_markListSet && m_markListSet->size()) if (m_markListSet && m_markListSet->size())
MarkedArgumentBuffer::markLists(markStack, *m_markListSet); MarkedArgumentBuffer::markLists(markStack, *m_markListSet);
if (m_globalData->exception) if (m_globalData->exception)
markStack.append(&m_globalData->exception); heapRootMarker.mark(&m_globalData->exception);
markStack.drain(); markStack.drain();
m_handleHeap.markStrongHandles(markStack); m_handleHeap.markStrongHandles(markStack);
// Mark the small strings cache last, since it will clear itself if nothing // Mark the small strings cache last, since it will clear itself if nothing
// else has marked it. // else has marked it.
m_globalData->smallStrings.markChildren(markStack); m_globalData->smallStrings.markChildren(heapRootMarker);
markStack.drain(); markStack.drain();
markStack.compact(); markStack.compact();
......
...@@ -34,6 +34,7 @@ namespace JSC { ...@@ -34,6 +34,7 @@ namespace JSC {
class GCActivityCallback; class GCActivityCallback;
class GlobalCodeBlock; class GlobalCodeBlock;
class HeapRootMarker;
class JSCell; class JSCell;
class JSGlobalData; class JSGlobalData;
class JSValue; class JSValue;
...@@ -113,8 +114,8 @@ namespace JSC { ...@@ -113,8 +114,8 @@ namespace JSC {
void reportExtraMemoryCostSlowCase(size_t); void reportExtraMemoryCostSlowCase(size_t);
void markRoots(); void markRoots();
void markProtectedObjects(MarkStack&); void markProtectedObjects(HeapRootMarker&);
void markTempSortVectors(MarkStack&); void markTempSortVectors(HeapRootMarker&);
enum SweepToggle { DoNotSweep, DoSweep }; enum SweepToggle { DoNotSweep, DoSweep };
void reset(SweepToggle); void reset(SweepToggle);
......
...@@ -376,6 +376,18 @@ namespace JSC { ...@@ -376,6 +376,18 @@ namespace JSC {
internalAppend(*value); internalAppend(*value);
} }
ALWAYS_INLINE void MarkStack::append(JSValue* value)
{
ASSERT(value);
internalAppend(*value);
}
ALWAYS_INLINE void MarkStack::append(JSCell** value)
{
ASSERT(value);
internalAppend(*value);
}
ALWAYS_INLINE void MarkStack::deprecatedAppend(Register* value) ALWAYS_INLINE void MarkStack::deprecatedAppend(Register* value)
{ {
ASSERT(value); ASSERT(value);
......
...@@ -212,7 +212,7 @@ namespace JSC { ...@@ -212,7 +212,7 @@ namespace JSC {
Terminator terminator; Terminator terminator;
Heap heap; Heap heap;
HeapRoot<Unknown> exception; JSValue exception;
#if ENABLE(JIT) #if ENABLE(JIT)
ReturnAddressPtr exceptionLocation; ReturnAddressPtr exceptionLocation;
#endif #endif
......
...@@ -96,6 +96,10 @@ namespace JSC { ...@@ -96,6 +96,10 @@ namespace JSC {
} }
private: private:
friend class HeapRootMarker; // Allowed to mark a JSValue* or JSCell** directly.
void append(JSValue*);
void append(JSCell**);
void internalAppend(JSCell*); void internalAppend(JSCell*);
void internalAppend(JSValue); void internalAppend(JSValue);
void markChildren(JSCell*); void markChildren(JSCell*);
...@@ -211,7 +215,45 @@ namespace JSC { ...@@ -211,7 +215,45 @@ namespace JSC {
bool m_isDraining; bool m_isDraining;
#endif #endif
}; };
} // Privileged class for marking JSValues directly. It is only safe to use
// this class to mark direct heap roots that are marked during every GC pass.
// All other references should be wrapped in WriteBarriers and marked through
// the MarkStack.
class HeapRootMarker {
private:
friend class Heap;
HeapRootMarker(MarkStack&);
public:
void mark(JSValue*);
void mark(JSString**);
void mark(JSCell**);
private:
MarkStack& m_markStack;
};
inline HeapRootMarker::HeapRootMarker(MarkStack& markStack)
: m_markStack(markStack)
{
}
inline void HeapRootMarker::mark(JSValue* slot)
{
m_markStack.append(slot);
}
inline void HeapRootMarker::mark(JSString** slot)
{
m_markStack.append(reinterpret_cast<JSCell**>(slot));
}
inline void HeapRootMarker::mark(JSCell** slot)
{
m_markStack.append(slot);
}
} // namespace JSC
#endif #endif
...@@ -74,7 +74,7 @@ SmallStrings::~SmallStrings() ...@@ -74,7 +74,7 @@ SmallStrings::~SmallStrings()
{ {
} }
void SmallStrings::markChildren(MarkStack& markStack) void SmallStrings::markChildren(HeapRootMarker& heapRootMarker)
{ {
/* /*
Our hypothesis is that small strings are very common. So, we cache them Our hypothesis is that small strings are very common. So, we cache them
...@@ -86,9 +86,9 @@ void SmallStrings::markChildren(MarkStack& markStack) ...@@ -86,9 +86,9 @@ void SmallStrings::markChildren(MarkStack& markStack)
so, it's probably reasonable to mark the rest. If not, we clear the cache. so, it's probably reasonable to mark the rest. If not, we clear the cache.
*/ */
bool isAnyStringMarked = isMarked(m_emptyString.get()); bool isAnyStringMarked = isMarked(m_emptyString);
for (unsigned i = 0; i < singleCharacterStringCount && !isAnyStringMarked; ++i) for (unsigned i = 0; i < singleCharacterStringCount && !isAnyStringMarked; ++i)
isAnyStringMarked = isMarked(m_singleCharacterStrings[i].get()); isAnyStringMarked = isMarked(m_singleCharacterStrings[i]);
if (!isAnyStringMarked) { if (!isAnyStringMarked) {
clear(); clear();
...@@ -96,10 +96,10 @@ void SmallStrings::markChildren(MarkStack& markStack) ...@@ -96,10 +96,10 @@ void SmallStrings::markChildren(MarkStack& markStack)
} }
if (m_emptyString) if (m_emptyString)
markStack.append(&m_emptyString); heapRootMarker.mark(&m_emptyString);
for (unsigned i = 0; i < singleCharacterStringCount; ++i) { for (unsigned i = 0; i < singleCharacterStringCount; ++i) {
if (m_singleCharacterStrings[i]) if (m_singleCharacterStrings[i])
markStack.append(&m_singleCharacterStrings[i]); heapRootMarker.mark(&m_singleCharacterStrings[i]);
} }
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
namespace JSC { namespace JSC {
class HeapRootMarker;
class JSGlobalData; class JSGlobalData;
class JSString; class JSString;
class MarkStack; class MarkStack;
...@@ -50,24 +51,24 @@ namespace JSC { ...@@ -50,24 +51,24 @@ namespace JSC {
{ {
if (!m_emptyString) if (!m_emptyString)
createEmptyString(globalData); createEmptyString(globalData);
return m_emptyString.get(); return m_emptyString;
} }
JSString* singleCharacterString(JSGlobalData* globalData, unsigned char character) JSString* singleCharacterString(JSGlobalData* globalData, unsigned char character)
{ {
if (!m_singleCharacterStrings[character]) if (!m_singleCharacterStrings[character])
createSingleCharacterString(globalData, character); createSingleCharacterString(globalData, character);
return m_singleCharacterStrings[character].get(); return m_singleCharacterStrings[character];
} }
StringImpl* singleCharacterStringRep(unsigned char character); StringImpl* singleCharacterStringRep(unsigned char character);
void markChildren(MarkStack&); void markChildren(HeapRootMarker&);
void clear(); void clear();
unsigned count() const; unsigned count() const;
JSCell** singleCharacterStrings() { return m_singleCharacterStrings[0].slot(); } JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; }
private: private:
static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1; static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
...@@ -75,8 +76,8 @@ namespace JSC { ...@@ -75,8 +76,8 @@ namespace JSC {
void createEmptyString(JSGlobalData*); void createEmptyString(JSGlobalData*);
void createSingleCharacterString(JSGlobalData*, unsigned char); void createSingleCharacterString(JSGlobalData*, unsigned char);
HeapRoot<JSString> m_emptyString; JSString* m_emptyString;
HeapRoot<JSString> m_singleCharacterStrings[singleCharacterStringCount]; JSString* m_singleCharacterStrings[singleCharacterStringCount];
OwnPtr<SmallStringsStorage> m_storage; OwnPtr<SmallStringsStorage> m_storage;
}; };
......
...@@ -171,48 +171,6 @@ template <typename U, typename V> inline bool operator==(const WriteBarrierBase< ...@@ -171,48 +171,6 @@ template <typename U, typename V> inline bool operator==(const WriteBarrierBase<
return lhs.get() == rhs.get(); return lhs.get() == rhs.get();
} }
// For use in data members that are owned by the Heap.
template <typename T> class HeapRoot : public WriteBarrier<T> {
private:
friend class Heap;
friend class JSGlobalData; // FIXME: Move Heap roots from JSGlobalData to Heap.
friend class SmallStrings; // FIXME: Convert SmallStrings to use weak handles.
HeapRoot() { }
HeapRoot(T* value)
{
this->setWithoutWriteBarrier(value);
}
public:
HeapRoot& operator=(T* value)
{
this->setWithoutWriteBarrier(value);
return *this;
}
};
// For use in data members that are owned by the Heap.
template <> class HeapRoot<Unknown> : public WriteBarrier<Unknown> {
private:
friend class Heap;
friend class JSGlobalData; // FIXME: Move Heap roots from JSGlobalData to Heap.
friend class SmallStrings; // FIXME: Convert SmallStrings to use weak handles.
HeapRoot() { }
HeapRoot(JSValue value)
{
this->setWithoutWriteBarrier(value);
}
public:
HeapRoot& operator=(JSValue value)
{
this->setWithoutWriteBarrier(value);
return *this;
}
};
} // namespace JSC } // namespace JSC
#endif // WriteBarrier_h #endif // WriteBarrier_h
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment