Commit e6a7f5fb authored by fpizlo@apple.com's avatar fpizlo@apple.com

The executable allocator makes it difficult to free individual

chunks of executable memory
https://bugs.webkit.org/show_bug.cgi?id=66363

Reviewed by Oliver Hunt.
        
Introduced a best-fit, balanced-tree based allocator. The allocator
required a balanced tree that does not allocate memory and that
permits the removal of individual nodes directly (as opposed to by
key); neither AVLTree nor WebCore's PODRedBlackTree supported this.
Changed all references to executable code to use a reference counted
handle.

Source/JavaScriptCore: 

* GNUmakefile.list.am:
* JavaScriptCore.exp:
* JavaScriptCore.vcproj/WTF/WTF.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* assembler/AssemblerBuffer.h:
(JSC::AssemblerBuffer::executableCopy):
* assembler/LinkBuffer.h:
(JSC::LinkBuffer::LinkBuffer):
(JSC::LinkBuffer::finalizeCode):
(JSC::LinkBuffer::linkCode):
* assembler/MacroAssemblerCodeRef.h:
(JSC::MacroAssemblerCodeRef::MacroAssemblerCodeRef):
(JSC::MacroAssemblerCodeRef::createSelfManagedCodeRef):
(JSC::MacroAssemblerCodeRef::executableMemory):
(JSC::MacroAssemblerCodeRef::code):
(JSC::MacroAssemblerCodeRef::size):
(JSC::MacroAssemblerCodeRef::operator!):
* assembler/X86Assembler.h:
(JSC::X86Assembler::executableCopy):
(JSC::X86Assembler::X86InstructionFormatter::executableCopy):
* bytecode/CodeBlock.h:
* bytecode/Instruction.h:
* bytecode/StructureStubInfo.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compile):
(JSC::DFG::JITCompiler::compileFunction):
* dfg/DFGRepatch.cpp:
(JSC::DFG::generateProtoChainAccessStub):
(JSC::DFG::tryCacheGetByID):
(JSC::DFG::tryBuildGetByIDList):
(JSC::DFG::tryBuildGetByIDProtoList):
(JSC::DFG::tryCachePutByID):
* jit/ExecutableAllocator.cpp:
(JSC::ExecutableAllocator::initializeAllocator):
(JSC::ExecutableAllocator::ExecutableAllocator):
(JSC::ExecutableAllocator::allocate):
(JSC::ExecutableAllocator::committedByteCount):
(JSC::ExecutableAllocator::dumpProfile):
* jit/ExecutableAllocator.h:
(JSC::ExecutableAllocator::dumpProfile):
* jit/ExecutableAllocatorFixedVMPool.cpp:
(JSC::ExecutableAllocator::initializeAllocator):
(JSC::ExecutableAllocator::ExecutableAllocator):
(JSC::ExecutableAllocator::isValid):
(JSC::ExecutableAllocator::underMemoryPressure):
(JSC::ExecutableAllocator::allocate):
(JSC::ExecutableAllocator::committedByteCount):
(JSC::ExecutableAllocator::dumpProfile):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JIT.h:
(JSC::JIT::compileCTIMachineTrampolines):
(JSC::JIT::compileCTINativeCall):
* jit/JITCode.h:
(JSC::JITCode::operator !):
(JSC::JITCode::addressForCall):
(JSC::JITCode::offsetOf):
(JSC::JITCode::execute):
(JSC::JITCode::start):
(JSC::JITCode::size):
(JSC::JITCode::getExecutableMemory):
(JSC::JITCode::HostFunction):
(JSC::JITCode::JITCode):
* jit/JITOpcodes.cpp:
(JSC::JIT::privateCompileCTIMachineTrampolines):
(JSC::JIT::privateCompileCTINativeCall):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::privateCompileCTIMachineTrampolines):
(JSC::JIT::privateCompileCTINativeCall):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::stringGetByValStubGenerator):
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::privateCompilePutByIdTransition):
(JSC::JIT::privateCompilePatchGetArrayLength):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::stringGetByValStubGenerator):
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::privateCompilePutByIdTransition):
(JSC::JIT::privateCompilePatchGetArrayLength):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
* jit/JITStubs.cpp:
(JSC::JITThunks::JITThunks):
(JSC::DEFINE_STUB_FUNCTION):
(JSC::getPolymorphicAccessStructureListSlot):
(JSC::JITThunks::ctiStub):
(JSC::JITThunks::hostFunctionStub):
* jit/JITStubs.h:
* jit/SpecializedThunkJIT.h:
(JSC::SpecializedThunkJIT::SpecializedThunkJIT):
(JSC::SpecializedThunkJIT::finalize):
* jit/ThunkGenerators.cpp:
(JSC::charCodeAtThunkGenerator):
(JSC::charAtThunkGenerator):
(JSC::fromCharCodeThunkGenerator):
(JSC::sqrtThunkGenerator):
(JSC::floorThunkGenerator):
(JSC::ceilThunkGenerator):
(JSC::roundThunkGenerator):
(JSC::expThunkGenerator):
(JSC::logThunkGenerator):
(JSC::absThunkGenerator):
(JSC::powThunkGenerator):
* jit/ThunkGenerators.h:
* runtime/Executable.h:
(JSC::NativeExecutable::create):
* runtime/InitializeThreading.cpp:
(JSC::initializeThreadingOnce):
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::JSGlobalData):
(JSC::JSGlobalData::dumpSampleData):
* runtime/JSGlobalData.h:
(JSC::JSGlobalData::getCTIStub):
* wtf/CMakeLists.txt:
* wtf/MetaAllocator.cpp: Added.
(WTF::MetaAllocatorHandle::MetaAllocatorHandle):
(WTF::MetaAllocatorHandle::~MetaAllocatorHandle):
(WTF::MetaAllocatorHandle::shrink):
(WTF::MetaAllocator::MetaAllocator):
(WTF::MetaAllocator::allocate):
(WTF::MetaAllocator::currentStatistics):
(WTF::MetaAllocator::findAndRemoveFreeSpace):
(WTF::MetaAllocator::addFreeSpaceFromReleasedHandle):
(WTF::MetaAllocator::addFreshFreeSpace):
(WTF::MetaAllocator::debugFreeSpaceSize):
(WTF::MetaAllocator::addFreeSpace):
(WTF::MetaAllocator::incrementPageOccupancy):
(WTF::MetaAllocator::decrementPageOccupancy):
(WTF::MetaAllocator::roundUp):
(WTF::MetaAllocator::allocFreeSpaceNode):
(WTF::MetaAllocator::freeFreeSpaceNode):
(WTF::MetaAllocator::dumpProfile):
* wtf/MetaAllocator.h: Added.
(WTF::MetaAllocator::bytesAllocated):
(WTF::MetaAllocator::bytesReserved):
(WTF::MetaAllocator::bytesCommitted):
(WTF::MetaAllocator::dumpProfile):
(WTF::MetaAllocator::~MetaAllocator):
* wtf/MetaAllocatorHandle.h: Added.
* wtf/RedBlackTree.h: Added.
(WTF::RedBlackTree::Node::Node):
(WTF::RedBlackTree::Node::successor):
(WTF::RedBlackTree::Node::predecessor):
(WTF::RedBlackTree::Node::reset):
(WTF::RedBlackTree::Node::parent):
(WTF::RedBlackTree::Node::setParent):
(WTF::RedBlackTree::Node::left):
(WTF::RedBlackTree::Node::setLeft):
(WTF::RedBlackTree::Node::right):
(WTF::RedBlackTree::Node::setRight):
(WTF::RedBlackTree::Node::color):
(WTF::RedBlackTree::Node::setColor):
(WTF::RedBlackTree::RedBlackTree):
(WTF::RedBlackTree::insert):
(WTF::RedBlackTree::remove):
(WTF::RedBlackTree::findExact):
(WTF::RedBlackTree::findLeastGreaterThanOrEqual):
(WTF::RedBlackTree::findGreatestLessThanOrEqual):
(WTF::RedBlackTree::first):
(WTF::RedBlackTree::last):
(WTF::RedBlackTree::size):
(WTF::RedBlackTree::isEmpty):
(WTF::RedBlackTree::treeMinimum):
(WTF::RedBlackTree::treeMaximum):
(WTF::RedBlackTree::treeInsert):
(WTF::RedBlackTree::leftRotate):
(WTF::RedBlackTree::rightRotate):
(WTF::RedBlackTree::removeFixup):
* wtf/wtf.pri:
* yarr/YarrJIT.cpp:
(JSC::Yarr::YarrGenerator::compile):
* yarr/YarrJIT.h:
(JSC::Yarr::YarrCodeBlock::execute):
(JSC::Yarr::YarrCodeBlock::getAddr):

