diff options
author | Kristian Monsen <kristianm@google.com> | 2010-07-30 10:46:49 +0100 |
---|---|---|
committer | Kristian Monsen <kristianm@google.com> | 2010-08-04 13:01:34 +0100 |
commit | 0617145a89917ae7735fe1c9538688ab9a577df5 (patch) | |
tree | 56206078694427c37ed7bdf27eb5221398b833c0 /JavaScriptCore/wtf | |
parent | ef1adcdfc805d4d13103f6f15cc5b4d96828a60f (diff) | |
download | external_webkit-0617145a89917ae7735fe1c9538688ab9a577df5.zip external_webkit-0617145a89917ae7735fe1c9538688ab9a577df5.tar.gz external_webkit-0617145a89917ae7735fe1c9538688ab9a577df5.tar.bz2 |
Merge WebKit at r64264 : Initial merge by git.
Change-Id: Ic42bef02efef8217a0f84c47176a9c617c28d1f1
Diffstat (limited to 'JavaScriptCore/wtf')
-rw-r--r-- | JavaScriptCore/wtf/BumpPointerAllocator.h | 253 | ||||
-rw-r--r-- | JavaScriptCore/wtf/CMakeListsEfl.txt | 10 | ||||
-rw-r--r-- | JavaScriptCore/wtf/PageAllocation.cpp | 231 | ||||
-rw-r--r-- | JavaScriptCore/wtf/PageAllocation.h | 125 | ||||
-rw-r--r-- | JavaScriptCore/wtf/Platform.h | 142 | ||||
-rw-r--r-- | JavaScriptCore/wtf/TCSpinLock.h | 39 |
6 files changed, 706 insertions, 94 deletions
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/wtf/CMakeListsEfl.txt b/JavaScriptCore/wtf/CMakeListsEfl.txt index 3e128be..3cd3c8e 100644 --- a/JavaScriptCore/wtf/CMakeListsEfl.txt +++ b/JavaScriptCore/wtf/CMakeListsEfl.txt @@ -3,15 +3,19 @@ ADD_DEFINITIONS(-DUSE_SYSTEM_MALLOC=1) LIST(APPEND WTF_SOURCES efl/MainThreadEfl.cpp - gobject/GOwnPtr.cpp - gobject/GRefPtr.cpp - ThreadIdentifierDataPthreads.cpp ThreadingPthreads.cpp unicode/icu/CollatorICU.cpp ) +IF (ENABLE_GLIB_SUPPORT) + LIST(APPEND WTF_SOURCES + gobject/GOwnPtr.cpp + gobject/GRefPtr.cpp + ) +ENDIF () + LIST(APPEND WTF_LIBRARIES pthread ${ICU_LIBRARIES} diff --git a/JavaScriptCore/wtf/PageAllocation.cpp b/JavaScriptCore/wtf/PageAllocation.cpp new file mode 100644 index 0000000..58a10f6 --- /dev/null +++ b/JavaScriptCore/wtf/PageAllocation.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + * + * 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. + */ + +#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 + +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 = static_cast<intptr_t>(base()) - static_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 = static_cast<intptr_t>(base()) - static_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, rchunk->Base(), size); +} + +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 + +} diff --git a/JavaScriptCore/wtf/PageAllocation.h b/JavaScriptCore/wtf/PageAllocation.h new file mode 100644 index 0000000..00b5363 --- /dev/null +++ b/JavaScriptCore/wtf/PageAllocation.h @@ -0,0 +1,125 @@ +/* + * 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 PageAllocation_h +#define PageAllocation_h + +#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 + +namespace WTF { + +class PageAllocation { +public: + enum Usage { + UnknownUsage = -1, + FastMallocPages = VM_TAG_FOR_TCMALLOC_MEMORY, + JSGCHeapPages = VM_TAG_FOR_COLLECTOR_MEMORY, + JSVMStackPages = VM_TAG_FOR_REGISTERFILE_MEMORY, + JSJITCodePages = VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, + }; + + PageAllocation() + : m_base(0) + , m_size(0) +#if OS(SYMBIAN) + , m_chunk(0) +#endif + { + } + + // 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.chunk) +#endif + { +#if defined(NDEBUG) && !OS(SYMBIAN) + UNUSED_PARAM(parent); +#endif + ASSERT(base >= parent.m_base); + ASSERT(size <= parent.m_size); + ASSERT(static_cast<char*>(base) + size <= static_cast<char*>(parent.m_base) + parent.m_size); + } + + void* base() const { return m_base; } + size_t size() const { return m_size; } + + bool operator!() const { return !m_base; } + + 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, 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); +#endif + static size_t pagesize(); + +private: +#if OS(SYMBIAN) + PageAllocation(void* base, size_t size, RChunk* chunk) + : m_base(base) + , m_size(size) + , m_chunk(chunk) + { + } +#else + PageAllocation(void* base, size_t size) + : m_base(base) + , m_size(size) + { + } +#endif + + void* m_base; + size_t m_size; +#if OS(SYMBIAN) + RChunk* m_chunk; +#endif +}; + +} + +using WTF::PageAllocation; + +#endif // PageAllocation_h diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h index 4166ad9..ed618b0 100644 --- a/JavaScriptCore/wtf/Platform.h +++ b/JavaScriptCore/wtf/Platform.h @@ -80,6 +80,10 @@ #if defined(__GNUC__) && !COMPILER(RVCT) #define WTF_COMPILER_GCC 1 #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#define GCC_VERSION_AT_LEAST(major, minor, patch) (GCC_VERSION >= (major * 10000 + minor * 100 + patch)) +#else +/* define this for !GCC compilers, just so we can write things like COMPILER(GCC) && GCC_VERSION_AT_LEAST(4,1,0) */ +#define GCC_VERSION_AT_LEAST(major, minor, patch) 0 #endif /* COMPILER(MINGW) - MinGW GCC */ @@ -522,6 +526,7 @@ #define WTF_USE_CORE_TEXT 1 #else #define WTF_PLATFORM_SKIA 1 +#define WTF_USE_GLES2_RENDERING 1 #endif #endif @@ -548,16 +553,6 @@ #endif #if OS(WINCE) && !PLATFORM(QT) -#undef ENABLE_JSC_MULTIPLE_THREADS -#define ENABLE_JSC_MULTIPLE_THREADS 0 -#define USE_SYSTEM_MALLOC 0 -#define ENABLE_ICONDATABASE 0 -#define ENABLE_JAVASCRIPT_DEBUGGER 0 -#define ENABLE_FTPDIR 0 -#define ENABLE_PAN_SCROLLING 0 -#define ENABLE_WML 1 -#define HAVE_ACCESSIBILITY 0 - #define NOMINMAX /* Windows min and max conflict with standard macros */ #define NOSHLWAPI /* shlwapi.h not available on WinCe */ @@ -650,7 +645,13 @@ This prevents unnecessary invals. */ #define ENABLE_TEXT_CARET 1 #define ENABLE_JAVASCRIPT_DEBUGGER 0 +<<<<<<< HEAD #define ENABLE_ORIENTATION_EVENTS 1 +======= +#if !defined(ENABLE_JIT) && !ENABLE(ANDROID_JSC_JIT) +#define ENABLE_JIT 0 +#endif +>>>>>>> webkit.org at r64264 #endif #if PLATFORM(WIN) @@ -936,86 +937,50 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define ENABLE_REPAINT_THROTTLING 0 #endif -#if !defined(ENABLE_JIT) - -/* The JIT is tested & working on x86_64 Mac */ -#if CPU(X86_64) && PLATFORM(MAC) - #define ENABLE_JIT 1 -/* The JIT is tested & working on x86 Mac */ -#elif CPU(X86) && PLATFORM(MAC) - #define ENABLE_JIT 1 -#elif CPU(ARM_THUMB2) && PLATFORM(IPHONE) - #define ENABLE_JIT 1 -/* The JIT is tested & working on Android */ -#elif CPU(ARM_THUMB2) && PLATFORM(ANDROID) && ENABLE(ANDROID_JSC_JIT) - #define ENABLE_JIT 1 -/* The JIT is tested & working on x86 Windows */ -#elif CPU(X86) && PLATFORM(WIN) - #define ENABLE_JIT 1 -#endif - -#if PLATFORM(QT) || PLATFORM(WX) -#if CPU(X86_64) && OS(DARWIN) - #define ENABLE_JIT 1 -#elif CPU(X86) && OS(DARWIN) - #define ENABLE_JIT 1 -#elif CPU(X86) && OS(WINDOWS) && COMPILER(MINGW) && GCC_VERSION >= 40100 - #define ENABLE_JIT 1 -#elif CPU(X86) && OS(WINDOWS) && COMPILER(MSVC) - #define ENABLE_JIT 1 -#elif CPU(X86) && OS(LINUX) && GCC_VERSION >= 40100 - #define ENABLE_JIT 1 -#elif CPU(X86_64) && OS(LINUX) && GCC_VERSION >= 40100 - #define ENABLE_JIT 1 -#elif CPU(ARM_TRADITIONAL) && OS(LINUX) - #define ENABLE_JIT 1 -#elif CPU(ARM_TRADITIONAL) && OS(SYMBIAN) && COMPILER(RVCT) - #define ENABLE_JIT 1 -#elif CPU(MIPS) && OS(LINUX) - #define ENABLE_JIT 1 -#endif -#endif /* PLATFORM(QT) */ - -#endif /* !defined(ENABLE_JIT) */ - -#if !ENABLE(JIT) -#define ENABLE_INTERPRETER 1 +/* Disable the JIT on versiond of GCC prior to 4.1 */ +#if !defined(ENABLE_JIT) && COMPILER(GCC) && !GCC_VERSION_AT_LEAST(4,1,0) +#define ENABLE_JIT 0 #endif -#if !(ENABLE(JIT) || ENABLE(INTERPRETER)) -#error You have to have at least one execution model enabled to build JSC +/* The JIT is enabled by default on all x86, x64-64, ARM & MIPS platforms. */ +#if !defined(ENABLE_JIT) \ + && (CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(MIPS)) \ + && (OS(DARWIN) || !COMPILER(GCC) || GCC_VERSION_AT_LEAST(4,1,0)) +#define ENABLE_JIT 1 #endif -/* CPU architecture specific optimizations */ -#if CPU(ARM_TRADITIONAL) -#if ENABLE(JIT) && !defined(ENABLE_JIT_OPTIMIZE_MOD) && WTF_ARM_ARCH_AT_LEAST(5) -#define ENABLE_JIT_OPTIMIZE_MOD 1 -#endif -#endif -#if (CPU(X86) && USE(JSVALUE32_64)) || (CPU(X86_64) && USE(JSVALUE64)) \ - || CPU(ARM) \ - || CPU(MIPS) -#if ENABLE(JIT) && !defined(ENABLE_JIT_OPTIMIZE_NATIVE_CALL) -#define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 1 +/* Ensure that either the JIT or the interpreter has been enabled. */ +#if !defined(ENABLE_INTERPRETER) && !ENABLE(JIT) +#define ENABLE_INTERPRETER 1 #endif +#if !(ENABLE(JIT) || ENABLE(INTERPRETER)) +#error You have to have at least one execution model enabled to build JSC #endif +/* Configure the JIT */ #if ENABLE(JIT) -#ifndef ENABLE_JIT_OPTIMIZE_CALL -#define ENABLE_JIT_OPTIMIZE_CALL 1 -#endif -#ifndef ENABLE_JIT_OPTIMIZE_NATIVE_CALL -#define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0 -#endif -#ifndef ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS -#define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1 -#endif -#ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS -#define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1 -#endif -#ifndef ENABLE_JIT_OPTIMIZE_MOD -#define ENABLE_JIT_OPTIMIZE_MOD 0 -#endif + #if CPU(ARM_TRADITIONAL) + #if !defined(ENABLE_JIT_USE_SOFT_MODULO) && WTF_ARM_ARCH_AT_LEAST(5) + #define ENABLE_JIT_USE_SOFT_MODULO 1 + #endif + #endif + + #if !defined(ENABLE_JIT_OPTIMIZE_NATIVE_CALL) && CPU(X86) && USE(JSVALUE32) + #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0 + #endif + + #ifndef ENABLE_JIT_OPTIMIZE_CALL + #define ENABLE_JIT_OPTIMIZE_CALL 1 + #endif + #ifndef ENABLE_JIT_OPTIMIZE_NATIVE_CALL + #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 1 + #endif + #ifndef ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS + #define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1 + #endif + #ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS + #define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1 + #endif #endif #if CPU(X86) && COMPILER(MSVC) @@ -1026,25 +991,20 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define JSC_HOST_CALL #endif +/* Configure the interpreter */ #if COMPILER(GCC) #define HAVE_COMPUTED_GOTO 1 #endif - #if HAVE(COMPUTED_GOTO) && ENABLE(INTERPRETER) #define ENABLE_COMPUTED_GOTO_INTERPRETER 1 #endif -/* Yet Another Regex Runtime. */ -#if !defined(ENABLE_YARR_JIT) - -/* YARR and YARR_JIT is usually turned on for JIT enabled ports */ -#if ENABLE(JIT) +/* Yet Another Regex Runtime - turned on by default for JIT enabled ports. */ +#if ENABLE(JIT) && !defined(ENABLE_YARR) && !defined(ENABLE_YARR_JIT) #define ENABLE_YARR 1 #define ENABLE_YARR_JIT 1 #endif -#endif /* !defined(ENABLE_YARR_JIT) */ - /* Sanity Check */ #if ENABLE(YARR_JIT) && !ENABLE(YARR) #error "YARR_JIT requires YARR" @@ -1100,7 +1060,7 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ /* FIXME: Defining ENABLE_3D_RENDERING here isn't really right, but it's always used with with WTF_USE_ACCELERATED_COMPOSITING, and it allows the feature to be turned on and off in one place. */ -#if PLATFORM(WIN) +#if PLATFORM(WIN) && !OS(WINCE) #include "QuartzCorePresent.h" #if QUARTZCORE_PRESENT #define WTF_USE_ACCELERATED_COMPOSITING 1 diff --git a/JavaScriptCore/wtf/TCSpinLock.h b/JavaScriptCore/wtf/TCSpinLock.h index 8a73e13..240b497 100644 --- a/JavaScriptCore/wtf/TCSpinLock.h +++ b/JavaScriptCore/wtf/TCSpinLock.h @@ -1,4 +1,5 @@ // Copyright (c) 2005, 2006, Google Inc. +// Copyright (c) 2010, Patrick Gansterer <paroga@paroga.com> // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -189,6 +190,44 @@ static void TCMalloc_SlowLock(volatile unsigned int* lockword) { } } +#elif OS(WINDOWS) + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> + +static void TCMalloc_SlowLock(LPLONG lockword); + +// The following is a struct so that it can be initialized at compile time +struct TCMalloc_SpinLock { + + inline void Lock() { + if (InterlockedExchange(&m_lockword, 1)) + TCMalloc_SlowLock(&m_lockword); + } + + inline void Unlock() { + InterlockedExchange(&m_lockword, 0); + } + + inline bool IsHeld() const { + return m_lockword != 0; + } + + inline void Init() { m_lockword = 0; } + + LONG m_lockword; +}; + +#define SPINLOCK_INITIALIZER { 0 } + +static void TCMalloc_SlowLock(LPLONG lockword) { + Sleep(0); // Yield immediately since fast path failed + while (InterlockedExchange(lockword, 1)) + Sleep(2); +} + #else #include <pthread.h> |