[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:43:16 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 70c0cc9270f19cf93923eda030d8c7e3ead27458
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Aug 5 00:18:58 2010 +0000

    JavaScriptCore: Bug 43515 - Fix small design issues with PageAllocation, split out PageReservation.
    
    Reviewed by Sam Weinig.
    
    The PageAllocation class has a number of issues:
    * Changes in bug #43269 accidentally switched SYMBIAN over to use malloc/free to allocate
      blocks of memory for the GC heap, instead of allocating RChunks.  Revert this change in
      behaviour.
    * In order for PageAllocation to work correctly on WinCE we should be decommitting memory
      before deallocating.  In order to simplify understanding the expected state at deallocate,
      split behaviour out into PageAllocation and PageReservation classes.  Require that all
      memory be decommitted before calling deallocate on a PageReservation, add asserts to
      enforce this.
    * add many missing asserts.
    * inline more functions.
    * remove ability to create sub-PageAllocations from an existing PageAllocations object -
      this presented an interface that would allow sub regions to be deallocated, which would
      not have provided expected behaviour.
    * remove writable/executable arguments to commit, this value can be cached at the point
      the memory is reserved.
    * remove writable/executable arguments to allocateAligned, protection other than RW is not
      supported.
    * add missing checks for overflow & failed allocation to mmap path through allocateAligned.
    
    * JavaScriptCore.xcodeproj/project.pbxproj:
    * jit/ExecutableAllocator.cpp:
    (JSC::ExecutableAllocator::intializePageSize):
    * jit/ExecutableAllocator.h:
    (JSC::ExecutablePool::Allocation::Allocation):
    (JSC::ExecutablePool::Allocation::base):
    (JSC::ExecutablePool::Allocation::size):
    (JSC::ExecutablePool::Allocation::operator!):
    * jit/ExecutableAllocatorFixedVMPool.cpp:
    (JSC::FixedVMPoolAllocator::reuse):
    (JSC::FixedVMPoolAllocator::coalesceFreeSpace):
    (JSC::FixedVMPoolAllocator::FixedVMPoolAllocator):
    (JSC::FixedVMPoolAllocator::alloc):
    (JSC::FixedVMPoolAllocator::free):
    (JSC::FixedVMPoolAllocator::allocInternal):
    * runtime/AlignedMemoryAllocator.h:
    (JSC::::allocate):
    (JSC::::AlignedMemoryAllocator):
    * runtime/Collector.cpp:
    (JSC::Heap::allocateBlock):
    * runtime/Collector.h:
    * wtf/PageAllocation.cpp:
    * wtf/PageAllocation.h:
    (WTF::PageAllocation::operator!):
    (WTF::PageAllocation::allocate):
    (WTF::PageAllocation::allocateAt):
    (WTF::PageAllocation::allocateAligned):
    (WTF::PageAllocation::deallocate):
    (WTF::PageAllocation::pageSize):
    (WTF::PageAllocation::systemAllocate):
    (WTF::PageAllocation::systemAllocateAt):
    (WTF::PageAllocation::systemAllocateAligned):
    (WTF::PageAllocation::systemDeallocate):
    (WTF::PageAllocation::systemPageSize):
    * wtf/PageReservation.h: Copied from JavaScriptCore/wtf/PageAllocation.h.
    (WTF::PageReservation::PageReservation):
    (WTF::PageReservation::commit):
    (WTF::PageReservation::decommit):
    (WTF::PageReservation::reserve):
    (WTF::PageReservation::reserveAt):
    (WTF::PageReservation::deallocate):
    (WTF::PageReservation::systemCommit):
    (WTF::PageReservation::systemDecommit):
    (WTF::PageReservation::systemReserve):
    (WTF::PageReservation::systemReserveAt):
    * wtf/Platform.h:
    
    JavaScriptGlue: Bug 43515 - Fix small design issues with PageAllocation, split out PageReservation.
    (add forwarding headers)
    
    Reviewed by Sam Weinig.
    
    * ForwardingHeaders/wtf/Bitmap.h: Added.
    * ForwardingHeaders/wtf/PageReservation.h: Added.
    
    WebCore: Bug 43515 - Fix small design issues with PageAllocation, split out PageReservation.
    (add forwarding headers)
    
    Reviewed by Sam Weinig.
    
    * ForwardingHeaders/wtf/Bitmap.h: Added.
    * ForwardingHeaders/wtf/PageReservation.h: Added.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64695 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 6889efc..59c3e8a 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,76 @@
+2010-08-04  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Bug 43515 - Fix small design issues with PageAllocation, split out PageReservation.
+
+        The PageAllocation class has a number of issues:
+        * Changes in bug #43269 accidentally switched SYMBIAN over to use malloc/free to allocate
+          blocks of memory for the GC heap, instead of allocating RChunks.  Revert this change in
+          behaviour.
+        * In order for PageAllocation to work correctly on WinCE we should be decommitting memory
+          before deallocating.  In order to simplify understanding the expected state at deallocate,
+          split behaviour out into PageAllocation and PageReservation classes.  Require that all
+          memory be decommitted before calling deallocate on a PageReservation, add asserts to
+          enforce this.
+        * add many missing asserts.
+        * inline more functions.
+        * remove ability to create sub-PageAllocations from an existing PageAllocations object -
+          this presented an interface that would allow sub regions to be deallocated, which would
+          not have provided expected behaviour.
+        * remove writable/executable arguments to commit, this value can be cached at the point
+          the memory is reserved.
+        * remove writable/executable arguments to allocateAligned, protection other than RW is not
+          supported.
+        * add missing checks for overflow & failed allocation to mmap path through allocateAligned.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * jit/ExecutableAllocator.cpp:
+        (JSC::ExecutableAllocator::intializePageSize):
+        * jit/ExecutableAllocator.h:
+        (JSC::ExecutablePool::Allocation::Allocation):
+        (JSC::ExecutablePool::Allocation::base):
+        (JSC::ExecutablePool::Allocation::size):
+        (JSC::ExecutablePool::Allocation::operator!):
+        * jit/ExecutableAllocatorFixedVMPool.cpp:
+        (JSC::FixedVMPoolAllocator::reuse):
+        (JSC::FixedVMPoolAllocator::coalesceFreeSpace):
+        (JSC::FixedVMPoolAllocator::FixedVMPoolAllocator):
+        (JSC::FixedVMPoolAllocator::alloc):
+        (JSC::FixedVMPoolAllocator::free):
+        (JSC::FixedVMPoolAllocator::allocInternal):
+        * runtime/AlignedMemoryAllocator.h:
+        (JSC::::allocate):
+        (JSC::::AlignedMemoryAllocator):
+        * runtime/Collector.cpp:
+        (JSC::Heap::allocateBlock):
+        * runtime/Collector.h:
+        * wtf/PageAllocation.cpp:
+        * wtf/PageAllocation.h:
+        (WTF::PageAllocation::operator!):
+        (WTF::PageAllocation::allocate):
+        (WTF::PageAllocation::allocateAt):
+        (WTF::PageAllocation::allocateAligned):
+        (WTF::PageAllocation::deallocate):
+        (WTF::PageAllocation::pageSize):
+        (WTF::PageAllocation::systemAllocate):
+        (WTF::PageAllocation::systemAllocateAt):
+        (WTF::PageAllocation::systemAllocateAligned):
+        (WTF::PageAllocation::systemDeallocate):
+        (WTF::PageAllocation::systemPageSize):
+        * wtf/PageReservation.h: Copied from JavaScriptCore/wtf/PageAllocation.h.
+        (WTF::PageReservation::PageReservation):
+        (WTF::PageReservation::commit):
+        (WTF::PageReservation::decommit):
+        (WTF::PageReservation::reserve):
+        (WTF::PageReservation::reserveAt):
+        (WTF::PageReservation::deallocate):
+        (WTF::PageReservation::systemCommit):
+        (WTF::PageReservation::systemDecommit):
+        (WTF::PageReservation::systemReserve):
+        (WTF::PageReservation::systemReserveAt):
+        * wtf/Platform.h:
+
 2010-08-04  Sheriff Bot  <webkit.review.bot at gmail.com>
 
         Unreviewed, rolling out r64655.
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 086d8e3..4f3d640 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -214,6 +214,7 @@
 		868BFA17117CF19900B908B1 /* WTFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 868BFA15117CF19900B908B1 /* WTFString.cpp */; };
 		868BFA18117CF19900B908B1 /* WTFString.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA16117CF19900B908B1 /* WTFString.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		868BFA60117D048200B908B1 /* StaticConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA5F117D048200B908B1 /* StaticConstructors.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		8690231512092D5C00630AF9 /* PageReservation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8690231412092D5C00630AF9 /* PageReservation.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		8698B86910D44D9400D8D01B /* StringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8698B86810D44D9400D8D01B /* StringBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		8698BB3910D86BAF00D8D01B /* UStringImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 8698BB3710D86BAF00D8D01B /* UStringImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		869D04AF1193B54D00803475 /* CachedTranscendentalFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -793,6 +794,7 @@
 		868BFA15117CF19900B908B1 /* WTFString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WTFString.cpp; path = text/WTFString.cpp; sourceTree = "<group>"; };
 		868BFA16117CF19900B908B1 /* WTFString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WTFString.h; path = text/WTFString.h; sourceTree = "<group>"; };
 		868BFA5F117D048200B908B1 /* StaticConstructors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticConstructors.h; sourceTree = "<group>"; };
+		8690231412092D5C00630AF9 /* PageReservation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageReservation.h; sourceTree = "<group>"; };
 		8698B86810D44D9400D8D01B /* StringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringBuilder.h; sourceTree = "<group>"; };
 		8698BB3710D86BAF00D8D01B /* UStringImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UStringImpl.h; sourceTree = "<group>"; };
 		869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedTranscendentalFunction.h; sourceTree = "<group>"; };
@@ -1460,6 +1462,7 @@
 				440B7AED0FAF7FCB0073323E /* OwnPtrCommon.h */,
 				8627E5E911F1281900A313B5 /* PageAllocation.cpp */,
 				8627E5EA11F1281900A313B5 /* PageAllocation.h */,