Source/JavaScriptGlue: 

* ForwardingHeaders/wtf/MetaAllocatorHandle.h: Added.

Source/WebCore: 

No new layout tests because behavior is not changed.  New API unit
tests:
Tests/WTF/RedBlackTree.cpp
Tests/WTF/MetaAllocator.cpp

* ForwardingHeaders/wtf/MetaAllocatorHandle.h: Added.

Tools: 

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WTF/MetaAllocator.cpp: Added.
(TestWebKitAPI::TEST_F):
* TestWebKitAPI/Tests/WTF/RedBlackTree.cpp: Added.
(TestWebKitAPI::Pair::findExact):
(TestWebKitAPI::Pair::remove):
(TestWebKitAPI::Pair::findLeastGreaterThanOrEqual):
(TestWebKitAPI::Pair::assertFoundAndRemove):
(TestWebKitAPI::Pair::assertEqual):
(TestWebKitAPI::Pair::assertSameValuesForKey):
(TestWebKitAPI::Pair::testDriver):
(TestWebKitAPI::TEST_F):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@94920 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 2cdc5a2d
2011-09-08 Filip Pizlo <fpizlo@apple.com>
The executable allocator makes it difficult to free individual
chunks of executable memory
https://bugs.webkit.org/show_bug.cgi?id=66363
Reviewed by Oliver Hunt.
Introduced a best-fit, balanced-tree based allocator. The allocator
required a balanced tree that does not allocate memory and that
permits the removal of individual nodes directly (as opposed to by
key); neither AVLTree nor WebCore's PODRedBlackTree supported this.
Changed all references to executable code to use a reference counted
handle.
* GNUmakefile.list.am:
* JavaScriptCore.exp:
* JavaScriptCore.vcproj/WTF/WTF.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* assembler/AssemblerBuffer.h:
(JSC::AssemblerBuffer::executableCopy):
* assembler/LinkBuffer.h:
(JSC::LinkBuffer::LinkBuffer):
(JSC::LinkBuffer::finalizeCode):
(JSC::LinkBuffer::linkCode):
* assembler/MacroAssemblerCodeRef.h:
(JSC::MacroAssemblerCodeRef::MacroAssemblerCodeRef):
(JSC::MacroAssemblerCodeRef::createSelfManagedCodeRef):
(JSC::MacroAssemblerCodeRef::executableMemory):
(JSC::MacroAssemblerCodeRef::code):
(JSC::MacroAssemblerCodeRef::size):
(JSC::MacroAssemblerCodeRef::operator!):
* assembler/X86Assembler.h:
(JSC::X86Assembler::executableCopy):
(JSC::X86Assembler::X86InstructionFormatter::executableCopy):
* bytecode/CodeBlock.h:
* bytecode/Instruction.h:
* bytecode/StructureStubInfo.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compile):
(JSC::DFG::JITCompiler::compileFunction):
* dfg/DFGRepatch.cpp:
(JSC::DFG::generateProtoChainAccessStub):
(JSC::DFG::tryCacheGetByID):
(JSC::DFG::tryBuildGetByIDList):
(JSC::DFG::tryBuildGetByIDProtoList):
(JSC::DFG::tryCachePutByID):
* jit/ExecutableAllocator.cpp:
(JSC::ExecutableAllocator::initializeAllocator):
(JSC::ExecutableAllocator::ExecutableAllocator):
(JSC::ExecutableAllocator::allocate):
(JSC::ExecutableAllocator::committedByteCount):
(JSC::ExecutableAllocator::dumpProfile):
* jit/ExecutableAllocator.h:
(JSC::ExecutableAllocator::dumpProfile):
* jit/ExecutableAllocatorFixedVMPool.cpp:
(JSC::ExecutableAllocator::initializeAllocator):
(JSC::ExecutableAllocator::ExecutableAllocator):
(JSC::ExecutableAllocator::isValid):
(JSC::ExecutableAllocator::underMemoryPressure):
(JSC::ExecutableAllocator::allocate):
(JSC::ExecutableAllocator::committedByteCount):
(JSC::ExecutableAllocator::dumpProfile):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JIT.h:
(JSC::JIT::compileCTIMachineTrampolines):
(JSC::JIT::compileCTINativeCall):
* jit/JITCode.h:
(JSC::JITCode::operator !):
(JSC::JITCode::addressForCall):
(JSC::JITCode::offsetOf):
(JSC::JITCode::execute):
(JSC::JITCode::start):
(JSC::JITCode::size):
(JSC::JITCode::getExecutableMemory):
(JSC::JITCode::HostFunction):
(JSC::JITCode::JITCode):
* jit/JITOpcodes.cpp:
(JSC::JIT::privateCompileCTIMachineTrampolines):
(JSC::JIT::privateCompileCTINativeCall):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::privateCompileCTIMachineTrampolines):
(JSC::JIT::privateCompileCTINativeCall):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::stringGetByValStubGenerator):
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::privateCompilePutByIdTransition):
(JSC::JIT::privateCompilePatchGetArrayLength):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::stringGetByValStubGenerator):
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::privateCompilePutByIdTransition):
(JSC::JIT::privateCompilePatchGetArrayLength):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
* jit/JITStubs.cpp:
(JSC::JITThunks::JITThunks):
(JSC::DEFINE_STUB_FUNCTION):
(JSC::getPolymorphicAccessStructureListSlot):
(JSC::JITThunks::ctiStub):
(JSC::JITThunks::hostFunctionStub):
* jit/JITStubs.h:
* jit/SpecializedThunkJIT.h:
(JSC::SpecializedThunkJIT::SpecializedThunkJIT):
(JSC::SpecializedThunkJIT::finalize):
* jit/ThunkGenerators.cpp:
(JSC::charCodeAtThunkGenerator):
(JSC::charAtThunkGenerator):
(JSC::fromCharCodeThunkGenerator):
(JSC::sqrtThunkGenerator):
(JSC::floorThunkGenerator):
(JSC::ceilThunkGenerator):
(JSC::roundThunkGenerator):
(JSC::expThunkGenerator):
(JSC::logThunkGenerator):
(JSC::absThunkGenerator):
(JSC::powThunkGenerator):
* jit/ThunkGenerators.h:
* runtime/Executable.h:
(JSC::NativeExecutable::create):
* runtime/InitializeThreading.cpp:
(JSC::initializeThreadingOnce):
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::JSGlobalData):
(JSC::JSGlobalData::dumpSampleData):
* runtime/JSGlobalData.h:
(JSC::JSGlobalData::getCTIStub):
* wtf/CMakeLists.txt:
* wtf/MetaAllocator.cpp: Added.
(WTF::MetaAllocatorHandle::MetaAllocatorHandle):
(WTF::MetaAllocatorHandle::~MetaAllocatorHandle):
(WTF::MetaAllocatorHandle::shrink):
(WTF::MetaAllocator::MetaAllocator):
(WTF::MetaAllocator::allocate):
(WTF::MetaAllocator::currentStatistics):
(WTF::MetaAllocator::findAndRemoveFreeSpace):
(WTF::MetaAllocator::addFreeSpaceFromReleasedHandle):
(WTF::MetaAllocator::addFreshFreeSpace):
(WTF::MetaAllocator::debugFreeSpaceSize):
(WTF::MetaAllocator::addFreeSpace):
(WTF::MetaAllocator::incrementPageOccupancy):
(WTF::MetaAllocator::decrementPageOccupancy):
(WTF::MetaAllocator::roundUp):
(WTF::MetaAllocator::allocFreeSpaceNode):
(WTF::MetaAllocator::freeFreeSpaceNode):
(WTF::MetaAllocator::dumpProfile):
* wtf/MetaAllocator.h: Added.
(WTF::MetaAllocator::bytesAllocated):
(WTF::MetaAllocator::bytesReserved):
(WTF::MetaAllocator::bytesCommitted):
(WTF::MetaAllocator::dumpProfile):
(WTF::MetaAllocator::~MetaAllocator):
* wtf/MetaAllocatorHandle.h: Added.
* wtf/RedBlackTree.h: Added.
(WTF::RedBlackTree::Node::Node):
(WTF::RedBlackTree::Node::successor):
(WTF::RedBlackTree::Node::predecessor):
(WTF::RedBlackTree::Node::reset):
(WTF::RedBlackTree::Node::parent):
(WTF::RedBlackTree::Node::setParent):
(WTF::RedBlackTree::Node::left):
(WTF::RedBlackTree::Node::setLeft):
(WTF::RedBlackTree::Node::right):
(WTF::RedBlackTree::Node::setRight):
(WTF::RedBlackTree::Node::color):
(WTF::RedBlackTree::Node::setColor):
(WTF::RedBlackTree::RedBlackTree):
(WTF::RedBlackTree::insert):
(WTF::RedBlackTree::remove):
(WTF::RedBlackTree::findExact):
(WTF::RedBlackTree::findLeastGreaterThanOrEqual):
(WTF::RedBlackTree::findGreatestLessThanOrEqual):
(WTF::RedBlackTree::first):
(WTF::RedBlackTree::last):
(WTF::RedBlackTree::size):
(WTF::RedBlackTree::isEmpty):
(WTF::RedBlackTree::treeMinimum):
(WTF::RedBlackTree::treeMaximum):
(WTF::RedBlackTree::treeInsert):
(WTF::RedBlackTree::leftRotate):
(WTF::RedBlackTree::rightRotate):
(WTF::RedBlackTree::removeFixup):
* wtf/wtf.pri:
* yarr/YarrJIT.cpp:
(JSC::Yarr::YarrGenerator::compile):
* yarr/YarrJIT.h:
(JSC::Yarr::YarrCodeBlock::execute):
(JSC::Yarr::YarrCodeBlock::getAddr):
2011-09-10 Sam Weinig <sam@webkit.org>
Remove JSC::isZombie() function, it did nothing and was called by no-one.
......
......@@ -529,6 +529,9 @@ javascriptcore_sources += \
Source/JavaScriptCore/wtf/MathExtras.h \
Source/JavaScriptCore/wtf/MD5.cpp \
Source/JavaScriptCore/wtf/MD5.h \
Source/JavaScriptCore/wtf/MetaAllocator.cpp \
Source/JavaScriptCore/wtf/MetaAllocator.h \
Source/JavaScriptCore/wtf/MetaAllocatorHandle.h \
Source/JavaScriptCore/wtf/MessageQueue.h \
Source/JavaScriptCore/wtf/NonCopyingSort.h \
Source/JavaScriptCore/wtf/Noncopyable.h \
......@@ -561,6 +564,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/wtf/RandomNumber.cpp \
Source/JavaScriptCore/wtf/RandomNumber.h \
Source/JavaScriptCore/wtf/RandomNumberSeed.h \
Source/JavaScriptCore/wtf/RedBlackTree.h \
Source/JavaScriptCore/wtf/RefCounted.h \
Source/JavaScriptCore/wtf/RefCountedLeakCounter.cpp \
Source/JavaScriptCore/wtf/RefCountedLeakCounter.h \
......
......@@ -407,6 +407,11 @@ __ZN3WTF12createThreadEPFPvS0_ES0_PKc
__ZN3WTF12detachThreadEj
__ZN3WTF12isMainThreadEv
__ZN3WTF12randomNumberEv
__ZN3WTF13MetaAllocator17addFreshFreeSpaceEPvm
__ZN3WTF13MetaAllocator17freeFreeSpaceNodeEPNS_12RedBlackTreeImPvE4NodeE
__ZN3WTF13MetaAllocator18debugFreeSpaceSizeEv
__ZN3WTF13MetaAllocator8allocateEm
__ZN3WTF13MetaAllocatorC2Em
__ZN3WTF13StringBuilder11reifyStringEv
__ZN3WTF13StringBuilder11shrinkToFitEv
__ZN3WTF13StringBuilder15reserveCapacityEj
......@@ -441,6 +446,8 @@ __ZN3WTF18calculateUTCOffsetEv
__ZN3WTF18charactersToDoubleEPKtmPbS2_
__ZN3WTF18dateToDaysFrom1970Eiii
__ZN3WTF18monthFromDayInYearEib
__ZN3WTF19MetaAllocatorHandle6shrinkEm
__ZN3WTF19MetaAllocatorHandleD1Ev
__ZN3WTF19initializeThreadingEv
__ZN3WTF20equalIgnoringNullityEPNS_10StringImplES1_
__ZN3WTF20fastMallocStatisticsEv
......@@ -521,6 +528,7 @@ __ZN3WTF8Internal21fastMallocMatchFailedEPv
__ZN3WTF8fastFreeEPv
__ZN3WTF8msToYearEd
__ZN3WTF8nullAtomE
__ZN3WTF8pageSizeEv
__ZN3WTF8starAtomE
__ZN3WTF8textAtomE
__ZN3WTF9ByteArray6createEm
......
......@@ -836,6 +836,18 @@
RelativePath="..\..\wtf\MathExtras.h"
>
</File>
<File
RelativePath="..\..\wtf\MetaAllocator.cpp"
>
</File>
<File
RelativePath="..\..\wtf\MetaAllocator.h"
>
</File>
<File
RelativePath="..\..\wtf\MetaAllocatorHandle.h"
>
</File>
<File
RelativePath="..\..\wtf\MD5.cpp"
>
......@@ -976,6 +988,10 @@
RelativePath="..\..\wtf\RandomNumberSeed.h"
>
</File>
<File
RelativePath="..\..\wtf\RedBlackTree.h"
>
</File>
<File
RelativePath="..\..\wtf\RefCounted.h"
>
......
......@@ -51,6 +51,10 @@
0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */; };
0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7700911402FF280078EB39 /* SamplingCounter.cpp */; };
0F963B2713F753BB0002D9B2 /* RedBlackTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B2613F753990002D9B2 /* RedBlackTree.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F963B2C13F853EC0002D9B2 /* MetaAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F963B2B13F853C70002D9B2 /* MetaAllocator.cpp */; settings = {COMPILER_FLAGS = "-fno-strict-aliasing"; }; };
0F963B2D13F854020002D9B2 /* MetaAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B2A13F853BD0002D9B2 /* MetaAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F963B2F13FC66BB0002D9B2 /* MetaAllocatorHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B2E13FC66AE0002D9B2 /* MetaAllocatorHandle.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */; };
......@@ -558,7 +562,7 @@
BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A396A60CD2933100B5B4FF /* SymbolTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C46C0E16F5CD00B34460 /* TCPackedCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA479650CFBCF56009328A0 /* TCPackedCache.h */; };
BC18C46D0E16F5CD00B34460 /* TCPageMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 6541BD6E08E80A17002CBEE7 /* TCPageMap.h */; };
BC18C46E0E16F5CD00B34460 /* TCSpinLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 6541BD6F08E80A17002CBEE7 /* TCSpinLock.h */; };
BC18C46E0E16F5CD00B34460 /* TCSpinLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 6541BD6F08E80A17002CBEE7 /* TCSpinLock.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C46F0E16F5CD00B34460 /* TCSystemAlloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 6541BD7108E80A17002CBEE7 /* TCSystemAlloc.h */; };
BC18C4700E16F5CD00B34460 /* Threading.h in Headers */ = {isa = PBXBuildFile; fileRef = E1EE79220D6C95CD00FEA3BA /* Threading.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4710E16F5CD00B34460 /* ThreadSpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = E1B7C8BD0DA3A3360074B0DC /* ThreadSpecific.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -778,6 +782,10 @@
0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakReferenceHarvester.h; sourceTree = "<group>"; };
0F77008E1402FDD60078EB39 /* SamplingCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingCounter.h; sourceTree = "<group>"; };
0F7700911402FF280078EB39 /* SamplingCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingCounter.cpp; sourceTree = "<group>"; };
0F963B2613F753990002D9B2 /* RedBlackTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RedBlackTree.h; sourceTree = "<group>"; };
0F963B2A13F853BD0002D9B2 /* MetaAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MetaAllocator.h; sourceTree = "<group>"; };
0F963B2B13F853C70002D9B2 /* MetaAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MetaAllocator.cpp; sourceTree = "<group>"; };
0F963B2E13FC66AE0002D9B2 /* MetaAllocatorHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MetaAllocatorHandle.h; sourceTree = "<group>"; };
0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueProfile.h; sourceTree = "<group>"; };
0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierSupport.cpp; sourceTree = "<group>"; };
0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierSupport.h; sourceTree = "<group>"; };
......@@ -1763,6 +1771,10 @@
65162EF108E6A21C007556CD /* wtf */ = {
isa = PBXGroup;
children = (
0F963B2E13FC66AE0002D9B2 /* MetaAllocatorHandle.h */,
0F963B2B13F853C70002D9B2 /* MetaAllocator.cpp */,
0F963B2A13F853BD0002D9B2 /* MetaAllocator.h */,
0F963B2613F753990002D9B2 /* RedBlackTree.h */,
C2EE599D13FC972A009CEAFE /* DecimalNumber.cpp */,
C2EE599E13FC972A009CEAFE /* DecimalNumber.h */,
C22C524813FAF6EF00B7DC0D /* dtoa */,
......@@ -2383,6 +2395,10 @@
86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */,
BC18C3E60E16F5CD00B34460 /* ArrayConstructor.h in Headers */,
BC18C46E0E16F5CD00B34460 /* TCSpinLock.h in Headers */,
0F963B2F13FC66BB0002D9B2 /* MetaAllocatorHandle.h in Headers */,
0F963B2D13F854020002D9B2 /* MetaAllocator.h in Headers */,
0F963B2713F753BB0002D9B2 /* RedBlackTree.h in Headers */,
0FC815151405119B00CFA603 /* VTableSpectrum.h in Headers */,
C22B31B9140577D700DB475A /* SamplingCounter.h in Headers */,
0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */,
......@@ -2686,7 +2702,6 @@
A784A26411D16622005776AC /* SyntaxChecker.h in Headers */,
BC18C46C0E16F5CD00B34460 /* TCPackedCache.h in Headers */,
BC18C46D0E16F5CD00B34460 /* TCPageMap.h in Headers */,
BC18C46E0E16F5CD00B34460 /* TCSpinLock.h in Headers */,
BC18C46F0E16F5CD00B34460 /* TCSystemAlloc.h in Headers */,
971EDEA61169E0D3005E4262 /* Terminator.h in Headers */,
F3BD31ED126735770065467F /* TextPosition.h in Headers */,
......@@ -3049,6 +3064,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0F963B2C13F853EC0002D9B2 /* MetaAllocator.cpp in Sources */,
0FD82E2114172CE300179C94 /* DFGCapabilities.cpp in Sources */,
0FD3C82514115D4000FD81CB /* DFGPropagator.cpp in Sources */,
0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */,
......
......@@ -28,6 +28,7 @@
#if ENABLE(ASSEMBLER)
#include "JSGlobalData.h"
#include "stdint.h"
#include <string.h>
#include <jit/ExecutableAllocator.h>
......@@ -128,19 +129,21 @@ namespace JSC {
return AssemblerLabel(m_index);
}
void* executableCopy(JSGlobalData& globalData, ExecutablePool* allocator)
PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData)
{
if (!m_index)
return 0;
void* result = allocator->alloc(globalData, m_index);
RefPtr<ExecutableMemoryHandle> result = globalData.executableAllocator.allocate(globalData, m_index);
if (!result)
return 0;
ExecutableAllocator::makeWritable(result, m_index);
ExecutableAllocator::makeWritable(result->start(), result->sizeInBytes());
return memcpy(result, m_buffer, m_index);
memcpy(result->start(), m_buffer, m_index);
return result.release();
}
void rewindToLabel(AssemblerLabel label)
......
......@@ -69,22 +69,8 @@ class LinkBuffer {
#endif
public:
LinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, PassRefPtr<ExecutablePool> executablePool)
: m_executablePool(executablePool)
, m_size(0)
, m_code(0)
, m_assembler(masm)
, m_globalData(&globalData)
#ifndef NDEBUG
, m_completed(false)
#endif
{
linkCode();
}
LinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, ExecutableAllocator& allocator)
: m_executablePool(allocator.poolForSize(globalData, masm->m_assembler.codeSize()))
, m_size(0)
LinkBuffer(JSGlobalData& globalData, MacroAssembler* masm)
: m_size(0)
, m_code(0)
, m_assembler(masm)
, m_globalData(&globalData)
......@@ -185,14 +171,7 @@ public:
{
performFinalization();
return CodeRef(m_code, m_executablePool, m_size);
}
CodeLocationLabel finalizeCodeAddendum()
{
performFinalization();
return CodeLocationLabel(code());
return CodeRef(m_executableMemory);
}
CodePtr trampolineAt(Label label)
......@@ -232,14 +211,19 @@ private:
{
ASSERT(!m_code);
#if !ENABLE(BRANCH_COMPACTION)
m_code = m_assembler->m_assembler.executableCopy(*m_globalData, m_executablePool.get());
m_executableMemory = m_assembler->m_assembler.executableCopy(*m_globalData);
if (!m_executableMemory)
return;
m_code = m_executableMemory->start();
m_size = m_assembler->m_assembler.codeSize();
ASSERT(m_code);
#else
size_t initialSize = m_assembler->m_assembler.codeSize();
m_code = (uint8_t*)m_executablePool->alloc(*m_globalData, initialSize);
if (!m_code)
m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, initialSize);
if (!m_executableMemory)
return;
m_code = (uint8_t*)m_executableMemory->start();
ASSERT(m_code);
ExecutableAllocator::makeWritable(m_code, initialSize);
uint8_t* inData = (uint8_t*)m_assembler->unlinkedCode();
uint8_t* outData = reinterpret_cast<uint8_t*>(m_code);
......@@ -297,7 +281,7 @@ private:
jumpsToLink.clear();
m_size = writePtr + initialSize - readPtr;
m_executablePool->tryShrink(m_code, initialSize, m_size);
m_executableMemory->shrink(m_size);
#if DUMP_LINK_STATISTICS
dumpLinkStatistics(m_code, initialSize, m_size);
......@@ -366,7 +350,7 @@ private:
}
#endif
RefPtr<ExecutablePool> m_executablePool;
RefPtr<ExecutableMemoryHandle> m_executableMemory;
size_t m_size;
void* m_code;
MacroAssembler* m_assembler;
......
......@@ -199,22 +199,59 @@ private:
// pointer to the code, and a ref pointer to the pool from within which it
// was allocated.
class MacroAssemblerCodeRef {
private:
// This is private because it's dangerous enough that we want uses of it
// to be easy to find - hence the static create method below.
explicit MacroAssemblerCodeRef(MacroAssemblerCodePtr codePtr)
: m_codePtr(codePtr)
{
ASSERT(m_codePtr);
}
public:
MacroAssemblerCodeRef()
: m_size(0)
{
}
MacroAssemblerCodeRef(void* code, PassRefPtr<ExecutablePool> executablePool, size_t size)
: m_code(code)
, m_executablePool(executablePool)
, m_size(size)
MacroAssemblerCodeRef(PassRefPtr<ExecutableMemoryHandle> executableMemory)
: m_codePtr(executableMemory->start())
, m_executableMemory(executableMemory)
{
ASSERT(m_executableMemory->isManaged());
ASSERT(m_executableMemory->start());
ASSERT(m_codePtr);
}
// Use this only when you know that the codePtr refers to code that is
// already being kept alive through some other means. Typically this means
// that codePtr is immortal.
static MacroAssemblerCodeRef createSelfManagedCodeRef(MacroAssemblerCodePtr codePtr)
{
return MacroAssemblerCodeRef(codePtr);
}
ExecutableMemoryHandle* executableMemory() const
{
return m_executableMemory.get();
}
MacroAssemblerCodePtr code() const
{
return m_codePtr;
}
size_t size() const
{
if (!m_executableMemory)
return 0;
return m_executableMemory->sizeInBytes();
}
bool operator!() const { return !m_codePtr; }
MacroAssemblerCodePtr m_code;
RefPtr<ExecutablePool> m_executablePool;
size_t m_size;
private:
MacroAssemblerCodePtr m_codePtr;
RefPtr<ExecutableMemoryHandle> m_executableMemory;
};
} // namespace JSC
......
......@@ -1595,9 +1595,9 @@ public:
return b.m_offset - a.m_offset;
}
void* executableCopy(JSGlobalData& globalData, ExecutablePool* allocator)
PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData)
{
return m_formatter.executableCopy(globalData, allocator);
return m_formatter.executableCopy(globalData);
}
void rewindToLabel(AssemblerLabel rewindTo) { m_formatter.rewindToLabel(rewindTo); }
......@@ -1939,9 +1939,9 @@ private:
bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
void* data() const { return m_buffer.data(); }
void* executableCopy(JSGlobalData& globalData, ExecutablePool* allocator)
PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData)
{
return m_buffer.executableCopy(globalData, allocator);
return m_buffer.executableCopy(globalData);
}
void rewindToLabel(AssemblerLabel rewindTo) { m_buffer.rewindToLabel(rewindTo); }
......
......@@ -324,7 +324,7 @@ namespace JSC {
}
JITCode& getJITCode() { return m_jitCode; }
JITCode::JITType getJITType() { return m_jitCode.jitType(); }
ExecutablePool* executablePool() { return getJITCode().getExecutablePool(); }
ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); }
virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*) = 0;
virtual CodeBlock* replacement() = 0;
virtual bool canCompileWithDFG() = 0;
......
......@@ -50,7 +50,7 @@ namespace JSC {
class StructureChain;
#if ENABLE(JIT)
typedef CodeLocationLabel PolymorphicAccessStructureListStubRoutineType;
typedef MacroAssemblerCodeRef PolymorphicAccessStructureListStubRoutineType;
// Structure used by op_get_by_id_self_list and op_get_by_id_proto_list instruction to hold data off the main opcode stream.
struct PolymorphicAccessStructureList {
......
......@@ -173,7 +173,7 @@ namespace JSC {
} putByIdReplace;
} u;
CodeLocationLabel stubRoutine;
MacroAssemblerCodeRef stubRoutine;
CodeLocationCall callReturnLocation;
CodeLocationLabel hotPathBegin;
};
......
......@@ -955,7 +955,7 @@ void JITCompiler::compile(JITCode& entry)
// Generate the body of the program.
compileBody();
// Link
LinkBuffer linkBuffer(*m_globalData, this, m_globalData->executableAllocator);
LinkBuffer linkBuffer(*m_globalData, this);
link(linkBuffer);
entry = JITCode(linkBuffer.finalizeCode(), JITCode::DFGJIT);
}
......@@ -1013,7 +1013,7 @@ void JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi
// === Link ===
LinkBuffer linkBuffer(*m_globalData, this, m_globalData->executableAllocator);
LinkBuffer linkBuffer(*m_globalData, this);
link(linkBuffer);
</