[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
barraclough at apple.com
barraclough at apple.com
Wed Dec 22 11:30:30 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit ae7fcf1010516feb36d6966f82002446079d6685
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Jul 27 19:14:40 2010 +0000
Bug 42621 - Add a bump allocator for the YARR interpreter
Reviewed by Oliver Hunt.
The regex engine requires lifo allocation, however currently uses the general purpose
malloc/free memory allocation. A simple bump pointer allocator should provide a lower
overhead allocation solution.
JavaScriptCore:
When using YARR interpreter, 15% progression on v8-regex.
* JavaScriptCore.xcodeproj/project.pbxproj:
* runtime/JSGlobalData.h:
* runtime/RegExp.cpp:
(JSC::RegExp::compile):
* wtf/BumpPointerAllocator.h: Added.
(WTF::BumpPointerPool::ensureCapacity):
(WTF::BumpPointerPool::alloc):
(WTF::BumpPointerPool::dealloc):
(WTF::BumpPointerPool::operator new):
(WTF::BumpPointerPool::BumpPointerPool):
(WTF::BumpPointerPool::create):
(WTF::BumpPointerPool::shrink):
(WTF::BumpPointerPool::destroy):
(WTF::BumpPointerPool::ensureCapacityCrossPool):
(WTF::BumpPointerPool::deallocCrossPool):
(WTF::BumpPointerAllocator::BumpPointerAllocator):
(WTF::BumpPointerAllocator::~BumpPointerAllocator):
(WTF::BumpPointerAllocator::startAllocator):
(WTF::BumpPointerAllocator::stopAllocator):
* yarr/RegexInterpreter.cpp:
(JSC::Yarr::Interpreter::allocDisjunctionContext):
(JSC::Yarr::Interpreter::freeDisjunctionContext):
(JSC::Yarr::Interpreter::allocParenthesesDisjunctionContext):
(JSC::Yarr::Interpreter::freeParenthesesDisjunctionContext):
(JSC::Yarr::Interpreter::interpret):
(JSC::Yarr::Interpreter::Interpreter):
(JSC::Yarr::ByteCompiler::compile):
(JSC::Yarr::byteCompileRegex):
* yarr/RegexInterpreter.h:
(JSC::Yarr::BytecodePattern::BytecodePattern):
JavaScriptGlue:
* ForwardingHeaders/wtf/BumpPointerAllocator.h: Added.
WebCore:
* ForwardingHeaders/wtf/BumpPointerAllocator.h: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64146 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 38f469f..a9bf93b 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,46 @@
+2010-07-27 Gavin Barraclough <barraclough at apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 42621 - Add a bump allocator for the YARR interpreter
+
+ The regex engine requires lifo allocation, however currently uses the general purpose
+ malloc/free memory allocation. A simple bump pointer allocator should provide a lower
+ overhead allocation solution.
+
+ When using YARR interpreter, 15% progression on v8-regex.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/JSGlobalData.h:
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::compile):
+ * wtf/BumpPointerAllocator.h: Added.
+ (WTF::BumpPointerPool::ensureCapacity):
+ (WTF::BumpPointerPool::alloc):
+ (WTF::BumpPointerPool::dealloc):
+ (WTF::BumpPointerPool::operator new):
+ (WTF::BumpPointerPool::BumpPointerPool):
+ (WTF::BumpPointerPool::create):
+ (WTF::BumpPointerPool::shrink):
+ (WTF::BumpPointerPool::destroy):
+ (WTF::BumpPointerPool::ensureCapacityCrossPool):
+ (WTF::BumpPointerPool::deallocCrossPool):
+ (WTF::BumpPointerAllocator::BumpPointerAllocator):
+ (WTF::BumpPointerAllocator::~BumpPointerAllocator):
+ (WTF::BumpPointerAllocator::startAllocator):
+ (WTF::BumpPointerAllocator::stopAllocator):
+ * yarr/RegexInterpreter.cpp:
+ (JSC::Yarr::Interpreter::allocDisjunctionContext):
+ (JSC::Yarr::Interpreter::freeDisjunctionContext):
+ (JSC::Yarr::Interpreter::allocParenthesesDisjunctionContext):
+ (JSC::Yarr::Interpreter::freeParenthesesDisjunctionContext):
+ (JSC::Yarr::Interpreter::interpret):
+ (JSC::Yarr::Interpreter::Interpreter):
+ (JSC::Yarr::ByteCompiler::compile):
+ (JSC::Yarr::byteCompileRegex):
+ * yarr/RegexInterpreter.h:
+ (JSC::Yarr::BytecodePattern::BytecodePattern):
+
2010-07-26 Gavin Barraclough <barraclough at apple.com>
Windows build fix from Chromium/GTK build fix!
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 118efde..9e86120 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -204,6 +204,7 @@
86565742115BE3DA00291F40 /* CString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86565740115BE3DA00291F40 /* CString.cpp */; };
86565743115BE3DA00291F40 /* CString.h in Headers */ = {isa = PBXBuildFile; fileRef = 86565741115BE3DA00291F40 /* CString.h */; settings = {ATTRIBUTES = (Private, ); }; };
865F408810E7D56300947361 /* APIShims.h in Headers */ = {isa = PBXBuildFile; fileRef = 865F408710E7D56300947361 /* APIShims.h */; };
+ 86676D5211FED9BC004B6863 /* BumpPointerAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 86676D4D11FED55D004B6863 /* BumpPointerAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
868BFA08117CEFD100B908B1 /* AtomicString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 868BFA00117CEFD100B908B1 /* AtomicString.cpp */; };
868BFA09117CEFD100B908B1 /* AtomicString.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA01117CEFD100B908B1 /* AtomicString.h */; settings = {ATTRIBUTES = (Private, ); }; };
868BFA0A117CEFD100B908B1 /* AtomicStringImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA02117CEFD100B908B1 /* AtomicStringImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -774,6 +775,7 @@
86565740115BE3DA00291F40 /* CString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CString.cpp; path = text/CString.cpp; sourceTree = "<group>"; };
86565741115BE3DA00291F40 /* CString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CString.h; path = text/CString.h; sourceTree = "<group>"; };
865F408710E7D56300947361 /* APIShims.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIShims.h; sourceTree = "<group>"; };
+ 86676D4D11FED55D004B6863 /* BumpPointerAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BumpPointerAllocator.h; sourceTree = "<group>"; };
867FC35F11B763950025105E /* JavaScriptCore.JSVALUE32_64only.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; path = JavaScriptCore.JSVALUE32_64only.exp; sourceTree = "<group>"; };
867FC36011B763950025105E /* JavaScriptCore.JSVALUE32only.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; path = JavaScriptCore.JSVALUE32only.exp; sourceTree = "<group>"; };
867FC36111B763950025105E /* JavaScriptCore.JSVALUE64only.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; path = JavaScriptCore.JSVALUE64only.exp; sourceTree = "<group>"; };
@@ -1404,6 +1406,7 @@
65E217B708E7EECC0023E5F6 /* Assertions.h */,
BC5F7BBB11823B590052C02C /* Atomics.h */,
E1A596370DE3E1C300C17E37 /* AVLTree.h */,
+ 86676D4D11FED55D004B6863 /* BumpPointerAllocator.h */,
A7A1F7AA0F252B3C00E184E2 /* ByteArray.cpp */,
A7A1F7AB0F252B3C00E184E2 /* ByteArray.h */,
0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */,
@@ -1921,6 +1924,7 @@
BC18C3EB0E16F5CD00B34460 /* AVLTree.h in Headers */,
147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */,
BC18C3EC0E16F5CD00B34460 /* BooleanObject.h in Headers */,
+ 86676D5211FED9BC004B6863 /* BumpPointerAllocator.h in Headers */,
A7A1F7AD0F252B3C00E184E2 /* ByteArray.h in Headers */,
969A07230ED1CE3300F1F681 /* BytecodeGenerator.h in Headers */,
869D04AF1193B54D00803475 /* CachedTranscendentalFunction.h in Headers */,
@@ -2083,6 +2087,7 @@
0BDFFAE10FC6193100D69EF4 /* OwnFastMallocPtr.h in Headers */,
BC18C44A0E16F5CD00B34460 /* OwnPtr.h in Headers */,
4409D8470FAF80A200523B87 /* OwnPtrCommon.h in Headers */,
+ 8627E5EC11F1281900A313B5 /* PageAllocation.h in Headers */,
BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */,
93052C350FB792190048FDC3 /* ParserArena.h in Headers */,
44DD48530FAEA85000D6B4EB /* PassOwnPtr.h in Headers */,
@@ -2188,7 +2193,6 @@
868BFA18117CF19900B908B1 /* WTFString.h in Headers */,
86D08D5411793613006E5ED0 /* WTFThreadData.h in Headers */,
9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */,
- 8627E5EC11F1281900A313B5 /* PageAllocation.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index 23b6b21..63f9ad8 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -41,6 +41,7 @@
#include "Terminator.h"
#include "TimeoutChecker.h"
#include "WeakRandom.h"
+#include <wtf/BumpPointerAllocator.h>
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
@@ -219,6 +220,8 @@ namespace JSC {
RegExpCache* m_regExpCache;
+ BumpPointerAllocator m_regexAllocator;
+
#ifndef NDEBUG
ThreadIdentifier exclusiveThread;
#endif
diff --git a/JavaScriptCore/runtime/RegExp.cpp b/JavaScriptCore/runtime/RegExp.cpp
index d8b217d..59e3f35 100644
--- a/JavaScriptCore/runtime/RegExp.cpp
+++ b/JavaScriptCore/runtime/RegExp.cpp
@@ -85,8 +85,7 @@ void RegExp::compile(JSGlobalData* globalData)
#if ENABLE(YARR_JIT)
Yarr::jitCompileRegex(globalData, m_regExpJITCode, m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline());
#else
- UNUSED_PARAM(globalData);
- m_regExpBytecode.set(Yarr::byteCompileRegex(m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline()));
+ m_regExpBytecode = Yarr::byteCompileRegex(m_pattern, m_numSubpatterns, m_constructionError, &globalData->m_regexAllocator, ignoreCase(), multiline());
#endif
}
diff --git a/JavaScriptCore/wtf/BumpPointerAllocator.h b/JavaScriptCore/wtf/BumpPointerAllocator.h
new file mode 100644
index 0000000..3deefe6
--- /dev/null
+++ b/JavaScriptCore/wtf/BumpPointerAllocator.h
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2010 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. ``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
+ * 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 BumpPointerAllocator_h
+#define BumpPointerAllocator_h
+
+#include <wtf/PageAllocation.h>
+
+namespace WTF {
+
+#define MINIMUM_BUMP_POOL_SIZE 0x1000
+
+class BumpPointerPool {
+public:
+ // ensureCapacity will check whether the current pool has capacity to
+ // allocate 'size' bytes of memory If it does not, it will attempt to
+ // allocate a new pool (which will be added to this one in a chain).
+ //
+ // If allocation fails (out of memory) this method will return null.
+ // If the return value is non-null, then callers should update any
+ // references they have to this current (possibly full) BumpPointerPool
+ // to instead point to the newly returned BumpPointerPool.
+ BumpPointerPool* ensureCapacity(size_t size)
+ {
+ void* allocationEnd = static_cast<char*>(m_current) + size;
+ ASSERT(allocationEnd > m_current); // check for overflow
+ if (allocationEnd <= static_cast<void*>(this))
+ return this;
+ return ensureCapacityCrossPool(this, size);
+ }
+
+ // alloc should only be called after calling ensureCapacity; as such
+ // alloc will never fail.
+ void* alloc(size_t size)
+ {
+ void* current = m_current;
+ void* allocationEnd = static_cast<char*>(current) + size;
+ ASSERT(allocationEnd > current); // check for overflow
+ ASSERT(allocationEnd <= static_cast<void*>(this));
+ m_current = allocationEnd;
+ return current;
+ }
+
+ // The dealloc method releases memory allocated using alloc. Memory
+ // must be released in a LIFO fashion, e.g. if the client calls alloc
+ // four times, returning pointer A, B, C, D, then the only valid order
+ // in which these may be deallocaed is D, C, B, A.
+ //
+ // The client may optionally skip some deallocations. In the example
+ // above, it would be valid to only explicitly dealloc C, A (D being
+ // dealloced along with C, B along with A).
+ //
+ // If pointer was not allocated from this pool (or pools) then dealloc
+ // will CRASH(). Callers should update any references they have to
+ // this current BumpPointerPool to instead point to the returned
+ // BumpPointerPool.
+ BumpPointerPool* dealloc(void* position)
+ {
+ if ((position >= m_start) && (position <= static_cast<void*>(this))) {
+ ASSERT(position <= m_current);
+ m_current = position;
+ return this;
+ }
+ return deallocCrossPool(this, position);
+ }
+
+private:
+ // Placement operator new, returns the last 'size' bytes of allocation for use as this.
+ void* operator new(size_t size, const PageAllocation& allocation)
+ {
+ ASSERT(size < allocation.size());
+ return reinterpret_cast<char*>(reinterpret_cast<intptr_t>(allocation.base()) + allocation.size()) - size;
+ }
+
+ BumpPointerPool(const PageAllocation& allocation)
+ : m_current(allocation.base())
+ , m_start(allocation.base())
+ , m_next(0)
+ , m_previous(0)
+ , m_allocation(allocation)
+ {
+ }
+
+ static BumpPointerPool* create(size_t minimumCapacity = 0)
+ {
+ // Add size of BumpPointerPool object, check for overflow.
+ minimumCapacity += sizeof(BumpPointerPool);
+ if (minimumCapacity < sizeof(BumpPointerPool))
+ return 0;
+
+ size_t poolSize = MINIMUM_BUMP_POOL_SIZE;
+ while (poolSize < minimumCapacity) {
+ poolSize <<= 1;
+ // The following if check relies on MINIMUM_BUMP_POOL_SIZE being a power of 2!
+ ASSERT(!(MINIMUM_BUMP_POOL_SIZE & (MINIMUM_BUMP_POOL_SIZE - 1)));
+ if (!poolSize)
+ return 0;
+ }
+
+ PageAllocation allocation = PageAllocation::allocate(poolSize);
+ if (!!allocation)
+ return new(allocation) BumpPointerPool(allocation);
+ return 0;
+ }
+
+ void shrink()
+ {
+ ASSERT(!m_previous);
+ m_current = m_start;
+ while (m_next) {
+ BumpPointerPool* nextNext = m_next->m_next;
+ m_next->destroy();
+ m_next = nextNext;
+ }
+ }
+
+ void destroy()
+ {
+ // Don't call deallocate on allocation, because allocation is *inside* allocation,
+ // and it will get deallocated before deallocate has completed!
+ PageAllocation allocation = m_allocation;
+ allocation.deallocate();
+ }
+
+ static BumpPointerPool* ensureCapacityCrossPool(BumpPointerPool* previousPool, size_t size)
+ {
+ // The pool passed should not have capacity, so we'll start with the next one.
+ ASSERT(previousPool);
+ ASSERT((static_cast<char*>(previousPool->m_current) + size) > previousPool->m_current); // check for overflow
+ ASSERT((static_cast<char*>(previousPool->m_current) + size) > static_cast<void*>(previousPool));
+ BumpPointerPool* pool = previousPool->m_next;
+
+ while (true) {
+ if (!pool) {
+ // We've run to the end; allocate a new pool.
+ pool = BumpPointerPool::create(size);
+ previousPool->m_next = pool;
+ pool->m_previous = previousPool;
+ return pool;
+ }
+
+ //
+ void* current = pool->m_current;
+ void* allocationEnd = static_cast<char*>(current) + size;
+ ASSERT(allocationEnd > current); // check for overflow
+ if (allocationEnd <= static_cast<void*>(pool))
+ return pool;
+ }
+ }
+
+ static BumpPointerPool* deallocCrossPool(BumpPointerPool* pool, void* position)
+ {
+ // Should only be called if position is not in the current pool.
+ ASSERT((position < pool->m_start) || (position > static_cast<void*>(pool)));
+
+ while (true) {
+ // Unwind the current pool to the start, move back in the chain to the previous pool.
+ pool->m_current = pool->m_start;
+ pool = pool->m_previous;
+
+ // position was nowhere in the chain!
+ if (!pool)
+ CRASH();
+
+ if ((position >= pool->m_start) && (position <= static_cast<void*>(pool))) {
+ ASSERT(position <= pool->m_current);
+ pool->m_current = position;
+ return pool;
+ }
+ }
+ }
+
+ void* m_current;
+ void* m_start;
+ BumpPointerPool* m_next;
+ BumpPointerPool* m_previous;
+ PageAllocation m_allocation;
+
+ friend class BumpPointerAllocator;
+};
+
+// A BumpPointerAllocator manages a set of BumpPointerPool objects, which
+// can be used for LIFO (stack like) allocation.
+//
+// To begin allocating using this class call startAllocator(). The result
+// of this method will be null if the initial pool allocation fails, or a
+// pointer to a BumpPointerPool object that can be used to perform
+// allocations. Whilst running no memory will be released until
+// stopAllocator() is called. At this point all allocations made through
+// this allocator will be reaped, and underlying memory may be freed.
+//
+// (In practice we will still hold on to the initial pool to allow allocation
+// to be quickly restared, but aditional pools will be freed).
+//
+// This allocator is non-renetrant, it is encumbant on the clients to ensure
+// startAllocator() is not called again until stopAllocator() has been called.
+class BumpPointerAllocator {
+public:
+ BumpPointerAllocator()
+ : m_head(0)
+ {
+ }
+
+ ~BumpPointerAllocator()
+ {
+ if (m_head)
+ m_head->destroy();
+ }
+
+ BumpPointerPool* startAllocator()
+ {
+ if (!m_head)
+ m_head = BumpPointerPool::create();
+ return m_head;
+ }
+
+ void stopAllocator()
+ {
+ if (m_head)
+ m_head->shrink();
+ }
+
+private:
+ BumpPointerPool* m_head;
+};
+
+}
+
+using WTF::BumpPointerAllocator;
+
+#endif // BumpPointerAllocator_h
diff --git a/JavaScriptCore/yarr/RegexInterpreter.cpp b/JavaScriptCore/yarr/RegexInterpreter.cpp
index 4fb5f92..d50c6c8 100644
--- a/JavaScriptCore/yarr/RegexInterpreter.cpp
+++ b/JavaScriptCore/yarr/RegexInterpreter.cpp
@@ -28,6 +28,7 @@
#include "RegexCompiler.h"
#include "RegexPattern.h"
+#include <wtf/BumpPointerAllocator.h>
#ifndef NDEBUG
#include <stdio.h>
@@ -104,12 +105,16 @@ public:
DisjunctionContext* allocDisjunctionContext(ByteDisjunction* disjunction)
{
- return new(malloc(sizeof(DisjunctionContext) + (disjunction->m_frameSize - 1) * sizeof(uintptr_t))) DisjunctionContext();
+ size_t size = sizeof(DisjunctionContext) - sizeof(uintptr_t) + disjunction->m_frameSize * sizeof(uintptr_t);
+ allocatorPool = allocatorPool->ensureCapacity(size);
+ if (!allocatorPool)
+ CRASH();
+ return new(allocatorPool->alloc(size)) DisjunctionContext();
}
void freeDisjunctionContext(DisjunctionContext* context)
{
- free(context);
+ allocatorPool = allocatorPool->dealloc(context);
}
struct ParenthesesDisjunctionContext
@@ -150,12 +155,16 @@ public:
ParenthesesDisjunctionContext* allocParenthesesDisjunctionContext(ByteDisjunction* disjunction, int* output, ByteTerm& term)
{
- return new(malloc(sizeof(ParenthesesDisjunctionContext) + (((term.atom.parenthesesDisjunction->m_numSubpatterns << 1) - 1) * sizeof(int)) + sizeof(DisjunctionContext) + (disjunction->m_frameSize - 1) * sizeof(uintptr_t))) ParenthesesDisjunctionContext(output, term);
+ size_t size = sizeof(ParenthesesDisjunctionContext) - sizeof(int) + (term.atom.parenthesesDisjunction->m_numSubpatterns << 1) * sizeof(int) + sizeof(DisjunctionContext) - sizeof(uintptr_t) + disjunction->m_frameSize * sizeof(uintptr_t);
+ allocatorPool = allocatorPool->ensureCapacity(size);
+ if (!allocatorPool)
+ CRASH();
+ return new(allocatorPool->alloc(size)) ParenthesesDisjunctionContext(output, term);
}
void freeParenthesesDisjunctionContext(ParenthesesDisjunctionContext* context)
{
- free(context);
+ allocatorPool = allocatorPool->dealloc(context);
}
class InputStream {
@@ -1190,6 +1199,10 @@ public:
int interpret()
{
+ allocatorPool = pattern->m_allocator->startAllocator();
+ if (!allocatorPool)
+ CRASH();
+
for (unsigned i = 0; i < ((pattern->m_body->m_numSubpatterns + 1) << 1); ++i)
output[i] = -1;
@@ -1202,6 +1215,8 @@ public:
freeDisjunctionContext(context);
+ pattern->m_allocator->stopAllocator();
+
return output[0];
}
@@ -1209,6 +1224,7 @@ public:
: pattern(pattern)
, output(output)
, input(inputChar, start, length)
+ , allocatorPool(0)
{
}
@@ -1216,6 +1232,7 @@ private:
BytecodePattern *pattern;
int* output;
InputStream input;
+ BumpPointerPool* allocatorPool;
};
@@ -1238,13 +1255,13 @@ public:
m_currentAlternativeIndex = 0;
}
- PassOwnPtr<BytecodePattern> compile()
+ PassOwnPtr<BytecodePattern> compile(BumpPointerAllocator* allocator)
{
regexBegin(m_pattern.m_numSubpatterns, m_pattern.m_body->m_callFrameSize);
emitDisjunction(m_pattern.m_body);
regexEnd();
- return adoptPtr(new BytecodePattern(m_bodyDisjunction.release(), m_allParenthesesInfo, m_pattern));
+ return adoptPtr(new BytecodePattern(m_bodyDisjunction.release(), m_allParenthesesInfo, m_pattern, allocator));
}
void checkInput(unsigned count)
@@ -1574,7 +1591,7 @@ private:
};
-PassOwnPtr<BytecodePattern> byteCompileRegex(const UString& patternString, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline)
+PassOwnPtr<BytecodePattern> byteCompileRegex(const UString& patternString, unsigned& numSubpatterns, const char*& error, BumpPointerAllocator* allocator, bool ignoreCase, bool multiline)
{
RegexPattern pattern(ignoreCase, multiline);
@@ -1583,7 +1600,7 @@ PassOwnPtr<BytecodePattern> byteCompileRegex(const UString& patternString, unsig
numSubpatterns = pattern.m_numSubpatterns;
- return ByteCompiler(pattern).compile();
+ return ByteCompiler(pattern).compile(allocator);
}
int interpretRegex(BytecodePattern* regex, const UChar* input, unsigned start, unsigned length, int* output)
diff --git a/JavaScriptCore/yarr/RegexInterpreter.h b/JavaScriptCore/yarr/RegexInterpreter.h
index af63a7b..4da9cc5 100644
--- a/JavaScriptCore/yarr/RegexInterpreter.h
+++ b/JavaScriptCore/yarr/RegexInterpreter.h
@@ -33,6 +33,11 @@
#include <wtf/PassOwnPtr.h>
#include <wtf/unicode/Unicode.h>
+namespace WTF {
+class BumpPointerAllocator;
+}
+using WTF::BumpPointerAllocator;
+
namespace JSC { namespace Yarr {
class ByteDisjunction;
@@ -293,10 +298,11 @@ public:
};
struct BytecodePattern : FastAllocBase {
- BytecodePattern(PassOwnPtr<ByteDisjunction> body, Vector<ByteDisjunction*> allParenthesesInfo, RegexPattern& pattern)
+ BytecodePattern(PassOwnPtr<ByteDisjunction> body, Vector<ByteDisjunction*> allParenthesesInfo, RegexPattern& pattern, BumpPointerAllocator* allocator)
: m_body(body)
, m_ignoreCase(pattern.m_ignoreCase)
, m_multiline(pattern.m_multiline)
+ , m_allocator(allocator)
{
newlineCharacterClass = pattern.newlineCharacterClass();
wordcharCharacterClass = pattern.wordcharCharacterClass();
@@ -318,7 +324,10 @@ struct BytecodePattern : FastAllocBase {
OwnPtr<ByteDisjunction> m_body;
bool m_ignoreCase;
bool m_multiline;
-
+ // Each BytecodePattern is associated with a RegExp, each RegExp is associated
+ // with a JSGlobalData. Cache a pointer to out JSGlobalData's m_regexAllocator.
+ BumpPointerAllocator* m_allocator;
+
CharacterClass* newlineCharacterClass;
CharacterClass* wordcharCharacterClass;
private:
@@ -326,7 +335,7 @@ private:
Vector<CharacterClass*> m_userCharacterClasses;
};
-PassOwnPtr<BytecodePattern> byteCompileRegex(const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase = false, bool multiline = false);
+PassOwnPtr<BytecodePattern> byteCompileRegex(const UString& pattern, unsigned& numSubpatterns, const char*& error, BumpPointerAllocator*, bool ignoreCase = false, bool multiline = false);
int interpretRegex(BytecodePattern* v_regex, const UChar* input, unsigned start, unsigned length, int* output);
} } // namespace JSC::Yarr
diff --git a/JavaScriptGlue/ChangeLog b/JavaScriptGlue/ChangeLog
index fcdd934..17aaffe 100644
--- a/JavaScriptGlue/ChangeLog
+++ b/JavaScriptGlue/ChangeLog
@@ -1,3 +1,15 @@
+2010-07-27 Gavin Barraclough <barraclough at apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 42621 - Add a bump allocator for the YARR interpreter
+
+ The regex engine requires lifo allocation, however currently uses the general purpose
+ malloc/free memory allocation. A simple bump pointer allocator should provide a lower
+ overhead allocation solution.
+
+ * ForwardingHeaders/wtf/BumpPointerAllocator.h: Added.
+
2010-07-26 Gavin Barraclough <barraclough at apple.com>
Reviewed by Oliver Hunt.
diff --git a/JavaScriptGlue/ForwardingHeaders/wtf/BumpPointerAllocator.h b/JavaScriptGlue/ForwardingHeaders/wtf/BumpPointerAllocator.h
new file mode 100644
index 0000000..f685611
--- /dev/null
+++ b/JavaScriptGlue/ForwardingHeaders/wtf/BumpPointerAllocator.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/BumpPointerAllocator.h>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 90622e2..638d50a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,15 @@
+2010-07-27 Gavin Barraclough <barraclough at apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 42621 - Add a bump allocator for the YARR interpreter
+
+ The regex engine requires lifo allocation, however currently uses the general purpose
+ malloc/free memory allocation. A simple bump pointer allocator should provide a lower
+ overhead allocation solution.
+
+ * ForwardingHeaders/wtf/BumpPointerAllocator.h: Added.
+
2010-07-27 Pavel Feldman <pfeldman at chromium.org>
Reviewed by Joseph Pecoraro.
diff --git a/WebCore/ForwardingHeaders/wtf/BumpPointerAllocator.h b/WebCore/ForwardingHeaders/wtf/BumpPointerAllocator.h
new file mode 100644
index 0000000..25acbf4
--- /dev/null
+++ b/WebCore/ForwardingHeaders/wtf/BumpPointerAllocator.h
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_BumpPointerAllocator_h
+#define WebCore_FWD_BumpPointerAllocator_h
+#include <JavaScriptCore/BumpPointerAllocator.h>
+#endif
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list