+				8690231412092D5C00630AF9 /* PageReservation.h */,
 				44DD48520FAEA85000D6B4EB /* PassOwnPtr.h */,
 				6580F795094070560082C219 /* PassRefPtr.h */,
 				65D6D87E09B5A32E0002E4D7 /* Platform.h */,
@@ -2103,6 +2106,7 @@
 				BC18C44A0E16F5CD00B34460 /* OwnPtr.h in Headers */,
 				4409D8470FAF80A200523B87 /* OwnPtrCommon.h in Headers */,
 				8627E5EC11F1281900A313B5 /* PageAllocation.h in Headers */,
+				8690231512092D5C00630AF9 /* PageReservation.h in Headers */,
 				BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */,
 				93052C350FB792190048FDC3 /* ParserArena.h in Headers */,
 				44DD48530FAEA85000D6B4EB /* PassOwnPtr.h in Headers */,
@@ -2303,7 +2307,6 @@
 			isa = PBXProject;
 			buildConfigurationList = 149C277108902AFE008A9EFC /* Build configuration list for PBXProject "JavaScriptCore" */;
 			compatibilityVersion = "Xcode 2.4";
-			developmentRegion = English;
 			hasScannedForEncodings = 1;
 			knownRegions = (
 				English,
diff --git a/JavaScriptCore/jit/ExecutableAllocator.cpp b/JavaScriptCore/jit/ExecutableAllocator.cpp
index bf0a0d8..e3525f5 100644
--- a/JavaScriptCore/jit/ExecutableAllocator.cpp
+++ b/JavaScriptCore/jit/ExecutableAllocator.cpp
@@ -45,7 +45,7 @@ void ExecutableAllocator::intializePageSize()
     // for moving memory model limitation
     ExecutableAllocator::pageSize = 256 * 1024;
 #else
-    ExecutableAllocator::pageSize = PageAllocation::pagesize();
+    ExecutableAllocator::pageSize = PageAllocation::pageSize();
 #endif
 }
 
