Commit 4b14805e authored by mhahnenberg@apple.com's avatar mhahnenberg@apple.com

Move Region into its own header

https://bugs.webkit.org/show_bug.cgi?id=113617

Reviewed by Geoffrey Garen.

BlockAllocator.h is getting a little crowded. We should move the Region class into its own
header, since it's pretty independent from the BlockAllocator.

* GNUmakefile.list.am:
* JavaScriptCore.gypi:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* heap/BlockAllocator.h:
(JSC):
* heap/Region.h: Added.
(JSC):
(DeadBlock):
(JSC::DeadBlock::DeadBlock):
(Region):
(JSC::Region::blockSize):
(JSC::Region::isFull):
(JSC::Region::isEmpty):
(JSC::Region::isCustomSize):
(JSC::Region::create):
(JSC::Region::createCustomSize):
(JSC::Region::Region):
(JSC::Region::~Region):
(JSC::Region::reset):
(JSC::Region::allocate):
(JSC::Region::deallocate):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@147282 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 336485f0
2013-03-30 Mark Hahnenberg <mhahnenberg@apple.com>
Move Region into its own header
https://bugs.webkit.org/show_bug.cgi?id=113617
Reviewed by Geoffrey Garen.
BlockAllocator.h is getting a little crowded. We should move the Region class into its own
header, since it's pretty independent from the BlockAllocator.
* GNUmakefile.list.am:
* JavaScriptCore.gypi:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* heap/BlockAllocator.h:
(JSC):
* heap/Region.h: Added.
(JSC):
(DeadBlock):
(JSC::DeadBlock::DeadBlock):
(Region):
(JSC::Region::blockSize):
(JSC::Region::isFull):
(JSC::Region::isEmpty):
(JSC::Region::isCustomSize):
(JSC::Region::create):
(JSC::Region::createCustomSize):
(JSC::Region::Region):
(JSC::Region::~Region):
(JSC::Region::reset):
(JSC::Region::allocate):
(JSC::Region::deallocate):
2013-03-29 Mark Hahnenberg <mhahnenberg@apple.com>
Objective-C API: Remove -[JSManagedValue managedValueWithValue:owner:]
......
......@@ -356,6 +356,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/heap/MarkedSpace.cpp \
Source/JavaScriptCore/heap/MarkedSpace.h \
Source/JavaScriptCore/heap/PassWeak.h \
Source/JavaScriptCore/heap/Region.h \
Source/JavaScriptCore/heap/Strong.h \
Source/JavaScriptCore/heap/StrongInlines.h \
Source/JavaScriptCore/heap/UnconditionalFinalizer.h \
......
......@@ -393,6 +393,7 @@
'heap/MarkStack.h',
'heap/MarkStackInlines.h',
'heap/PassWeak.h',
'heap/Region.h',
'heap/SlotVisitor.cpp',
'heap/SlotVisitor.h',
'heap/SlotVisitorInlines.h',
......
......@@ -2777,6 +2777,10 @@
RelativePath="..\..\heap\MarkStackInlines.h"
>
</File>
<File
RelativePath="..\..\heap\Region.h"
>
</File>
<File
RelativePath="..\..\heap\SlotVisitor.cpp"
>
......
......@@ -530,6 +530,7 @@
<ClInclude Include="..\heap\MarkStack.h" />
<ClInclude Include="..\heap\MarkStackInlines.h" />
<ClInclude Include="..\heap\PassWeak.h" />
<ClInclude Include="..\heap\Region.h" />
<ClInclude Include="..\heap\SlotVisitor.h" />
<ClInclude Include="..\heap\SlotVisitorInlines.h" />
<ClInclude Include="..\heap\Strong.h" />
......
......@@ -1139,6 +1139,9 @@
<ClInclude Include="..\heap\PassWeak.h">
<Filter>heap</Filter>
</ClInclude>
<ClInclude Include="..\heap\Region.h">
<Filter>heap</Filter>
</ClInclude>
<ClInclude Include="..\heap\SlotVisitor.h">
<Filter>heap</Filter>
</ClInclude>
......
......@@ -817,6 +817,7 @@
BCF605140E203EF800B9A64D /* ArgList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF605120E203EF800B9A64D /* ArgList.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCFD8C900EEB2EE700283848 /* JumpTable.cpp */; };
BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFD8C910EEB2EE700283848 /* JumpTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
C20B25991706536200C21F4E /* Region.h in Headers */ = {isa = PBXBuildFile; fileRef = C20B25981706536200C21F4E /* Region.h */; settings = {ATTRIBUTES = (Private, ); }; };
C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */; };
C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -1723,6 +1724,7 @@
BCF605120E203EF800B9A64D /* ArgList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgList.h; sourceTree = "<group>"; };
BCFD8C900EEB2EE700283848 /* JumpTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JumpTable.cpp; sourceTree = "<group>"; };
BCFD8C910EEB2EE700283848 /* JumpTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JumpTable.h; sourceTree = "<group>"; };
C20B25981706536200C21F4E /* Region.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Region.h; sourceTree = "<group>"; };
C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureRareDataInlines.h; sourceTree = "<group>"; };
C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCThreadSharedData.cpp; sourceTree = "<group>"; };
C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCThreadSharedData.h; sourceTree = "<group>"; };
......@@ -2163,6 +2165,7 @@
0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */,
C28318FF16FE4B7D00157BFD /* HandleBlock.h */,
C283190116FE533E00157BFD /* HandleBlockInlines.h */,
C20B25981706536200C21F4E /* Region.h */,
);
path = heap;
sourceTree = "<group>";
......@@ -2962,6 +2965,7 @@
0FB7F39515ED8E4600F167B2 /* ArrayConventions.h in Headers */,
0F63945515D07057006A597C /* ArrayProfile.h in Headers */,
BC18C3E70E16F5CD00B34460 /* ArrayPrototype.h in Headers */,
C20B25991706536200C21F4E /* Region.h in Headers */,
C283190016FE4B7D00157BFD /* HandleBlock.h in Headers */,
BC18C41D0E16F5CD00B34460 /* JSClassRef.h in Headers */,
86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */,
......
......@@ -27,6 +27,7 @@
#define BlockAllocator_h
#include "HeapBlock.h"
#include "Region.h"
#include <wtf/DoublyLinkedList.h>
#include <wtf/Forward.h>
#include <wtf/PageAllocationAligned.h>
......@@ -41,119 +42,11 @@ class CopyWorkListSegment;
class HandleBlock;
class MarkStackSegment;
class MarkedBlock;
class Region;
class WeakBlock;
// Simple allocator to reduce VM cost by holding onto blocks of memory for
// short periods of time and then freeing them on a secondary thread.
class DeadBlock : public HeapBlock<DeadBlock> {
public:
DeadBlock(Region*);
};
inline DeadBlock::DeadBlock(Region* region)
: HeapBlock<DeadBlock>(region)
{
}
class Region : public DoublyLinkedListNode<Region> {
friend CLASS_IF_GCC DoublyLinkedListNode<Region>;
friend class BlockAllocator;
public:
~Region();
static Region* create(size_t blockSize);
static Region* createCustomSize(size_t blockSize, size_t blockAlignment);
Region* reset(size_t blockSize);
size_t blockSize() const { return m_blockSize; }
bool isFull() const { return m_blocksInUse == m_totalBlocks; }
bool isEmpty() const { return !m_blocksInUse; }
bool isCustomSize() const { return m_isCustomSize; }
DeadBlock* allocate();
void deallocate(void*);
static const size_t s_regionSize = 64 * KB;
private:
Region(PageAllocationAligned&, size_t blockSize, size_t totalBlocks);
PageAllocationAligned m_allocation;
size_t m_totalBlocks;
size_t m_blocksInUse;
size_t m_blockSize;
bool m_isCustomSize;
Region* m_prev;
Region* m_next;
DoublyLinkedList<DeadBlock> m_deadBlocks;
};
inline Region* Region::create(size_t blockSize)
{
ASSERT(blockSize <= s_regionSize);
ASSERT(!(s_regionSize % blockSize));
PageAllocationAligned allocation = PageAllocationAligned::allocate(s_regionSize, s_regionSize, OSAllocator::JSGCHeapPages);
RELEASE_ASSERT(static_cast<bool>(allocation));
return new Region(allocation, blockSize, s_regionSize / blockSize);
}
inline Region* Region::createCustomSize(size_t blockSize, size_t blockAlignment)
{
PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, blockAlignment, OSAllocator::JSGCHeapPages);
RELEASE_ASSERT(static_cast<bool>(allocation));
Region* region = new Region(allocation, blockSize, 1);
region->m_isCustomSize = true;
return region;
}
inline Region::Region(PageAllocationAligned& allocation, size_t blockSize, size_t totalBlocks)
: DoublyLinkedListNode<Region>()
, m_allocation(allocation)
, m_totalBlocks(totalBlocks)
, m_blocksInUse(0)
, m_blockSize(blockSize)
, m_isCustomSize(false)
, m_prev(0)
, m_next(0)
{
ASSERT(allocation);
char* start = static_cast<char*>(m_allocation.base());
char* end = start + m_allocation.size();
for (char* current = start; current < end; current += blockSize)
m_deadBlocks.append(new (NotNull, current) DeadBlock(this));
}
inline Region::~Region()
{
ASSERT(isEmpty());
m_allocation.deallocate();
}
inline Region* Region::reset(size_t blockSize)
{
ASSERT(isEmpty());
PageAllocationAligned allocation = m_allocation;
return new (NotNull, this) Region(allocation, blockSize, s_regionSize / blockSize);
}
inline DeadBlock* Region::allocate()
{
ASSERT(!isFull());
m_blocksInUse++;
return m_deadBlocks.removeHead();
}
inline void Region::deallocate(void* base)
{
ASSERT(base);
ASSERT(m_blocksInUse);
ASSERT(base >= m_allocation.base() && base < static_cast<char*>(m_allocation.base()) + m_allocation.size());
DeadBlock* block = new (NotNull, base) DeadBlock(this);
m_deadBlocks.push(block);
m_blocksInUse--;
}
class BlockAllocator {
public:
BlockAllocator();
......
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef JSC_Region_h
#define JSC_Region_h
#include "HeapBlock.h"
#include <wtf/DoublyLinkedList.h>
#include <wtf/PageAllocationAligned.h>
namespace JSC {
class DeadBlock : public HeapBlock<DeadBlock> {
public:
DeadBlock(Region*);
};
inline DeadBlock::DeadBlock(Region* region)
: HeapBlock<DeadBlock>(region)
{
}
class Region : public DoublyLinkedListNode<Region> {
friend CLASS_IF_GCC DoublyLinkedListNode<Region>;
friend class BlockAllocator;
public:
~Region();
static Region* create(size_t blockSize);
static Region* createCustomSize(size_t blockSize, size_t blockAlignment);
Region* reset(size_t blockSize);
size_t blockSize() const { return m_blockSize; }
bool isFull() const { return m_blocksInUse == m_totalBlocks; }
bool isEmpty() const { return !m_blocksInUse; }
bool isCustomSize() const { return m_isCustomSize; }
DeadBlock* allocate();
void deallocate(void*);
static const size_t s_regionSize = 64 * KB;
private:
Region(PageAllocationAligned&, size_t blockSize, size_t totalBlocks);
PageAllocationAligned m_allocation;
size_t m_totalBlocks;
size_t m_blocksInUse;
size_t m_blockSize;
bool m_isCustomSize;
Region* m_prev;
Region* m_next;
DoublyLinkedList<DeadBlock> m_deadBlocks;
};
inline Region* Region::create(size_t blockSize)
{
ASSERT(blockSize <= s_regionSize);
ASSERT(!(s_regionSize % blockSize));
PageAllocationAligned allocation = PageAllocationAligned::allocate(s_regionSize, s_regionSize, OSAllocator::JSGCHeapPages);
RELEASE_ASSERT(static_cast<bool>(allocation));
return new Region(allocation, blockSize, s_regionSize / blockSize);
}
inline Region* Region::createCustomSize(size_t blockSize, size_t blockAlignment)
{
PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, blockAlignment, OSAllocator::JSGCHeapPages);
RELEASE_ASSERT(static_cast<bool>(allocation));
Region* region = new Region(allocation, blockSize, 1);
region->m_isCustomSize = true;
return region;
}
inline Region::Region(PageAllocationAligned& allocation, size_t blockSize, size_t totalBlocks)
: DoublyLinkedListNode<Region>()
, m_allocation(allocation)
, m_totalBlocks(totalBlocks)
, m_blocksInUse(0)
, m_blockSize(blockSize)
, m_isCustomSize(false)
, m_prev(0)
, m_next(0)
{
ASSERT(allocation);
char* start = static_cast<char*>(m_allocation.base());
char* end = start + m_allocation.size();
for (char* current = start; current < end; current += blockSize)
m_deadBlocks.append(new (NotNull, current) DeadBlock(this));
}
inline Region::~Region()
{
ASSERT(isEmpty());
m_allocation.deallocate();
}
inline Region* Region::reset(size_t blockSize)
{
ASSERT(isEmpty());
PageAllocationAligned allocation = m_allocation;
return new (NotNull, this) Region(allocation, blockSize, s_regionSize / blockSize);
}
inline DeadBlock* Region::allocate()
{
ASSERT(!isFull());
m_blocksInUse++;
return m_deadBlocks.removeHead();
}
inline void Region::deallocate(void* base)
{
ASSERT(base);
ASSERT(m_blocksInUse);
ASSERT(base >= m_allocation.base() && base < static_cast<char*>(m_allocation.base()) + m_allocation.size());
DeadBlock* block = new (NotNull, base) DeadBlock(this);
m_deadBlocks.push(block);
m_blocksInUse--;
}
} // namespace JSC
#endif // JSC_Region_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