From 2daae5fd11344eaa88a0d92b0f6d65f8d2255c00 Mon Sep 17 00:00:00 2001 From: Ben Murdoch Date: Thu, 2 Jun 2011 12:07:03 +0100 Subject: Merge WebKit at r84325: Initial merge by git. Change-Id: Ic1a909300ecc0a13ddc6b4e784371d2ac6e3d59b --- Source/JavaScriptCore/heap/MarkedSpace.cpp | 166 +++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 Source/JavaScriptCore/heap/MarkedSpace.cpp (limited to 'Source/JavaScriptCore/heap/MarkedSpace.cpp') diff --git a/Source/JavaScriptCore/heap/MarkedSpace.cpp b/Source/JavaScriptCore/heap/MarkedSpace.cpp new file mode 100644 index 0000000..d9a1e42 --- /dev/null +++ b/Source/JavaScriptCore/heap/MarkedSpace.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007 Eric Seidel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "config.h" +#include "MarkedSpace.h" + +#include "JSCell.h" +#include "JSGlobalData.h" +#include "JSLock.h" +#include "JSObject.h" +#include "ScopeChain.h" + +namespace JSC { + +class Structure; + +MarkedSpace::MarkedSpace(JSGlobalData* globalData) + : m_waterMark(0) + , m_highWaterMark(0) + , m_globalData(globalData) +{ + for (size_t cellSize = preciseStep; cellSize < preciseCutoff; cellSize += preciseStep) + sizeClassFor(cellSize).cellSize = cellSize; + + for (size_t cellSize = impreciseStep; cellSize < impreciseCutoff; cellSize += impreciseStep) + sizeClassFor(cellSize).cellSize = cellSize; +} + +void MarkedSpace::destroy() +{ + clearMarks(); + shrink(); + ASSERT(!size()); +} + +MarkedBlock* MarkedSpace::allocateBlock(SizeClass& sizeClass) +{ + MarkedBlock* block = MarkedBlock::create(globalData(), sizeClass.cellSize); + sizeClass.blockList.append(block); + sizeClass.nextBlock = block; + m_blocks.add(block); + + return block; +} + +void MarkedSpace::freeBlocks(DoublyLinkedList& blocks) +{ + MarkedBlock* next; + for (MarkedBlock* block = blocks.head(); block; block = next) { + next = block->next(); + + blocks.remove(block); + m_blocks.remove(block); + MarkedBlock::destroy(block); + } +} + +void* MarkedSpace::allocateFromSizeClass(SizeClass& sizeClass) +{ + for (MarkedBlock*& block = sizeClass.nextBlock ; block; block = block->next()) { + if (void* result = block->allocate()) + return result; + + m_waterMark += block->capacity(); + } + + if (m_waterMark < m_highWaterMark) + return allocateBlock(sizeClass)->allocate(); + + return 0; +} + +void MarkedSpace::shrink() +{ + // We record a temporary list of empties to avoid modifying m_blocks while iterating it. + DoublyLinkedList empties; + + BlockIterator end = m_blocks.end(); + for (BlockIterator it = m_blocks.begin(); it != end; ++it) { + MarkedBlock* block = *it; + if (block->isEmpty()) { + SizeClass& sizeClass = sizeClassFor(block->cellSize()); + sizeClass.blockList.remove(block); + sizeClass.nextBlock = sizeClass.blockList.head(); + empties.append(block); + } + } + + freeBlocks(empties); + ASSERT(empties.isEmpty()); +} + +void MarkedSpace::clearMarks() +{ + BlockIterator end = m_blocks.end(); + for (BlockIterator it = m_blocks.begin(); it != end; ++it) + (*it)->clearMarks(); +} + +void MarkedSpace::sweep() +{ + BlockIterator end = m_blocks.end(); + for (BlockIterator it = m_blocks.begin(); it != end; ++it) + (*it)->sweep(); +} + +size_t MarkedSpace::objectCount() const +{ + size_t result = 0; + BlockIterator end = m_blocks.end(); + for (BlockIterator it = m_blocks.begin(); it != end; ++it) + result += (*it)->markCount(); + return result; +} + +size_t MarkedSpace::size() const +{ + size_t result = 0; + BlockIterator end = m_blocks.end(); + for (BlockIterator it = m_blocks.begin(); it != end; ++it) + result += (*it)->size(); + return result; +} + +size_t MarkedSpace::capacity() const +{ + size_t result = 0; + BlockIterator end = m_blocks.end(); + for (BlockIterator it = m_blocks.begin(); it != end; ++it) + result += (*it)->capacity(); + return result; +} + +void MarkedSpace::reset() +{ + m_waterMark = 0; + + for (size_t cellSize = preciseStep; cellSize < preciseCutoff; cellSize += preciseStep) + sizeClassFor(cellSize).reset(); + + for (size_t cellSize = impreciseStep; cellSize < impreciseCutoff; cellSize += impreciseStep) + sizeClassFor(cellSize).reset(); + + BlockIterator end = m_blocks.end(); + for (BlockIterator it = m_blocks.begin(); it != end; ++it) + (*it)->reset(); +} + +} // namespace JSC -- cgit v1.1