diff --git a/JavaScriptCore/jit/ExecutableAllocator.h b/JavaScriptCore/jit/ExecutableAllocator.h
index be4f9c7..b712dfd 100644
--- a/JavaScriptCore/jit/ExecutableAllocator.h
+++ b/JavaScriptCore/jit/ExecutableAllocator.h
@@ -85,11 +85,28 @@ inline size_t roundUpAllocationSize(size_t request, size_t granularity)
 namespace JSC {
 
 class ExecutablePool : public RefCounted<ExecutablePool> {
-private:
+public:
+#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND)
     typedef PageAllocation Allocation;
+#else
+    class Allocation {
+    public:
+        Allocation(void* base, size_t size)
+            : m_base(base)
+            , m_size(size)
+        {
+        }
+        void* base() { return m_base; }
+        size_t size() { return m_size; }
+        bool operator!() const { return !m_base; }
+
+    private:
+        void* m_base;
+        size_t m_size;
+    };
+#endif
     typedef Vector<Allocation, 2> AllocationList;
 
-public:
     static PassRefPtr<ExecutablePool> create(size_t n);
 
     void* alloc(size_t n)
diff --git a/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp b/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
index acc4ee5..f05e919 100644
--- a/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
+++ b/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
@@ -35,6 +35,7 @@
 #include <sys/mman.h>
 #include <unistd.h>
 #include <wtf/AVLTree.h>
+#include <wtf/PageReservation.h>
 #include <wtf/VMTags.h>
 
 #if CPU(X86_64)
@@ -131,12 +132,12 @@ class FixedVMPoolAllocator
 
     void reuse(void* position, size_t size)
     {
-        bool okay = m_allocation.commit(position, size, EXECUTABLE_POOL_WRITABLE, true);
+        bool okay = m_allocation.commit(position, size);
         ASSERT_UNUSED(okay, okay);
     }
 
     // All addition to the free list should go through this method, rather than
-    // calling insert directly, to avoid multiple entries beging added with the
+    // calling insert directly, to avoid multiple entries being added with the
     // same key.  All nodes being added should be singletons, they should not
     // already be a part of a chain.
     void addToFreeList(FreeListEntry* entry)
@@ -155,7 +156,7 @@ class FixedVMPoolAllocator
     }
 
     // We do not attempt to coalesce addition, which may lead to fragmentation;
-    // instead we periodically perform a sweep to try to coalesce neigboring
+    // instead we periodically perform a sweep to try to coalesce neighboring
     // entries in m_freeList.  Presently this is triggered at the point 16MB
     // of memory has been released.
     void coalesceFreeSpace()
@@ -168,7 +169,7 @@ class FixedVMPoolAllocator
         for (FreeListEntry* entry; (entry = *iter); ++iter) {
             // Each entry in m_freeList might correspond to multiple
             // free chunks of memory (of the same size).  Walk the chain
-            // (this is likely of couse only be one entry long!) adding
+            // (this is likely of course only be one entry long!) adding
             // each entry to the Vector (at reseting the next in chain
             // pointer to separate each node out).
             FreeListEntry* next;
@@ -283,16 +284,16 @@ public:
         //
         // But! - as a temporary workaround for some plugin problems (rdar://problem/6812854),
         // for now instead of 2^26 bits of ASLR lets stick with 25 bits of randomization plus
-        // 2^24, which should put up somewhere in the middle of usespace (in the address range
+        // 2^24, which should put up somewhere in the middle of userspace (in the address range
         // 0x200000000000 .. 0x5fffffffffff).
 #if VM_POOL_ASLR
         intptr_t randomLocation = 0;
         randomLocation = arc4random() & ((1 << 25) - 1);
         randomLocation += (1 << 24);
         randomLocation <<= 21;
-        m_allocation = PageAllocation::reserveAt(reinterpret_cast<void*>(randomLocation), false, totalHeapSize, PageAllocation::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
+        m_allocation = PageReservation::reserveAt(reinterpret_cast<void*>(randomLocation), false, totalHeapSize, PageAllocation::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
 #else
-        m_allocation = PageAllocation::reserve(totalHeapSize, PageAllocation::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
+        m_allocation = PageReservation::reserve(totalHeapSize, PageAllocation::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
 #endif
 
         if (!!m_allocation)
@@ -303,12 +304,12 @@ public:
 #endif
     }
 
-    PageAllocation alloc(size_t size)
+    ExecutablePool::Allocation alloc(size_t size)
     {
-        return PageAllocation(allocInternal(size), size, m_allocation);
+        return ExecutablePool::Allocation(allocInternal(size), size);
     }
 
-    void free(PageAllocation allocation)
+    void free(ExecutablePool::Allocation allocation)
     {
         void* pointer = allocation.base();
         size_t size = allocation.size();
@@ -356,12 +357,12 @@ private:
             result = m_commonSizedAllocations.last();
             m_commonSizedAllocations.removeLast();
         } else {
-            // Serach m_freeList for a suitable sized chunk to allocate memory from.
+            // Search m_freeList for a suitable sized chunk to allocate memory from.
             FreeListEntry* entry = m_freeList.search(size, m_freeList.GREATER_EQUAL);
 
             // This is bad news.
             if (!entry) {
-                // Errk!  Lets take a last-ditch desparation attempt at defragmentation...
+                // Errk!  Lets take a last-ditch desperation attempt at defragmentation...
                 coalesceFreeSpace();
                 // Did that free up a large enough chunk?
                 entry = m_freeList.search(size, m_freeList.GREATER_EQUAL);
@@ -423,7 +424,7 @@ private:
     // This is used for housekeeping, to trigger defragmentation of the freed lists.
     size_t m_countFreedSinceLastCoalesce;
 
-    PageAllocation m_allocation;
+    PageReservation m_allocation;
 };
 
 void ExecutableAllocator::intializePageSize()
diff --git a/JavaScriptCore/runtime/AlignedMemoryAllocator.h b/JavaScriptCore/runtime/AlignedMemoryAllocator.h
index 2451bf3..e682eb3 100644
--- a/JavaScriptCore/runtime/AlignedMemoryAllocator.h
+++ b/JavaScriptCore/runtime/AlignedMemoryAllocator.h
@@ -21,7 +21,7 @@
 #define AlignedMemoryAllocator_h
 
 #include <wtf/Bitmap.h>
-#include <wtf/PageAllocation.h>
+#include <wtf/PageReservation.h>
 
 namespace JSC {
 
@@ -42,7 +42,7 @@ struct AlignedMemoryAllocatorConstants {
 template<size_t blockSize> class AlignedMemory;
 template<size_t blockSize> class AlignedMemoryAllocator;
 
-#if HAVE(ALIGNED_ALLOCATE)
+#if HAVE(PAGE_ALLOCATE_ALIGNED)
 
 template<size_t blockSize>
 class AlignedMemoryAllocator;
@@ -76,7 +76,7 @@ inline void AlignedMemoryAllocator<blockSize>::destroy()
 template<size_t blockSize>
 inline AlignedMemory<blockSize> AlignedMemoryAllocator<blockSize>::allocate()
 {
-    return AlignedMemory<blockSize>(PageAllocation::allocateAligned(blockSize));
+    return AlignedMemory<blockSize>(PageAllocation::allocateAligned(blockSize, PageAllocation::JSGCHeapPages));
 }
 
 template<size_t blockSize>
@@ -128,7 +128,7 @@ private:
     static const size_t reservationSize = AlignedMemoryAllocatorConstants::virtualMemoryReservation;
     static const size_t bitmapSize = reservationSize / blockSize;
 
-    PageAllocation m_reservation;
+    PageReservation m_reservation;
     size_t m_nextFree;
     uintptr_t m_reservationBase;
     WTF::Bitmap<bitmapSize> m_bitmap;
@@ -136,7 +136,7 @@ private:
 
 template<size_t blockSize>
 AlignedMemoryAllocator<blockSize>::AlignedMemoryAllocator()
-    : m_reservation(PageAllocation::reserve(reservationSize + blockSize))
+    : m_reservation(PageReservation::reserve(reservationSize + blockSize, PageAllocation::JSGCHeapPages))
     , m_nextFree(0)
 {
     // check that blockSize and reservationSize are powers of two
@@ -145,7 +145,7 @@ AlignedMemoryAllocator<blockSize>::AlignedMemoryAllocator()
 
     // check that blockSize is a multiple of pageSize and that
     // reservationSize is a multiple of blockSize
-    ASSERT(!(blockSize & (PageAllocation::pagesize() - 1)));
+    ASSERT(!(blockSize & (PageAllocation::pageSize() - 1)));
     ASSERT(!(reservationSize & (blockSize - 1)));
 
     ASSERT(m_reservation);
diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index 93649dd..4bf73a3 100644
--- a/JavaScriptCore/runtime/Collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -191,6 +191,8 @@ NEVER_INLINE CollectorBlock* Heap::allocateBlock()
 {
     AlignedBlock allocation = m_blockallocator.allocate();
     CollectorBlock* block = static_cast<CollectorBlock*>(allocation.base());
+    if (!block)
+        CRASH();
 
     // Initialize block.
 
diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h
index 726a273..7e4051f 100644
--- a/JavaScriptCore/runtime/Collector.h
+++ b/JavaScriptCore/runtime/Collector.h
@@ -59,7 +59,7 @@ namespace JSC {
 #if OS(WINCE) || OS(SYMBIAN)
     const size_t BLOCK_SIZE = 64 * 1024; // 64k
 #else
-    const size_t BLOCK_SIZE = 64 * 4096; // 256k
+    const size_t BLOCK_SIZE = 256 * 1024; // 256k
 #endif
 
     typedef AlignedMemoryAllocator<BLOCK_SIZE> AlignedAllocator;
diff --git a/JavaScriptCore/wtf/PageAllocation.cpp b/JavaScriptCore/wtf/PageAllocation.cpp
index 4cf2ea9..01cfbc1 100644
--- a/JavaScriptCore/wtf/PageAllocation.cpp
+++ b/JavaScriptCore/wtf/PageAllocation.cpp
@@ -26,206 +26,10 @@
 
 #include "config.h"
 #include "PageAllocation.h"
-
-#if HAVE(ERRNO_H)
-#include <errno.h>
-#endif
-
-#if HAVE(MMAP)
-#include <sys/mman.h>
-#include <unistd.h>
-#endif
-
-#if OS(WINDOWS)
-#include "windows.h"
-#endif
-
-#if OS(SYMBIAN)
-#include <e32hal.h>
-#endif
+#include "PageReservation.h"
 
 namespace WTF {
 
-#if HAVE(MMAP)
-
-bool PageAllocation::commit(void* start, size_t size, bool, bool) const
-{
-#if HAVE(MADV_FREE_REUSE)
-    while (madvise(start, size, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { }
-#else
-    UNUSED_PARAM(start);
-    UNUSED_PARAM(size);
-#endif
-    return true;
-}
-
-void PageAllocation::decommit(void* start, size_t size) const
-{
-#if HAVE(MADV_FREE_REUSE)
-    while (madvise(start, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
-#elif HAVE(MADV_FREE)
-    while (madvise(start, size, MADV_FREE) == -1 && errno == EAGAIN) { }
-#elif HAVE(MADV_DONTNEED)
-    while (madvise(start, size, MADV_DONTNEED) == -1 && errno == EAGAIN) { }
-#else
-    UNUSED_PARAM(start);
-    UNUSED_PARAM(size);
-#endif
-}
-
-PageAllocation PageAllocation::allocate(size_t size, Usage usage, bool writable, bool executable)
-{
-    return allocateAt(0, false, size, usage, writable, executable);
-}
-
-PageAllocation PageAllocation::reserve(size_t size, Usage usage, bool writable, bool executable)
-{
-    return reserveAt(0, false, size, usage, writable, executable);
-}
-
-PageAllocation PageAllocation::allocateAt(void* address, bool fixed, size_t size, Usage usage, bool writable, bool executable)
-{
-    int flags = MAP_PRIVATE | MAP_ANON;
-    if (fixed)
-        flags |= MAP_FIXED;
-
-    int protection = PROT_READ;
-    if (writable)
-        protection |= PROT_WRITE;
-    if (executable)
-        protection |= PROT_EXEC;
-
-    void* base = mmap(address, size, protection, flags, usage, 0);
-    if (base == MAP_FAILED)
-        base = 0;
-
-    return PageAllocation(base, size);
-}
-
-PageAllocation PageAllocation::reserveAt(void* address, bool fixed, size_t size, Usage usage, bool writable, bool executable)
-{
-    PageAllocation result = allocateAt(address, fixed, size, usage, writable, executable);
-    if (!!result)
-        result.decommit(result.base(), size);
-    return result;
-}
-
-void PageAllocation::deallocate()
-{
-    int result = munmap(m_base, m_size);
-    ASSERT_UNUSED(result, !result);
-    m_base = 0;
-}
-
-size_t PageAllocation::pagesize()
-{
-    static size_t size = 0;
-    if (!size)
-        size = getpagesize();
-    return size;
-}
-
-#elif HAVE(VIRTUALALLOC)
-
-static DWORD protection(bool writable, bool executable)
-{
-    if (executable)
-        return writable ?PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
-    return writable ?PAGE_READWRITE : PAGE_READONLY;
-}
-
-bool PageAllocation::commit(void* start, size_t size, bool writable, bool executable) const
-{
-    return VirtualAlloc(start, size, MEM_COMMIT, protection(writable, executable)) == start;
-}
-
-void PageAllocation::decommit(void* start, size_t size) const
-{
-    VirtualFree(start, size, MEM_DECOMMIT);
-}
-
-PageAllocation PageAllocation::allocate(size_t size, Usage, bool writable, bool executable)
-{
-    return PageAllocation(VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, protection(writable, executable)), size);
-}
-
-PageAllocation PageAllocation::reserve(size_t size, Usage usage, bool writable, bool executable)
-{
-    return PageAllocation(VirtualAlloc(0, size, MEM_RESERVE, protection(writable, executable)), size);
-}
-
-void PageAllocation::deallocate()
-{
-    VirtualFree(m_base, 0, MEM_RELEASE); 
-    m_base = 0;
-}
-
-size_t PageAllocation::pagesize()
-{
-    static size_t size = 0;
-    if (!size) {
-        SYSTEM_INFO system_info;
-        GetSystemInfo(&system_info);
-        size = system_info.dwPageSize;
-    }
-    return size;
-}
-
-#elif OS(SYMBIAN)
-
-bool PageAllocation::commit(void* start, size_t size, bool writable, bool executable) const
-{
-    if (m_chunk) {
-        intptr_t offset = reinterpret_cast<intptr_t>(base()) - reinterpret_cast<intptr_t>(start);
-        m_chunk->Commit(offset, size);
-    }
-    return true;
-}
-
-void PageAllocation::decommit(void* start, size_t size) const
-{
-    if (m_chunk) {
-        intptr_t offset = reinterpret_cast<intptr_t>(base()) - reinterpret_cast<intptr_t>(start);
-        m_chunk->Decommit(offset, size);
-    }
-}
-
-PageAllocation PageAllocation::allocate(size_t size, Usage usage, bool writable, bool executable)
-{
-    if (!executable)
-        return PageAllocation(fastMalloc(size), size, 0);
-    RChunk* rchunk = new RChunk();
-    TInt errorCode = rchunk->CreateLocalCode(size, size);
-    return PageAllocation(rchunk->Base(), size, rchunk);
-}
-
-PageAllocation PageAllocation::reserve(size_t size, Usage usage, bool writable, bool executable)
-{
-    if (!executable)
-        return PageAllocation(fastMalloc(size), size, 0);
-    RChunk* rchunk = new RChunk();
-    TInt errorCode = rchunk->CreateLocalCode(0, size);
-    return PageAllocation(rchunk->Base(), size, rchunk);
-}
-
-void PageAllocation::deallocate()
-{
-    if (m_chunk) {
-        m_chunk->Close();
-        delete m_chunk;
-    } else
-        fastFree(m_base);
-    m_base = 0;
-}
-
-size_t PageAllocation::pagesize()
-{
-    static TInt page_size = 0;
-    if (!page_size)
-        UserHal::PageSizeInBytes(page_size);
-    return page_size;
-}
-
-#endif
+size_t PageAllocation::s_pageSize = 0;
 
 }
diff --git a/JavaScriptCore/wtf/PageAllocation.h b/JavaScriptCore/wtf/PageAllocation.h
index 76e96f9..7629620 100644
--- a/JavaScriptCore/wtf/PageAllocation.h
+++ b/JavaScriptCore/wtf/PageAllocation.h
@@ -30,63 +30,59 @@
 #include <wtf/UnusedParam.h>
 #include <wtf/VMTags.h>
 
-#if OS(SYMBIAN)
-#include <e32std.h>
-#endif
-
-#if HAVE(MMAP)
-#define PAGE_ALLOCATION_ALLOCATE_AT 1
-#else
-#define PAGE_ALLOCATION_ALLOCATE_AT 0
-#endif
-
-#if HAVE(MMAP)
-#include <sys/mman.h>
-#include <unistd.h>
-#endif
-
 #if OS(DARWIN)
-
 #include <mach/mach_init.h>
-#include <mach/mach_port.h>
-#include <mach/task.h>
-#include <mach/thread_act.h>
 #include <mach/vm_map.h>
+#endif
 
-#elif OS(WINDOWS)
+#if OS(HAIKU)
+#include <OS.h>
+#endif
 
+#if OS(WINDOWS)
 #include <malloc.h>
 #include <windows.h>
-
-#elif OS(HAIKU)
-
-#include <OS.h>
-
-#elif OS(UNIX)
-
-#include <stdlib.h>
-
-#if OS(SOLARIS)
-#include <thread.h>
-#else
-#include <pthread.h>
 #endif
 
-#if HAVE(PTHREAD_NP_H)
-#include <pthread_np.h>
+#if OS(SYMBIAN)
+#include <e32hal.h>
+#include <e32std.h>
 #endif
 
-#if OS(QNX)
+#if HAVE(ERRNO_H)
 #include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <sys/procfs.h>
 #endif
 
+#if HAVE(MMAP)
+#include <sys/mman.h>
+#include <unistd.h>
 #endif
 
 namespace WTF {
 
+/*
+    PageAllocation
+
+    The PageAllocation class provides a cross-platform memory allocation interface
+    with similar capabilities to posix mmap/munmap.  Memory is allocated by calling
+    PageAllocation::allocate, and deallocated by calling deallocate on the
+    PageAllocation object.  The PageAllocation holds the allocation's base pointer
+    and size.
+
+    The allocate method is passed the size required (which must be a multiple of
+    the system page size, which can be accessed using PageAllocation::pageSize).
+    Callers may also optinally provide a flag indicating the usage (for use by
+    system memory usage tracking tools, where implemented), and boolean values
+    specifying the required protection (defaulting to writable, non-executable).
+
+    Where HAVE(PAGE_ALLOCATE_AT) and HAVE(PAGE_ALLOCATE_ALIGNED) are available
+    memory may also be allocated at a specified address, or with a specified
+    alignment respectively.  PageAllocation::allocateAt take an address to try
+    to allocate at, and a boolean indicating whether this behaviour is strictly
+    required (if this address is unavailable, should memory at another address
+    be allocated instead).  PageAllocation::allocateAligned requires that the
+    size is a power of two that is >= system page size.
+*/
 class PageAllocation {
 public:
     enum Usage {
@@ -106,53 +102,56 @@ public:
     {
     }
 
-    // Create a PageAllocation object representing a sub-region of an existing allocation;
-    // deallocate should never be called on an object represnting a subregion, only on the
-    // initial allocation.
-    PageAllocation(void* base, size_t size, const PageAllocation& parent)
-        : m_base(base)
-        , m_size(size)
-#if OS(SYMBIAN)
-        , m_chunk(parent.m_chunk)
-#endif
-    {
-#if defined(NDEBUG) && !OS(SYMBIAN)
-        UNUSED_PARAM(parent);
-#endif
-        ASSERT(!base || base >= parent.m_base);
-        ASSERT(!base || size <= parent.m_size);
-        ASSERT(!base || static_cast<char*>(base) + size <= static_cast<char*>(parent.m_base) + parent.m_size);
-    }
-
+    bool operator!() const { return !m_base; }
     void* base() const { return m_base; }
     size_t size() const { return m_size; }
 
-    bool operator!() const { return !m_base; }
-#if COMPILER(WINSCW)
-    operator bool const { return m_base; }
-#else
-    typedef void* PageAllocation::*UnspecifiedBoolType;
-    operator UnspecifiedBoolType() const { return m_base ? &PageAllocation::m_base : 0; }
-#endif
-
-    bool commit(void*, size_t, bool writable = true, bool executable = false) const;
-    void decommit(void*, size_t) const;
-    void deallocate();
+    static PageAllocation allocate(size_t size, Usage usage = UnknownUsage, bool writable = true, bool executable = false)
+    {
+        // size must be a multiple of pageSize.
+        ASSERT(!(size & (pageSize() - 1)));
+        return systemAllocate(size, usage, writable, executable);
+    }
 
-    static PageAllocation allocate(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false);
-    static PageAllocation reserve(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false);
-#if PAGE_ALLOCATION_ALLOCATE_AT
-    static PageAllocation allocateAt(void* address, bool fixed, size_t, Usage = UnknownUsage, bool writable = true, bool executable = false);
-    static PageAllocation reserveAt(void* address, bool fixed, size_t, Usage = UnknownUsage, bool writable = true, bool executable = false);
+#if HAVE(PAGE_ALLOCATE_AT)
+    static PageAllocation allocateAt(void* address, bool fixed, size_t size, Usage usage = UnknownUsage, bool writable = true, bool executable = false)
+    {
+        // size must be a multiple of pageSize.
+        ASSERT(!(size & (pageSize() - 1)));
+        // address must be aligned to pageSize.
+        ASSERT(!(reinterpret_cast<intptr_t>(address) & (pageSize() - 1)));
+        return systemAllocateAt(address, fixed, size, usage, writable, executable);
+    }
 #endif
 
-#if HAVE(ALIGNED_ALLOCATE)
-    static PageAllocation allocateAligned(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false);
+#if HAVE(PAGE_ALLOCATE_ALIGNED)
+    static PageAllocation allocateAligned(size_t size, Usage usage = UnknownUsage)
+    {
+        // size must be a multiple of pageSize.
+        ASSERT(!(size & (pageSize() - 1)));
+        // size must be a power of two.
+        ASSERT(!(size & (size - 1)));
+        return systemAllocateAligned(size, usage);
+    }
 #endif
 
-    static size_t pagesize();
+    void deallocate()
+    {
+        ASSERT(m_base);
+        systemDeallocate(true);
+    }
 
-private:
+    static size_t pageSize()
+    {
+        if (!s_pageSize) {
+            s_pageSize = systemPageSize();
+            // system page size must be a power of two.
+            ASSERT(!(s_pageSize & (s_pageSize - 1)));
+        }
+        return s_pageSize;
+    }
+
+protected:
 #if OS(SYMBIAN)
     PageAllocation(void* base, size_t size, RChunk* chunk)
         : m_base(base)
@@ -168,95 +167,192 @@ private:
     }
 #endif
 
+    static PageAllocation systemAllocate(size_t, Usage, bool, bool);
+#if HAVE(PAGE_ALLOCATE_AT)
+    static PageAllocation systemAllocateAt(void*, bool, size_t, Usage, bool, bool);
+#endif
+#if HAVE(PAGE_ALLOCATE_ALIGNED)
+    static PageAllocation systemAllocateAligned(size_t, Usage);
+#endif
+    // systemDeallocate takes a parameter indicating whether memory is currently committed
+    // (this should always be true for PageAllocation, false for PageReservation).
+    void systemDeallocate(bool committed);
+    static size_t systemPageSize();
+
     void* m_base;
     size_t m_size;
 #if OS(SYMBIAN)
     RChunk* m_chunk;
 #endif
+
+    static JS_EXPORTDATA size_t s_pageSize;
 };
 
-#if HAVE(ALIGNED_ALLOCATE)
 
-#if OS(DARWIN)
+#if HAVE(MMAP)
+
 
-inline PageAllocation PageAllocation::allocateAligned(size_t size, Usage, bool writable, bool executable)
+inline PageAllocation PageAllocation::systemAllocate(size_t size, Usage usage, bool writable, bool executable)
 {
-    ASSERT(!(size & (size - 1)));
-    vm_address_t address = 0;
-    vm_prot_t protection = VM_PROT_READ;
-    protection |= executable ? VM_PROT_EXECUTE : 0;
-    protection |= writable ? VM_PROT_WRITE : 0;
-    vm_map(current_task(), &address, size, (size - 1), VM_FLAGS_ANYWHERE | VM_TAG_FOR_COLLECTOR_MEMORY, MEMORY_OBJECT_NULL, 0, FALSE, protection, protection, VM_INHERIT_DEFAULT);
-    return PageAllocation(reinterpret_cast<void*>(address), size);
+    return systemAllocateAt(0, false, size, usage, writable, executable);
 }
 
-#elif OS(WINDOWS)
-
-inline PageAllocation PageAllocation::allocateAligned(size_t size, Usage usage, bool writable, bool executable)
+inline PageAllocation PageAllocation::systemAllocateAt(void* address, bool fixed, size_t size, Usage usage, bool writable, bool executable)
 {
-    ASSERT(writable && !executable);
-#if COMPILER(MINGW) && !COMPILER(MINGW64)
-    void* address = __mingw_aligned_malloc(size, size);
+    int protection = PROT_READ;
+    if (writable)
+        protection |= PROT_WRITE;
+    if (executable)
+        protection |= PROT_EXEC;
+
+    int flags = MAP_PRIVATE | MAP_ANON;
+    if (fixed)
+        flags |= MAP_FIXED;
+
+#if OS(DARWIN) && !defined(BUILDING_ON_TIGER)
+    int fd = usage;
 #else
-    void* address = _aligned_malloc(size, size);
+    int fd = -1;
 #endif
-    memset(address, 0, size);
-    return PageAllocation(address, size);
-}
 
-#elif HAVE(POSIX_MEMALIGN)
+    void* base = mmap(address, size, protection, flags, fd, 0);
+    if (base == MAP_FAILED)
+        base = 0;
+    return PageAllocation(base, size);
+}
 
-inline PageAllocation PageAllocation::allocateAligned(size_t size, Usage usage, bool writable, bool executable)
+inline PageAllocation PageAllocation::systemAllocateAligned(size_t size, Usage usage)
 {
-    ASSERT(writable && !executable);
-
+#if OS(DARWIN)
+    vm_address_t address = 0;
+    int flags = VM_FLAGS_ANYWHERE;
+    if (usage != -1)
+        flags |= usage;
+    vm_map(current_task(), &address, size, (size - 1), flags, MEMORY_OBJECT_NULL, 0, FALSE, PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE | PROT_EXEC, VM_INHERIT_DEFAULT);
+    return PageAllocation(reinterpret_cast<void*>(address), size);
+#elif HAVE(POSIX_MEMALIGN)
     void* address;
     posix_memalign(&address, size, size);
     return PageAllocation(address, size);
-}
-
-#elif HAVE(MMAP)
-
-inline PageAllocation PageAllocation::allocateAligned(size_t size, Usage usage, bool writable, bool executable)
-{
-    ASSERT(!(size & (size - 1)));
-    ASSERT(writable && !executable);
-    static size_t pagesize = getpagesize();
-
-    size_t extra = 0;
-    if (size > pagesize)
-        extra = size - pagesize;
+#else
+    size_t extra = size - pageSize();
 
-    int flags = MAP_PRIVATE | MAP_ANON;
+    // Check for overflow.
+    if ((size + extra) < size)
+        return PageAllocation(0, size);
 
-    int protection = PROT_READ;
-    if (writable)
-        protection |= PROT_WRITE;
-    if (executable)
-        protection |= PROT_EXEC;
-
-    // use page allocation
-    void* mmapResult = mmap(0, size + extra, protection, flags, usage, 0);
+#if OS(DARWIN) && !defined(BUILDING_ON_TIGER)
+    int fd = usage;
+#else
+    int fd = -1;
+#endif
+    void* mmapResult = mmap(0, size + extra, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, fd, 0);
+    if (mmapResult == MAP_FAILED)
+        return PageAllocation(0, size);
     uintptr_t address = reinterpret_cast<uintptr_t>(mmapResult);
 
     size_t adjust = 0;
     if ((address & (size - 1)))
         adjust = size - (address & (size - 1));
-
     if (adjust > 0)
         munmap(reinterpret_cast<char*>(address), adjust);
-
     if (adjust < extra)
         munmap(reinterpret_cast<char*>(address + adjust + size), extra - adjust);
-
     address += adjust;
 
     return PageAllocation(reinterpret_cast<void*>(address), size);
+#endif
+}
+
+inline void PageAllocation::systemDeallocate(bool)
+{
+    int result = munmap(m_base, m_size);
+    ASSERT_UNUSED(result, !result);
+    m_base = 0;
+}
+
+inline size_t PageAllocation::systemPageSize()
+{
+    return getpagesize();
+}
+
+
+#elif HAVE(VIRTUALALLOC)
+
+
+inline PageAllocation PageAllocation::systemAllocate(size_t size, Usage, bool writable, bool executable)
+{
+    DWORD protection = executable ?
+        (writable ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ) :
+        (writable ? PAGE_READWRITE : PAGE_READONLY);
+    return PageAllocation(VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, protection), size);
 }
 
+#if HAVE(ALIGNED_MALLOC)
+inline PageAllocation PageAllocation::systemAllocateAligned(size_t size, Usage usage)
+{
+#if COMPILER(MINGW) && !COMPILER(MINGW64)
+    void* address = __mingw_aligned_malloc(size, size);
+#else
+    void* address = _aligned_malloc(size, size);
+#endif
+    memset(address, 0, size);
+    return PageAllocation(address, size);
+}
 #endif
 
+inline void PageAllocation::systemDeallocate(bool committed)
+{
+#if OS(WINCE)
+    if (committed)
+        VirtualFree(m_base, m_size, MEM_DECOMMIT);
+#else
+    UNUSED_PARAM(committed);
 #endif
+    VirtualFree(m_base, 0, MEM_RELEASE); 
+    m_base = 0;
+}
+
+inline size_t PageAllocation::systemPageSize()
+{
+    static size_t size = 0;
+    SYSTEM_INFO system_info;
+    GetSystemInfo(&system_info);
+    size = system_info.dwPageSize;
+    return size;
+}
+
+
+#elif OS(SYMBIAN)
+
+
+inline PageAllocation PageAllocation::systemAllocate(size_t size, Usage usage, bool writable, bool executable)
+{
+    RChunk* rchunk = new RChunk();
+    if (executable)
+        rchunk->CreateLocalCode(size, size);
+    else
+        rchunk->CreateLocal(size, size);
+    return PageAllocation(rchunk->Base(), size, rchunk);
+}
+
+inline void PageAllocation::systemDeallocate(bool)
+{
+    m_chunk->Close();
+    delete m_chunk;
+    m_base = 0;
+}
+
+inline size_t PageAllocation::systemPageSize()
+{
+    static TInt page_size = 0;
+    UserHal::PageSizeInBytes(page_size);
+    return page_size;
+}
+
+
+#endif
+
 
 }
 
diff --git a/JavaScriptCore/wtf/PageReservation.h b/JavaScriptCore/wtf/PageReservation.h
new file mode 100644
index 0000000..f068120
--- /dev/null
+++ b/JavaScriptCore/wtf/PageReservation.h
@@ -0,0 +1,259 @@
+/*
+ * 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 PageReservation_h
+#define PageReservation_h
+
+#include <wtf/PageAllocation.h>
+
+namespace WTF {
+
+/*
+    PageReservation
+
+    Like PageAllocation, the PageReservation class provides a cross-platform memory
+    allocation interface, but with a set of capabilities more similar to that of
+    VirtualAlloc than posix mmap.  PageReservation can be used to allocate virtual
+    memory without committing physical memory pages using PageReservation::reserve.
+    Following a call to reserve all memory in the region is in a decommited state,
+    in which the memory should not be used (accessing the memory may cause a fault).
+
+    Before using memory it must be committed by calling commit, which is passed start
+    and size values (both of which require system page size granularity).  One the
+    committed memory is no longer needed 'decommit' may be called to return the
+    memory to its devommitted state.  Commit should only be called on memory that is
+    currently decommitted, and decommit should only be called on memory regions that
+    are currently committed.  All memory should be decommited before the reservation
+    is deallocated.  Values in memory may not be retained accross a pair of calls if
+    the region of memory is decommitted and then committed again.
+
+    Where HAVE(PAGE_ALLOCATE_AT) is available a PageReservation::reserveAt method
+    also exists, with behaviour mirroring PageAllocation::allocateAt.
+
+    Memory protection should not be changed on decommitted memory, and if protection
+    is changed on memory while it is committed it should be returned to the orignal
+    protection before decommit is called.
+
+    Note: Inherits from PageAllocation privately to prevent clients accidentally
+    calling PageAllocation::deallocate on a PageReservation.
+*/
+class PageReservation : private PageAllocation {
+public:
+    PageReservation()
+    {
+    }
+
+    using PageAllocation::operator!;
+    using PageAllocation::base;
+    using PageAllocation::size;
+
+    bool commit(void* start, size_t size)
+    {
+        ASSERT(m_base);
+        // size must be a multiple of pageSize.
+        ASSERT(!(size & (pageSize() - 1)));
+        // address must be aligned to pageSize.
+        ASSERT(!(reinterpret_cast<intptr_t>(start) & (pageSize() - 1)));
+
+        bool commited = systemCommit(start, size);
+#ifndef NDEBUG
+        if (commited)
+            m_committed += size;
+#endif
+        return commited;
+    }
+    void decommit(void* start, size_t size)
+    {
+        ASSERT(m_base);
+        // size must be a multiple of pageSize.
+        ASSERT(!(size & (pageSize() - 1)));
+        // address must be aligned to pageSize.
+        ASSERT(!(reinterpret_cast<intptr_t>(start) & (pageSize() - 1)));
+
+#ifndef NDEBUG
+        m_committed -= size;
+#endif
+        systemDecommit(start, size);
+    }
+
+    static PageReservation reserve(size_t size, Usage usage = UnknownUsage, bool writable = true, bool executable = false)
+    {
+        // size must be a multiple of pageSize.
+        ASSERT(!(size & (pageSize() - 1)));
+        return systemReserve(size, usage, writable, executable);
+    }
+
+#if HAVE(PAGE_ALLOCATE_AT)
+    static PageReservation reserveAt(void* address, bool fixed, size_t size, Usage usage = UnknownUsage, bool writable = true, bool executable = false)
+    {
+        // size must be a multiple of pageSize.
+        ASSERT(!(size & (pageSize() - 1)));
+        // address must be aligned to pageSize.
+        ASSERT(!(reinterpret_cast<intptr_t>(address) & (pageSize() - 1)));
+        return systemReserveAt(address, fixed, size, usage, writable, executable);
+    }
+#endif
+
+    void deallocate()
+    {
+        ASSERT(m_base);
+        ASSERT(!m_committed);
+        systemDeallocate(false);
+    }
+
+private:
+#if OS(SYMBIAN)
+    PageReservation(void* base, size_t size, RChunk* chunk)
+        : PageAllocation(base, size, chunk)
+#else
+    PageReservation(void* base, size_t size)
+        : PageAllocation(base, size)
+#endif
+#ifndef NDEBUG
+        , m_committed(0)
+#endif
+    {
+    }
+
+    bool systemCommit(void*, size_t);
+    void systemDecommit(void*, size_t);
+    static PageReservation systemReserve(size_t, Usage, bool, bool);
+#if HAVE(PAGE_ALLOCATE_AT)
+    static PageReservation systemReserveAt(void*, bool, size_t, Usage, bool, bool);
+#endif
+
+#if HAVE(VIRTUALALLOC)
+    DWORD m_protection;
+#endif
+#ifndef NDEBUG
+    size_t m_committed;
+#endif
+};
+
+
+#if HAVE(MMAP)
+
+
+inline bool PageReservation::systemCommit(void* start, size_t size)
+{
+#if HAVE(MADV_FREE_REUSE)
+    while (madvise(start, size, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { }
+#else
+    UNUSED_PARAM(start);
+    UNUSED_PARAM(size);
+#endif
+    return true;
+}
+
+inline void PageReservation::systemDecommit(void* start, size_t size)
+{
+#if HAVE(MADV_FREE_REUSE)
+    while (madvise(start, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
+#elif HAVE(MADV_FREE)
+    while (madvise(start, size, MADV_FREE) == -1 && errno == EAGAIN) { }
+#elif HAVE(MADV_DONTNEED)
+    while (madvise(start, size, MADV_DONTNEED) == -1 && errno == EAGAIN) { }
+#else
+    UNUSED_PARAM(start);
+    UNUSED_PARAM(size);
+#endif
+}
+
+inline PageReservation PageReservation::systemReserve(size_t size, Usage usage, bool writable, bool executable)
+{
+    return systemReserveAt(0, false, size, usage, writable, executable);
+}
+
+inline PageReservation PageReservation::systemReserveAt(void* address, bool fixed, size_t size, Usage usage, bool writable, bool executable)
+{
+    void* base = systemAllocateAt(address, fixed, size, usage, writable, executable).base();
+#if HAVE(MADV_FREE_REUSE)
+    // When using MADV_FREE_REUSE we keep all decommitted memory marked as REUSABLE.
+    // We call REUSE on commit, and REUSABLE on decommit.
+    if (base)
+        while (madvise(base, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
+#endif
+    return PageReservation(base, size);
+}
+
+
+#elif HAVE(VIRTUALALLOC)
+
+
+inline bool PageReservation::systemCommit(void* start, size_t size)
+{
+    return VirtualAlloc(start, size, MEM_COMMIT, m_protection) == start;
+}
+
+inline void PageReservation::systemDecommit(void* start, size_t size)
+{
+    VirtualFree(start, size, MEM_DECOMMIT);
+}
+
+inline PageReservation PageReservation::systemReserve(size_t size, Usage usage, bool writable, bool executable)
+{
+    // Record the protection for use during commit.
+    m_protection = executable ?
+        (writable ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ) :
+        (writable ? PAGE_READWRITE : PAGE_READONLY);
+    return PageReservation(VirtualAlloc(0, size, MEM_RESERVE, m_protection), size);
+}
+
+
+#elif OS(SYMBIAN)
+
+
+inline bool PageReservation::systemCommit(void* start, size_t size)
+{
+    intptr_t offset = reinterpret_cast<intptr_t>(m_base) - reinterpret_cast<intptr_t>(start);
+    m_chunk->Commit(offset, size);
+    return true;
+}
+
+inline void PageReservation::systemDecommit(void* start, size_t size)
+{
+    intptr_t offset = reinterpret_cast<intptr_t>(m_base) - reinterpret_cast<intptr_t>(start);
+    m_chunk->Decommit(offset, size);
+}
+
+inline PageReservation PageReservation::systemReserve(size_t size, Usage usage, bool writable, bool executable)
+{
+    RChunk* rchunk = new RChunk();
+    if (executable)
+        rchunk->CreateLocalCode(0, size);
+    else
+        rchunk->CreateDisconnectedLocal(0, 0, size);
+    return PageReservation(rchunk->Base(), size, rchunk);
+}
+
+
+#endif
+
+
+}
+
+using WTF::PageReservation;
+
+#endif // PageReservation_h
diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h
index 1abf90b..75acc5c 100644
--- a/JavaScriptCore/wtf/Platform.h
+++ b/JavaScriptCore/wtf/Platform.h
@@ -708,7 +708,6 @@
 #define HAVE_ERRNO_H 1
 #define HAVE_LANGINFO_H 1
 #define HAVE_MMAP 1
-#define HAVE_ALIGNED_ALLOCATE 1
 #define HAVE_MERGESORT 1
 #define HAVE_SBRK 1
 #define HAVE_STRINGS_H 1
@@ -737,10 +736,9 @@
 
 #if OS(WINCE)
 #define HAVE_ERRNO_H 0
-#define HAVE_ALIGNED_ALLOCATE 0
 #else
 #define HAVE_SYS_TIMEB_H 1
-#define HAVE_ALIGNED_ALLOCATE 1
+#define HAVE_ALIGNED_MALLOC 1
 #endif
 #define HAVE_VIRTUALALLOC 1
 
@@ -797,12 +795,11 @@
 
 #endif
 
-#if !defined(HAVE_ALIGNED_ALLOCATE)
-#if HAVE(POSIX_MEMALIGN)
-#define HAVE_ALIGNED_ALLOCATE 1
-#else
-#define HAVE_ALIGNED_ALLOCATE 0
+#if HAVE(MMAP) || (HAVE(VIRTUALALLOC) && HAVE(ALIGNED_MALLOC))
+#define HAVE_PAGE_ALLOCATE_ALIGNED 1
 #endif
+#if HAVE(MMAP)
+#define HAVE_PAGE_ALLOCATE_AT 1
 #endif
 
 /* ENABLE macro defaults */
diff --git a/JavaScriptGlue/ChangeLog b/JavaScriptGlue/ChangeLog
index 5f64601..9301542 100644
--- a/JavaScriptGlue/ChangeLog
+++ b/JavaScriptGlue/ChangeLog
@@ -1,3 +1,13 @@
+2010-08-04  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Bug 43515 - Fix small design issues with PageAllocation, split out PageReservation.
+        (add forwarding headers)
+
+        * ForwardingHeaders/wtf/Bitmap.h: Added.
+        * ForwardingHeaders/wtf/PageReservation.h: Added.
+
 2010-08-04  Sheriff Bot  <webkit.review.bot at gmail.com>
 
         Unreviewed, rolling out r64655.
diff --git a/JavaScriptGlue/ForwardingHeaders/wtf/PageReservation.h b/JavaScriptGlue/ForwardingHeaders/wtf/PageReservation.h
new file mode 100644
index 0000000..81581b6
--- /dev/null
+++ b/JavaScriptGlue/ForwardingHeaders/wtf/PageReservation.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/PageReservation.h>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 28b005e..365662c 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,13 @@
+2010-08-04  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Bug 43515 - Fix small design issues with PageAllocation, split out PageReservation.
+        (add forwarding headers)
+
+        * ForwardingHeaders/wtf/Bitmap.h: Added.
+        * ForwardingHeaders/wtf/PageReservation.h: Added.
+
 2010-08-04  Zhenyao Mo  <zmo at google.com>
 
         Reviewed by Adam Barth.
diff --git a/WebCore/ForwardingHeaders/wtf/PageReservation.h b/WebCore/ForwardingHeaders/wtf/PageReservation.h
new file mode 100644
index 0000000..212b02c
--- /dev/null
+++ b/WebCore/ForwardingHeaders/wtf/PageReservation.h
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_PageReservation_h
+#define WebCore_FWD_PageReservation_h
+#include <JavaScriptCore/PageReservation.h>
+#endif

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list