Changeset 97642 in webkit for trunk/Source/JavaScriptCore/heap/MarkStack.cpp
- Timestamp:
- Oct 17, 2011, 1:43:43 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/heap/MarkStack.cpp
r97203 r97642 34 34 #include "ScopeChain.h" 35 35 #include "Structure.h" 36 #include "WriteBarrier.h" 36 37 37 38 namespace JSC { 39 40 MarkStackArray::MarkStackArray() 41 : m_top(0) 42 , m_allocated(pageSize()) 43 { 44 m_data = static_cast<const JSCell**>(MarkStack::allocateStack(m_allocated)); 45 m_capacity = m_allocated / sizeof(JSCell*); 46 } 47 48 MarkStackArray::~MarkStackArray() 49 { 50 MarkStack::releaseStack(m_data, m_allocated); 51 } 52 53 void MarkStackArray::expand() 54 { 55 size_t oldAllocation = m_allocated; 56 m_allocated *= 2; 57 m_capacity = m_allocated / sizeof(JSCell*); 58 void* newData = MarkStack::allocateStack(m_allocated); 59 memcpy(newData, m_data, oldAllocation); 60 MarkStack::releaseStack(m_data, oldAllocation); 61 m_data = static_cast<const JSCell**>(newData); 62 } 63 64 void MarkStackArray::shrinkAllocation(size_t size) 65 { 66 ASSERT(size <= m_allocated); 67 ASSERT(isPageAligned(size)); 68 if (size == m_allocated) 69 return; 70 #if OS(WINDOWS) 71 // We cannot release a part of a region with VirtualFree. To get around this, 72 // we'll release the entire region and reallocate the size that we want. 73 MarkStack::releaseStack(m_data, m_allocated); 74 m_data = static_cast<JSCell*>(MarkStack::allocateStack(size)); 75 #else 76 MarkStack::releaseStack(reinterpret_cast<char*>(m_data) + size, m_allocated - size); 77 #endif 78 m_allocated = size; 79 m_capacity = m_allocated / sizeof(JSCell*); 80 } 38 81 39 82 void MarkStack::reset() 40 83 { 41 84 m_visitCount = 0; 42 m_values.shrinkAllocation(pageSize()); 43 m_markSets.shrinkAllocation(pageSize()); 85 m_stack.shrinkAllocation(pageSize()); 44 86 m_opaqueRoots.clear(); 45 87 } … … 53 95 } 54 96 55 void SlotVisitor::visitChildren(JSCell* cell)97 ALWAYS_INLINE static void visitChildren(SlotVisitor& visitor, const JSCell* cell, void* jsFinalObjectVPtr, void* jsArrayVPtr, void* jsStringVPtr) 56 98 { 57 99 #if ENABLE(SIMPLE_HEAP_PROFILING) … … 60 102 61 103 ASSERT(Heap::isMarked(cell)); 62 if (cell->structure()->typeInfo().type() < CompoundType) { 63 JSCell::visitChildren(cell, *this); 104 105 if (cell->vptr() == jsStringVPtr) 106 return; 107 108 if (cell->vptr() == jsFinalObjectVPtr) { 109 JSObject::visitChildren(const_cast<JSCell*>(cell), visitor); 64 110 return; 65 111 } 66 112 67 if (!cell->structure()->typeInfo().overridesVisitChildren()) { 68 ASSERT(cell->isObject()); 69 #ifdef NDEBUG 70 asObject(cell)->visitChildrenDirect(*this); 71 #else 72 ASSERT(!m_isCheckingForDefaultMarkViolation); 73 m_isCheckingForDefaultMarkViolation = true; 74 cell->methodTable()->visitChildren(cell, *this); 75 ASSERT(m_isCheckingForDefaultMarkViolation); 76 m_isCheckingForDefaultMarkViolation = false; 77 #endif 113 if (cell->vptr() == jsArrayVPtr) { 114 JSArray::visitChildren(const_cast<JSCell*>(cell), visitor); 78 115 return; 79 116 } 80 if (cell->vptr() == m_jsArrayVPtr) { 81 asArray(cell)->visitChildrenDirect(*this); 82 return; 83 } 84 cell->methodTable()->visitChildren(cell, *this); 117 118 cell->methodTable()->visitChildren(const_cast<JSCell*>(cell), visitor); 85 119 } 86 120 87 121 void SlotVisitor::drain() 88 122 { 89 #if !ASSERT_DISABLED 90 ASSERT(!m_isDraining); 91 m_isDraining = true; 92 #endif 93 while (!m_markSets.isEmpty() || !m_values.isEmpty()) { 94 while (!m_markSets.isEmpty() && m_values.size() < 50) { 95 ASSERT(!m_markSets.isEmpty()); 96 MarkSet& current = m_markSets.last(); 97 ASSERT(current.m_values); 98 JSValue* end = current.m_end; 99 ASSERT(current.m_values); 100 ASSERT(current.m_values != end); 101 findNextUnmarkedNullValue: 102 ASSERT(current.m_values != end); 103 JSValue value = *current.m_values; 104 current.m_values++; 123 void* jsFinalObjectVPtr = m_jsFinalObjectVPtr; 124 void* jsArrayVPtr = m_jsArrayVPtr; 125 void* jsStringVPtr = m_jsStringVPtr; 105 126 106 JSCell* cell; 107 if (!value || !value.isCell() || Heap::testAndSetMarked(cell = value.asCell())) { 108 if (current.m_values == end) { 109 m_markSets.removeLast(); 110 continue; 111 } 112 goto findNextUnmarkedNullValue; 113 } 114 115 if (cell->structure()->typeInfo().type() < CompoundType) { 116 #if ENABLE(SIMPLE_HEAP_PROFILING) 117 m_visitedTypeCounts.count(cell); 118 #endif 119 JSCell::visitChildren(cell, *this); 120 if (current.m_values == end) { 121 m_markSets.removeLast(); 122 continue; 123 } 124 goto findNextUnmarkedNullValue; 125 } 126 127 if (current.m_values == end) 128 m_markSets.removeLast(); 129 130 visitChildren(cell); 131 } 132 while (!m_values.isEmpty()) 133 visitChildren(m_values.removeLast()); 134 } 135 #if !ASSERT_DISABLED 136 m_isDraining = false; 137 #endif 127 while (!m_stack.isEmpty()) 128 visitChildren(*this, m_stack.removeLast(), jsFinalObjectVPtr, jsArrayVPtr, jsStringVPtr); 138 129 } 139 130 … … 150 141 151 142 #if ENABLE(GC_VALIDATION) 152 void MarkStack::validate Set(JSValue* values, size_t count)143 void MarkStack::validate(JSCell* cell) 153 144 { 154 for (size_t i = 0; i < count; i++) {155 if (values[i])156 validateValue(values[i]);157 }158 }159 160 void MarkStack::validateValue(JSValue value)161 {162 if (!value)163 CRASH();164 if (!value.isCell())165 return;166 JSCell* cell = value.asCell();167 145 if (!cell) 168 146 CRASH(); … … 177 155 } 178 156 #else 179 void MarkStack::validate Value(JSValue)157 void MarkStack::validate(JSCell*) 180 158 { 181 } 159 } 182 160 #endif 183 161
Note:
See TracChangeset
for help on using the changeset viewer.