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>
Reviewed by Geoffrey Garen.
......
......@@ -2638,7 +2638,6 @@
};
buildConfigurationList = 149C277108902AFE008A9EFC /* Build configuration list for PBXProject "JavaScriptCore" */;
compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
......
......@@ -122,7 +122,7 @@ JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSG
EvalExecutable* eval = EvalExecutable::create(globalCallFrame, makeSource(script), false);
if (!eval) {
exception = globalData.exception.get();
exception = globalData.exception;
globalData.exception = JSValue();
return exception;
}
......@@ -132,7 +132,7 @@ JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSG
JSValue result = globalData.interpreter->execute(eval, globalCallFrame, globalObject, globalCallFrame->scopeChain());
if (globalData.exception) {
exception = globalData.exception.get();
exception = globalData.exception;
globalData.exception = JSValue();
}
ASSERT(result);
......
......@@ -91,7 +91,7 @@ JSValue DebuggerCallFrame::evaluate(const UString& script, JSValue& exception) c
JSGlobalData& globalData = m_callFrame->globalData();
EvalExecutable* eval = EvalExecutable::create(m_callFrame, makeSource(script), m_callFrame->codeBlock()->isStrictMode());
if (globalData.exception) {
exception = globalData.exception.get();
exception = globalData.exception;
globalData.exception = JSValue();
}
......@@ -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());
if (globalData.exception) {
exception = globalData.exception.get();
exception = globalData.exception;
globalData.exception = JSValue();
}
ASSERT(result);
......
......@@ -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.
void clearException() { globalData().exception = JSValue(); }
JSValue exception() const { return globalData().exception.get(); }
JSValue exception() const { return globalData().exception; }
bool hadException() const { return globalData().exception; }
const CommonIdentifiers& propertyNames() const { return *globalData().propertyNames; }
......
......@@ -943,17 +943,17 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD
#define CHECK_FOR_EXCEPTION() \
do { \
if (UNLIKELY(stackFrame.globalData->exception.get())) \
if (UNLIKELY(stackFrame.globalData->exception)) \
VM_THROW_EXCEPTION(); \
} while (0)
#define CHECK_FOR_EXCEPTION_AT_END() \
do { \
if (UNLIKELY(stackFrame.globalData->exception.get())) \
if (UNLIKELY(stackFrame.globalData->exception)) \
VM_THROW_EXCEPTION_AT_END(); \
} while (0)
#define CHECK_FOR_EXCEPTION_VOID() \
do { \
if (UNLIKELY(stackFrame.globalData->exception.get())) { \
if (UNLIKELY(stackFrame.globalData->exception)) { \
VM_THROW_EXCEPTION_AT_END(); \
return; \
} \
......@@ -3472,7 +3472,7 @@ DEFINE_STUB_FUNCTION(void*, vm_throw)
{
STUB_INIT_STACK_FRAME(stackFrame);
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);
return handler.callFrame;
}
......
......@@ -54,7 +54,7 @@ Completion evaluate(ExecState* exec, ScopeChainNode* scopeChain, const SourceCod
ProgramExecutable* program = ProgramExecutable::create(exec, source);
if (!program) {
JSValue exception = exec->globalData().exception.get();
JSValue exception = exec->globalData().exception;
exec->globalData().exception = JSValue();
return Completion(Throw, exception);
}
......
......@@ -151,11 +151,11 @@ bool Heap::unprotect(JSValue k)
return m_protectedValues.remove(k.asCell());
}
void Heap::markProtectedObjects(MarkStack& markStack)
void Heap::markProtectedObjects(HeapRootMarker& heapRootMarker)
{
ProtectCountSet::iterator end = m_protectedValues.end();
for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
markStack.deprecatedAppend(&it->first);
heapRootMarker.mark(&it->first);
}
void Heap::pushTempSortVector(Vector<ValueStringPair>* tempVector)
......@@ -169,7 +169,7 @@ void Heap::popTempSortVector(Vector<ValueStringPair>* tempVector)
m_tempSortingVectors.removeLast();
}
void Heap::markTempSortVectors(MarkStack& markStack)
void Heap::markTempSortVectors(HeapRootMarker& heapRootMarker)
{
typedef Vector<Vector<ValueStringPair>* > VectorOfValueStringVectors;
......@@ -180,7 +180,7 @@ void Heap::markTempSortVectors(MarkStack& markStack)
Vector<ValueStringPair>::iterator vectorEnd = tempSortingVector->end();
for (Vector<ValueStringPair>::iterator vectorIt = tempSortingVector->begin(); vectorIt != vectorEnd; ++vectorIt) {
if (vectorIt->first)
markStack.deprecatedAppend(&vectorIt->first);
heapRootMarker.mark(&vectorIt->first);
}
}
}
......@@ -215,29 +215,28 @@ void Heap::markRoots()
m_markedSpace.clearMarks();
MarkStack& markStack = m_markStack;
HeapRootMarker heapRootMarker(markStack);
markStack.append(conservativeRoots);
markStack.drain();
// Mark explicitly registered roots.
markProtectedObjects(markStack);
markProtectedObjects(heapRootMarker);
markStack.drain();
// Mark temporary vector for Array sorting
markTempSortVectors(markStack);
markTempSortVectors(heapRootMarker);
markStack.drain();
// Mark misc. other roots.
if (m_markListSet && m_markListSet->size())
MarkedArgumentBuffer::markLists(markStack, *m_markListSet);
if (m_globalData->exception)
markStack.append(&m_globalData->exception);
heapRootMarker.mark(&m_globalData->exception);
markStack.drain();
m_handleHeap.markStrongHandles(markStack);
// Mark the small strings cache last, since it will clear itself if nothing
// else has marked it.
m_globalData->smallStrings.markChildren(markStack);
m_globalData->smallStrings.markChildren(heapRootMarker);
markStack.drain();
markStack.compact();
......
......@@ -34,6 +34,7 @@ namespace JSC {
class GCActivityCallback;
class GlobalCodeBlock;
class HeapRootMarker;
class JSCell;
class JSGlobalData;
class JSValue;
......@@ -113,8 +114,8 @@ namespace JSC {
void reportExtraMemoryCostSlowCase(size_t);
void markRoots();
void markProtectedObjects(MarkStack&);
void markTempSortVectors(MarkStack&);
void markProtectedObjects(HeapRootMarker&);
void markTempSortVectors(HeapRootMarker&);
enum SweepToggle { DoNotSweep, DoSweep };
void reset(SweepToggle);
......
......@@ -376,6 +376,18 @@ namespace JSC {
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)
{
ASSERT(value);
......
......@@ -212,7 +212,7 @@ namespace JSC {
Terminator terminator;
Heap heap;
HeapRoot<Unknown> exception;
JSValue exception;
#if ENABLE(JIT)
ReturnAddressPtr exceptionLocation;
#endif
......
......@@ -96,6 +96,10 @@ namespace JSC {
}
private:
friend class HeapRootMarker; // Allowed to mark a JSValue* or JSCell** directly.
void append(JSValue*);
void append(JSCell**);
void internalAppend(JSCell*);
void internalAppend(JSValue);
void markChildren(JSCell*);
......@@ -211,7 +215,45 @@ namespace JSC {
bool m_isDraining;
#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
......@@ -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
......@@ -86,9 +86,9 @@ void SmallStrings::markChildren(MarkStack& markStack)
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)
isAnyStringMarked = isMarked(m_singleCharacterStrings[i].get());
isAnyStringMarked = isMarked(m_singleCharacterStrings[i]);
if (!isAnyStringMarked) {
clear();
......@@ -96,10 +96,10 @@ void SmallStrings::markChildren(MarkStack& markStack)
}
if (m_emptyString)
markStack.append(&m_emptyString);
heapRootMarker.mark(&m_emptyString);
for (unsigned i = 0; i < singleCharacterStringCount; ++i) {
if (m_singleCharacterStrings[i])
markStack.append(&m_singleCharacterStrings[i]);
heapRootMarker.mark(&m_singleCharacterStrings[i]);
}
}
......
......@@ -33,6 +33,7 @@
namespace JSC {
class HeapRootMarker;
class JSGlobalData;
class JSString;
class MarkStack;
......@@ -50,24 +51,24 @@ namespace JSC {
{
if (!m_emptyString)
createEmptyString(globalData);
return m_emptyString.get();
return m_emptyString;
}
JSString* singleCharacterString(JSGlobalData* globalData, unsigned char character)
{
if (!m_singleCharacterStrings[character])
createSingleCharacterString(globalData, character);
return m_singleCharacterStrings[character].get();
return m_singleCharacterStrings[character];
}
StringImpl* singleCharacterStringRep(unsigned char character);
void markChildren(MarkStack&);
void markChildren(HeapRootMarker&);
void clear();
unsigned count() const;
JSCell** singleCharacterStrings() { return m_singleCharacterStrings[0].slot(); }
JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; }
private:
static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
......@@ -75,8 +76,8 @@ namespace JSC {
void createEmptyString(JSGlobalData*);
void createSingleCharacterString(JSGlobalData*, unsigned char);
HeapRoot<JSString> m_emptyString;
HeapRoot<JSString> m_singleCharacterStrings[singleCharacterStringCount];
JSString* m_emptyString;
JSString* m_singleCharacterStrings[singleCharacterStringCount];
OwnPtr<SmallStringsStorage> m_storage;
};
......
......@@ -171,48 +171,6 @@ template <typename U, typename V> inline bool operator==(const WriteBarrierBase<
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
#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