Commit 4eb5911e authored by ggaren@apple.com's avatar ggaren@apple.com

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

        Reviewed by Oliver Hunt.

        A little bit of MarkStack cleanup
        https://bugs.webkit.org/show_bug.cgi?id=56443
        
        Moved MarkStack functions into MarkStack.h/.cpp.
        
        SunSpider reports no change.

        * runtime/JSArray.h:
        * runtime/JSCell.h: Moved from here...
        * runtime/MarkStack.cpp:
        (JSC::MarkStack::markChildren):
        (JSC::MarkStack::drain): ...to here. Also, no need to inline drain. It's
        a huge function, and not called many times.

        * runtime/MarkStack.h:
        (JSC::MarkStack::~MarkStack): Moved near constructor, per style guide.
        (JSC::MarkStack::append):
        (JSC::MarkStack::deprecatedAppend):
        (JSC::MarkStack::internalAppend): Moved to here.


git-svn-id: svn://svn.chromium.org/blink/trunk@81261 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent f13f74ea
2011-03-16 Geoffrey Garen <ggaren@apple.com>
Reviewed by Oliver Hunt.
A little bit of MarkStack cleanup
https://bugs.webkit.org/show_bug.cgi?id=56443
Moved MarkStack functions into MarkStack.h/.cpp.
SunSpider reports no change.
* runtime/JSArray.h:
* runtime/JSCell.h: Moved from here...
* runtime/MarkStack.cpp:
(JSC::MarkStack::markChildren):
(JSC::MarkStack::drain): ...to here. Also, no need to inline drain. It's
a huge function, and not called many times.
* runtime/MarkStack.h:
(JSC::MarkStack::~MarkStack): Moved near constructor, per style guide.
(JSC::MarkStack::append):
(JSC::MarkStack::deprecatedAppend):
(JSC::MarkStack::internalAppend): Moved to here.
2011-03-15 Geoffrey Garen <ggaren@apple.com> 2011-03-15 Geoffrey Garen <ggaren@apple.com>
Reviewed by Oliver Hunt. Reviewed by Oliver Hunt.
......
...@@ -202,77 +202,6 @@ namespace JSC { ...@@ -202,77 +202,6 @@ namespace JSC {
} }
} }
inline void MarkStack::markChildren(JSCell* cell)
{
ASSERT(Heap::isMarked(cell));
if (!cell->structure()->typeInfo().overridesMarkChildren()) {
#ifdef NDEBUG
asObject(cell)->markChildrenDirect(*this);
#else
ASSERT(!m_isCheckingForDefaultMarkViolation);
m_isCheckingForDefaultMarkViolation = true;
cell->markChildren(*this);
ASSERT(m_isCheckingForDefaultMarkViolation);
m_isCheckingForDefaultMarkViolation = false;
#endif
return;
}
if (cell->vptr() == m_jsArrayVPtr) {
asArray(cell)->markChildrenDirect(*this);
return;
}
cell->markChildren(*this);
}
inline void MarkStack::drain()
{
#if !ASSERT_DISABLED
ASSERT(!m_isDraining);
m_isDraining = true;
#endif
while (!m_markSets.isEmpty() || !m_values.isEmpty()) {
while (!m_markSets.isEmpty() && m_values.size() < 50) {
ASSERT(!m_markSets.isEmpty());
MarkSet& current = m_markSets.last();
ASSERT(current.m_values);
JSValue* end = current.m_end;
ASSERT(current.m_values);
ASSERT(current.m_values != end);
findNextUnmarkedNullValue:
ASSERT(current.m_values != end);
JSValue value = *current.m_values;
current.m_values++;
JSCell* cell;
if (!value || !value.isCell() || Heap::testAndSetMarked(cell = value.asCell())) {
if (current.m_values == end) {
m_markSets.removeLast();
continue;
}
goto findNextUnmarkedNullValue;
}
if (cell->structure()->typeInfo().type() < CompoundType) {
if (current.m_values == end) {
m_markSets.removeLast();
continue;
}
goto findNextUnmarkedNullValue;
}
if (current.m_values == end)
m_markSets.removeLast();
markChildren(cell);
}
while (!m_values.isEmpty())
markChildren(m_values.removeLast());
}
#if !ASSERT_DISABLED
m_isDraining = false;
#endif
}
// Rule from ECMA 15.2 about what an array index is. // Rule from ECMA 15.2 about what an array index is.
// Must exactly match string form of an unsigned integer, and be less than 2^32 - 1. // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1.
inline unsigned Identifier::toArrayIndex(bool& ok) const inline unsigned Identifier::toArrayIndex(bool& ok) const
......
...@@ -344,16 +344,6 @@ namespace JSC { ...@@ -344,16 +344,6 @@ namespace JSC {
return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec); return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec);
} }
template <typename T> void MarkStack::append(DeprecatedPtr<T>* slot)
{
internalAppend(slot->get());
}
template <typename T> void MarkStack::append(WriteBarrierBase<T>* slot)
{
internalAppend(slot->get());
}
ALWAYS_INLINE void MarkStack::internalAppend(JSCell* cell) ALWAYS_INLINE void MarkStack::internalAppend(JSCell* cell)
{ {
ASSERT(!m_isCheckingForDefaultMarkViolation); ASSERT(!m_isCheckingForDefaultMarkViolation);
...@@ -364,43 +354,6 @@ namespace JSC { ...@@ -364,43 +354,6 @@ namespace JSC {
m_values.append(cell); m_values.append(cell);
} }
ALWAYS_INLINE void MarkStack::deprecatedAppend(JSCell** value)
{
ASSERT(value);
internalAppend(*value);
}
ALWAYS_INLINE void MarkStack::deprecatedAppend(JSValue* value)
{
ASSERT(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)
{
ASSERT(value);
internalAppend(value->jsValue());
}
ALWAYS_INLINE void MarkStack::internalAppend(JSValue value)
{
ASSERT(value);
if (value.isCell())
internalAppend(value.asCell());
}
inline Heap* Heap::heap(JSValue v) inline Heap* Heap::heap(JSValue v)
{ {
if (!v.isCell()) if (!v.isCell())
......
/* /*
* Copyright (C) 2009 Apple Inc. All rights reserved. * Copyright (C) 2009, 2011 Apple Inc. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -26,6 +26,11 @@ ...@@ -26,6 +26,11 @@
#include "config.h" #include "config.h"
#include "MarkStack.h" #include "MarkStack.h"
#include "Heap.h"
#include "JSArray.h"
#include "JSCell.h"
#include "Structure.h"
namespace JSC { namespace JSC {
size_t MarkStack::s_pageSize = 0; size_t MarkStack::s_pageSize = 0;
...@@ -37,4 +42,75 @@ void MarkStack::compact() ...@@ -37,4 +42,75 @@ void MarkStack::compact()
m_markSets.shrinkAllocation(s_pageSize); m_markSets.shrinkAllocation(s_pageSize);
} }
inline void MarkStack::markChildren(JSCell* cell)
{
ASSERT(Heap::isMarked(cell));
if (!cell->structure()->typeInfo().overridesMarkChildren()) {
#ifdef NDEBUG
asObject(cell)->markChildrenDirect(*this);
#else
ASSERT(!m_isCheckingForDefaultMarkViolation);
m_isCheckingForDefaultMarkViolation = true;
cell->markChildren(*this);
ASSERT(m_isCheckingForDefaultMarkViolation);
m_isCheckingForDefaultMarkViolation = false;
#endif
return;
}
if (cell->vptr() == m_jsArrayVPtr) {
asArray(cell)->markChildrenDirect(*this);
return;
}
cell->markChildren(*this);
}
void MarkStack::drain()
{
#if !ASSERT_DISABLED
ASSERT(!m_isDraining);
m_isDraining = true;
#endif
while (!m_markSets.isEmpty() || !m_values.isEmpty()) {
while (!m_markSets.isEmpty() && m_values.size() < 50) {
ASSERT(!m_markSets.isEmpty());
MarkSet& current = m_markSets.last();
ASSERT(current.m_values);
JSValue* end = current.m_end;
ASSERT(current.m_values);
ASSERT(current.m_values != end);
findNextUnmarkedNullValue:
ASSERT(current.m_values != end);
JSValue value = *current.m_values;
current.m_values++;
JSCell* cell;
if (!value || !value.isCell() || Heap::testAndSetMarked(cell = value.asCell())) {
if (current.m_values == end) {
m_markSets.removeLast();
continue;
}
goto findNextUnmarkedNullValue;
}
if (cell->structure()->typeInfo().type() < CompoundType) {
if (current.m_values == end) {
m_markSets.removeLast();
continue;
}
goto findNextUnmarkedNullValue;
}
if (current.m_values == end)
m_markSets.removeLast();
markChildren(cell);
}
while (!m_values.isEmpty())
markChildren(m_values.removeLast());
}
#if !ASSERT_DISABLED
m_isDraining = false;
#endif
} }
} // namespace JSC
/* /*
* Copyright (C) 2009 Apple Inc. All rights reserved. * Copyright (C) 2009, 2011 Apple Inc. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "ConservativeSet.h" #include "ConservativeSet.h"
#include "JSValue.h" #include "JSValue.h"
#include "Register.h"
#include "WriteBarrier.h" #include "WriteBarrier.h"
#include <wtf/Vector.h> #include <wtf/Vector.h>
#include <wtf/Noncopyable.h> #include <wtf/Noncopyable.h>
...@@ -51,7 +52,13 @@ namespace JSC { ...@@ -51,7 +52,13 @@ namespace JSC {
#endif #endif
{ {
} }
~MarkStack()
{
ASSERT(m_markSets.isEmpty());
ASSERT(m_values.isEmpty());
}
void deprecatedAppend(JSValue*); void deprecatedAppend(JSValue*);
void deprecatedAppend(JSCell**); void deprecatedAppend(JSCell**);
void deprecatedAppend(Register*); void deprecatedAppend(Register*);
...@@ -80,15 +87,9 @@ namespace JSC { ...@@ -80,15 +87,9 @@ namespace JSC {
internalAppend(roots[i]); internalAppend(roots[i]);
} }
inline void drain(); void drain();
void compact(); void compact();
~MarkStack()
{
ASSERT(m_markSets.isEmpty());
ASSERT(m_values.isEmpty());
}
private: private:
friend class HeapRootMarker; // Allowed to mark a JSValue* or JSCell** directly. friend class HeapRootMarker; // Allowed to mark a JSValue* or JSCell** directly.
void append(JSValue*); void append(JSValue*);
...@@ -218,6 +219,53 @@ namespace JSC { ...@@ -218,6 +219,53 @@ namespace JSC {
m_markSets.append(MarkSet(slot, slot + count, NoNullValues)); m_markSets.append(MarkSet(slot, slot + count, NoNullValues));
} }
template <typename T> inline void MarkStack::append(DeprecatedPtr<T>* slot)
{
internalAppend(slot->get());
}
template <typename T> inline void MarkStack::append(WriteBarrierBase<T>* slot)
{
internalAppend(slot->get());
}
ALWAYS_INLINE void MarkStack::deprecatedAppend(JSCell** value)
{
ASSERT(value);
internalAppend(*value);
}
ALWAYS_INLINE void MarkStack::deprecatedAppend(JSValue* value)
{
ASSERT(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)
{
ASSERT(value);
internalAppend(value->jsValue());
}
ALWAYS_INLINE void MarkStack::internalAppend(JSValue value)
{
ASSERT(value);
if (value.isCell())
internalAppend(value.asCell());
}
// Privileged class for marking JSValues directly. It is only safe to use // 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. // 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 // All other references should be wrapped in WriteBarriers and marked through
......
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