summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/wtf
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-05 14:36:32 +0100
committerBen Murdoch <benm@google.com>2011-05-10 15:38:30 +0100
commitf05b935882198ccf7d81675736e3aeb089c5113a (patch)
tree4ea0ca838d9ef1b15cf17ddb3928efb427c7e5a1 /JavaScriptCore/wtf
parent60fbdcc62bced8db2cb1fd233cc4d1e4ea17db1b (diff)
downloadexternal_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.zip
external_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.tar.gz
external_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.tar.bz2
Merge WebKit at r74534: Initial merge by git.
Change-Id: I6ccd1154fa1b19c2ec2a66878eb675738735f1eb
Diffstat (limited to 'JavaScriptCore/wtf')
-rw-r--r--JavaScriptCore/wtf/ASCIICType.h14
-rw-r--r--JavaScriptCore/wtf/BumpPointerAllocator.h5
-rw-r--r--JavaScriptCore/wtf/CMakeLists.txt1
-rw-r--r--JavaScriptCore/wtf/CMakeListsWinCE.txt20
-rw-r--r--JavaScriptCore/wtf/Complex.h3
-rw-r--r--JavaScriptCore/wtf/DateMath.cpp6
-rw-r--r--JavaScriptCore/wtf/DateMath.h34
-rw-r--r--JavaScriptCore/wtf/MathExtras.h7
-rw-r--r--JavaScriptCore/wtf/OSAllocator.h100
-rw-r--r--JavaScriptCore/wtf/OSAllocatorPosix.cpp121
-rw-r--r--JavaScriptCore/wtf/OSAllocatorSymbian.cpp56
-rw-r--r--JavaScriptCore/wtf/OSAllocatorWin.cpp80
-rw-r--r--JavaScriptCore/wtf/PageAllocation.h281
-rw-r--r--JavaScriptCore/wtf/PageAllocationAligned.cpp87
-rw-r--r--JavaScriptCore/wtf/PageAllocationAligned.h70
-rw-r--r--JavaScriptCore/wtf/PageBlock.cpp84
-rw-r--r--JavaScriptCore/wtf/PageBlock.h83
-rw-r--r--JavaScriptCore/wtf/PageReservation.h193
-rw-r--r--JavaScriptCore/wtf/Platform.h14
-rw-r--r--JavaScriptCore/wtf/PlatformRefPtr.h7
-rw-r--r--JavaScriptCore/wtf/RandomNumberSeed.h2
-rw-r--r--JavaScriptCore/wtf/StackBounds.cpp283
-rw-r--r--JavaScriptCore/wtf/StackBounds.h114
-rw-r--r--JavaScriptCore/wtf/Vector3.h138
-rw-r--r--JavaScriptCore/wtf/WTFThreadData.cpp3
-rw-r--r--JavaScriptCore/wtf/WTFThreadData.h7
-rw-r--r--JavaScriptCore/wtf/brew/StringBrew.cpp (renamed from JavaScriptCore/wtf/PageAllocation.cpp)35
-rw-r--r--JavaScriptCore/wtf/gobject/GTypedefs.h3
-rw-r--r--JavaScriptCore/wtf/haiku/StringHaiku.cpp51
-rw-r--r--JavaScriptCore/wtf/text/AtomicString.cpp82
-rw-r--r--JavaScriptCore/wtf/text/AtomicString.h5
-rw-r--r--JavaScriptCore/wtf/text/CString.cpp7
-rw-r--r--JavaScriptCore/wtf/text/StringConcatenate.h58
-rw-r--r--JavaScriptCore/wtf/text/StringImpl.h2
-rw-r--r--JavaScriptCore/wtf/text/WTFString.h9
-rw-r--r--JavaScriptCore/wtf/unicode/UTF8.cpp169
-rw-r--r--JavaScriptCore/wtf/unicode/UTF8.h11
-rw-r--r--JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h31
-rw-r--r--JavaScriptCore/wtf/wtf.pri7
-rw-r--r--JavaScriptCore/wtf/wx/StringWx.cpp75
40 files changed, 1684 insertions, 674 deletions
diff --git a/JavaScriptCore/wtf/ASCIICType.h b/JavaScriptCore/wtf/ASCIICType.h
index b43bb37..c19b85a 100644
--- a/JavaScriptCore/wtf/ASCIICType.h
+++ b/JavaScriptCore/wtf/ASCIICType.h
@@ -49,6 +49,7 @@ namespace WTF {
inline bool isASCII(wchar_t c) { return !(c & ~0x7F); }
#endif
inline bool isASCII(int c) { return !(c & ~0x7F); }
+ inline bool isASCII(unsigned c) { return !(c & ~0x7F); }
inline bool isASCIIAlpha(char c) { return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; }
inline bool isASCIIAlpha(unsigned short c) { return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; }
@@ -56,6 +57,7 @@ namespace WTF {
inline bool isASCIIAlpha(wchar_t c) { return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; }
#endif
inline bool isASCIIAlpha(int c) { return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; }
+ inline bool isASCIIAlpha(unsigned c) { return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; }
inline bool isASCIIAlphanumeric(char c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'z'); }
inline bool isASCIIAlphanumeric(unsigned short c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'z'); }
@@ -63,6 +65,7 @@ namespace WTF {
inline bool isASCIIAlphanumeric(wchar_t c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'z'); }
#endif
inline bool isASCIIAlphanumeric(int c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'z'); }
+ inline bool isASCIIAlphanumeric(unsigned c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'z'); }
inline bool isASCIIDigit(char c) { return (c >= '0') & (c <= '9'); }
inline bool isASCIIDigit(unsigned short c) { return (c >= '0') & (c <= '9'); }
@@ -70,6 +73,7 @@ namespace WTF {
inline bool isASCIIDigit(wchar_t c) { return (c >= '0') & (c <= '9'); }
#endif
inline bool isASCIIDigit(int c) { return (c >= '0') & (c <= '9'); }
+ inline bool isASCIIDigit(unsigned c) { return (c >= '0') & (c <= '9'); }
inline bool isASCIIHexDigit(char c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'); }
inline bool isASCIIHexDigit(unsigned short c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'); }
@@ -77,6 +81,7 @@ namespace WTF {
inline bool isASCIIHexDigit(wchar_t c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'); }
#endif
inline bool isASCIIHexDigit(int c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'); }
+ inline bool isASCIIHexDigit(unsigned c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'); }
inline bool isASCIIOctalDigit(char c) { return (c >= '0') & (c <= '7'); }
inline bool isASCIIOctalDigit(unsigned short c) { return (c >= '0') & (c <= '7'); }
@@ -84,6 +89,7 @@ namespace WTF {
inline bool isASCIIOctalDigit(wchar_t c) { return (c >= '0') & (c <= '7'); }
#endif
inline bool isASCIIOctalDigit(int c) { return (c >= '0') & (c <= '7'); }
+ inline bool isASCIIOctalDigit(unsigned c) { return (c >= '0') & (c <= '7'); }
inline bool isASCIILower(char c) { return c >= 'a' && c <= 'z'; }
inline bool isASCIILower(unsigned short c) { return c >= 'a' && c <= 'z'; }
@@ -91,6 +97,7 @@ namespace WTF {
inline bool isASCIILower(wchar_t c) { return c >= 'a' && c <= 'z'; }
#endif
inline bool isASCIILower(int c) { return c >= 'a' && c <= 'z'; }
+ inline bool isASCIILower(unsigned c) { return c >= 'a' && c <= 'z'; }
inline bool isASCIIUpper(char c) { return c >= 'A' && c <= 'Z'; }
inline bool isASCIIUpper(unsigned short c) { return c >= 'A' && c <= 'Z'; }
@@ -98,6 +105,7 @@ namespace WTF {
inline bool isASCIIUpper(wchar_t c) { return c >= 'A' && c <= 'Z'; }
#endif
inline bool isASCIIUpper(int c) { return c >= 'A' && c <= 'Z'; }
+ inline bool isASCIIUpper(unsigned c) { return c >= 'A' && c <= 'Z'; }
/*
Statistics from a run of Apple's page load test for callers of isASCIISpace:
@@ -118,6 +126,7 @@ namespace WTF {
inline bool isASCIISpace(wchar_t c) { return c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); }
#endif
inline bool isASCIISpace(int c) { return c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); }
+ inline bool isASCIISpace(unsigned c) { return c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); }
inline char toASCIILower(char c) { return c | ((c >= 'A' && c <= 'Z') << 5); }
inline unsigned short toASCIILower(unsigned short c) { return c | ((c >= 'A' && c <= 'Z') << 5); }
@@ -125,13 +134,16 @@ namespace WTF {
inline wchar_t toASCIILower(wchar_t c) { return c | ((c >= 'A' && c <= 'Z') << 5); }
#endif
inline int toASCIILower(int c) { return c | ((c >= 'A' && c <= 'Z') << 5); }
+ inline unsigned toASCIILower(unsigned c) { return c | ((c >= 'A' && c <= 'Z') << 5); }
+ // FIXME: Why do these need static_cast?
inline char toASCIIUpper(char c) { return static_cast<char>(c & ~((c >= 'a' && c <= 'z') << 5)); }
inline unsigned short toASCIIUpper(unsigned short c) { return static_cast<unsigned short>(c & ~((c >= 'a' && c <= 'z') << 5)); }
#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
inline wchar_t toASCIIUpper(wchar_t c) { return static_cast<wchar_t>(c & ~((c >= 'a' && c <= 'z') << 5)); }
#endif
inline int toASCIIUpper(int c) { return static_cast<int>(c & ~((c >= 'a' && c <= 'z') << 5)); }
+ inline unsigned toASCIIUpper(unsigned c) { return static_cast<unsigned>(c & ~((c >= 'a' && c <= 'z') << 5)); }
inline int toASCIIHexValue(char c) { ASSERT(isASCIIHexDigit(c)); return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF; }
inline int toASCIIHexValue(unsigned short c) { ASSERT(isASCIIHexDigit(c)); return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF; }
@@ -139,6 +151,7 @@ namespace WTF {
inline int toASCIIHexValue(wchar_t c) { ASSERT(isASCIIHexDigit(c)); return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF; }
#endif
inline int toASCIIHexValue(int c) { ASSERT(isASCIIHexDigit(c)); return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF; }
+ inline int toASCIIHexValue(unsigned c) { ASSERT(isASCIIHexDigit(c)); return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF; }
inline bool isASCIIPrintable(char c) { return c >= ' ' && c <= '~'; }
inline bool isASCIIPrintable(unsigned short c) { return c >= ' ' && c <= '~'; }
@@ -146,6 +159,7 @@ namespace WTF {
inline bool isASCIIPrintable(wchar_t c) { return c >= ' ' && c <= '~'; }
#endif
inline bool isASCIIPrintable(int c) { return c >= ' ' && c <= '~'; }
+ inline bool isASCIIPrintable(unsigned c) { return c >= ' ' && c <= '~'; }
}
using WTF::isASCII;
diff --git a/JavaScriptCore/wtf/BumpPointerAllocator.h b/JavaScriptCore/wtf/BumpPointerAllocator.h
index 3deefe6..682283c 100644
--- a/JavaScriptCore/wtf/BumpPointerAllocator.h
+++ b/JavaScriptCore/wtf/BumpPointerAllocator.h
@@ -138,10 +138,7 @@ private:
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();
+ m_allocation.deallocate();
}
static BumpPointerPool* ensureCapacityCrossPool(BumpPointerPool* previousPool, size_t size)
diff --git a/JavaScriptCore/wtf/CMakeLists.txt b/JavaScriptCore/wtf/CMakeLists.txt
index 898d19b..98cd7e4 100644
--- a/JavaScriptCore/wtf/CMakeLists.txt
+++ b/JavaScriptCore/wtf/CMakeLists.txt
@@ -9,6 +9,7 @@ SET(WTF_SOURCES
MD5.cpp
RandomNumber.cpp
RefCountedLeakCounter.cpp
+ StackBounds.cpp
StringExtras.cpp
Threading.cpp
TypeTraits.cpp
diff --git a/JavaScriptCore/wtf/CMakeListsWinCE.txt b/JavaScriptCore/wtf/CMakeListsWinCE.txt
new file mode 100644
index 0000000..ed38c6f
--- /dev/null
+++ b/JavaScriptCore/wtf/CMakeListsWinCE.txt
@@ -0,0 +1,20 @@
+LIST(APPEND WTF_SOURCES
+ NullPtr.cpp
+ OSAllocatorWin.cpp
+ TCSystemAlloc.cpp
+ ThreadingWin.cpp
+ ThreadSpecificWin.cpp
+
+ unicode/CollatorDefault.cpp
+ unicode/wince/UnicodeWinCE.cpp
+
+ win/MainThreadWin.cpp
+ win/OwnPtrWin.cpp
+
+ ${3RDPARTY_DIR}/ce-compat/ce_time.c
+ ${3RDPARTY_DIR}/ce-compat/ce_unicode.cpp
+)
+
+LIST(APPEND WTF_LIBRARIES
+ mmtimer
+)
diff --git a/JavaScriptCore/wtf/Complex.h b/JavaScriptCore/wtf/Complex.h
index 7da8511..40fe56a 100644
--- a/JavaScriptCore/wtf/Complex.h
+++ b/JavaScriptCore/wtf/Complex.h
@@ -43,4 +43,7 @@ inline Complex complexFromMagnitudePhase(double magnitude, double phase)
} // namespace WTF
+using WTF::Complex;
+using WTF::complexFromMagnitudePhase;
+
#endif // WTF_Complex_h
diff --git a/JavaScriptCore/wtf/DateMath.cpp b/JavaScriptCore/wtf/DateMath.cpp
index f3627e6..8873352 100644
--- a/JavaScriptCore/wtf/DateMath.cpp
+++ b/JavaScriptCore/wtf/DateMath.cpp
@@ -379,7 +379,7 @@ int equivalentYearForDST(int year)
return year;
}
-static int32_t calculateUTCOffset()
+int32_t calculateUTCOffset()
{
#if PLATFORM(BREWMP)
time_t localTime = static_cast<time_t>(currentTime());
@@ -449,7 +449,7 @@ static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset
}
// Get the DST offset, given a time in UTC
-static double calculateDSTOffset(double ms, double utcOffset)
+double calculateDSTOffset(double ms, double utcOffset)
{
// On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will return historically accurate
// DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript
@@ -1129,7 +1129,7 @@ void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, Gregori
tm.year = year - 1900;
tm.isDST = dstOff != 0.0;
tm.utcOffset = static_cast<long>((dstOff + utcOff) / WTF::msPerSecond);
- tm.timeZone = NULL;
+ tm.timeZone = nullptr;
}
double parseDateFromNullTerminatedCharacters(ExecState* exec, const char* dateString)
diff --git a/JavaScriptCore/wtf/DateMath.h b/JavaScriptCore/wtf/DateMath.h
index be51947..8d0d932 100644
--- a/JavaScriptCore/wtf/DateMath.h
+++ b/JavaScriptCore/wtf/DateMath.h
@@ -2,6 +2,7 @@
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Research In Motion Limited. All rights reserved.
*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -47,6 +48,8 @@
#include <time.h>
#include <wtf/CurrentTime.h>
#include <wtf/Noncopyable.h>
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/PassOwnArrayPtr.h>
#include <wtf/UnusedParam.h>
namespace WTF {
@@ -84,18 +87,26 @@ int dayInYear(double ms, int year);
int monthFromDayInYear(int dayInYear, bool leapYear);
int dayInMonthFromDayInYear(int dayInYear, bool leapYear);
+// Returns offset milliseconds for UTC and DST.
+int32_t calculateUTCOffset();
+double calculateDSTOffset(double ms, double utcOffset);
+
} // namespace WTF
+using WTF::adoptArrayPtr;
using WTF::dateToDaysFrom1970;
using WTF::dayInMonthFromDayInYear;
using WTF::dayInYear;
using WTF::minutesPerHour;
using WTF::monthFromDayInYear;
using WTF::msPerDay;
+using WTF::msPerMinute;
using WTF::msPerSecond;
using WTF::msToYear;
using WTF::secondsPerMinute;
using WTF::parseDateFromNullTerminatedCharacters;
+using WTF::calculateUTCOffset;
+using WTF::calculateDSTOffset;
#if USE(JSC)
namespace JSC {
@@ -125,11 +136,6 @@ struct GregorianDateTime : Noncopyable {
{
}
- ~GregorianDateTime()
- {
- delete [] timeZone;
- }
-
GregorianDateTime(ExecState* exec, const tm& inTm)
: second(inTm.tm_sec)
, minute(inTm.tm_min)
@@ -150,10 +156,10 @@ struct GregorianDateTime : Noncopyable {
#if HAVE(TM_ZONE)
int inZoneSize = strlen(inTm.tm_zone) + 1;
- timeZone = new char[inZoneSize];
- strncpy(timeZone, inTm.tm_zone, inZoneSize);
+ timeZone = adoptArrayPtr(new char[inZoneSize]);
+ strncpy(timeZone.get(), inTm.tm_zone, inZoneSize);
#else
- timeZone = 0;
+ timeZone = nullptr;
#endif
}
@@ -176,7 +182,7 @@ struct GregorianDateTime : Noncopyable {
ret.tm_gmtoff = static_cast<long>(utcOffset);
#endif
#if HAVE(TM_ZONE)
- ret.tm_zone = timeZone;
+ ret.tm_zone = timeZone.get();
#endif
return ret;
@@ -195,11 +201,11 @@ struct GregorianDateTime : Noncopyable {
isDST = rhs.isDST;
utcOffset = rhs.utcOffset;
if (rhs.timeZone) {
- int inZoneSize = strlen(rhs.timeZone) + 1;
- timeZone = new char[inZoneSize];
- strncpy(timeZone, rhs.timeZone, inZoneSize);
+ int inZoneSize = strlen(rhs.timeZone.get()) + 1;
+ timeZone = adoptArrayPtr(new char[inZoneSize]);
+ strncpy(timeZone.get(), rhs.timeZone.get(), inZoneSize);
} else
- timeZone = 0;
+ timeZone = nullptr;
}
int second;
@@ -212,7 +218,7 @@ struct GregorianDateTime : Noncopyable {
int year;
int isDST;
int utcOffset;
- char* timeZone;
+ OwnArrayPtr<char> timeZone;
};
static inline int gmtoffset(const GregorianDateTime& t)
diff --git a/JavaScriptCore/wtf/MathExtras.h b/JavaScriptCore/wtf/MathExtras.h
index 8a8741c..095549e 100644
--- a/JavaScriptCore/wtf/MathExtras.h
+++ b/JavaScriptCore/wtf/MathExtras.h
@@ -145,6 +145,13 @@ inline float nextafterf(float x, float y) { return x > y ? x - FLT_EPSILON : x +
inline double copysign(double x, double y) { return _copysign(x, y); }
inline int isfinite(double x) { return _finite(x); }
+// MSVC's math.h does not currently supply log2.
+inline double log2(double num)
+{
+ // This constant is roughly M_LN2, which is not provided by default on Windows.
+ return log(num) / 0.693147180559945309417232121458176568;
+}
+
// Work around a bug in Win, where atan2(+-infinity, +-infinity) yields NaN instead of specific values.
inline double wtf_atan2(double x, double y)
{
diff --git a/JavaScriptCore/wtf/OSAllocator.h b/JavaScriptCore/wtf/OSAllocator.h
new file mode 100644
index 0000000..577a6b8
--- /dev/null
+++ b/JavaScriptCore/wtf/OSAllocator.h
@@ -0,0 +1,100 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OSAllocator_h
+#define OSAllocator_h
+
+#include <wtf/UnusedParam.h>
+#include <wtf/VMTags.h>
+#include <wtf/VMTags.h>
+
+namespace WTF {
+
+class OSAllocator {
+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,
+ };
+
+ // These methods are symmetric; reserveUncommitted allocates VM in an uncommitted state,
+ // releaseDecommitted should be called on a region of VM allocated by a single reservation,
+ // the memory must all currently be in a decommitted state.
+ static void* reserveUncommitted(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false);
+ static void releaseDecommitted(void*, size_t);
+
+ // These methods are symmetric; they commit or decommit a region of VM (uncommitted VM should
+ // never be accessed, since the OS may not have attached physical memory for these regions).
+ // Clients should only call commit on uncommitted regions and decommit on committed regions.
+ static void commit(void*, size_t, bool writable, bool executable);
+ static void decommit(void*, size_t);
+
+ // These methods are symmetric; reserveAndCommit allocates VM in an committed state,
+ // decommitAndRelease should be called on a region of VM allocated by a single reservation,
+ // the memory must all currently be in a committed state.
+ static void* reserveAndCommit(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false);
+ static void decommitAndRelease(void* base, size_t size);
+
+ // These methods are akin to reserveAndCommit/decommitAndRelease, above - however rather than
+ // committing/decommitting the entire region additional parameters allow a subregion to be
+ // specified.
+ static void* reserveAndCommit(size_t reserveSize, size_t commitSize, Usage = UnknownUsage, bool writable = true, bool executable = false);
+ static void decommitAndRelease(void* releaseBase, size_t releaseSize, void* decommitBase, size_t decommitSize);
+};
+
+inline void* OSAllocator::reserveAndCommit(size_t reserveSize, size_t commitSize, Usage usage, bool writable, bool executable)
+{
+ void* base = reserveUncommitted(reserveSize, usage, writable, executable);
+ commit(base, commitSize, writable, executable);
+ return base;
+}
+
+inline void OSAllocator::decommitAndRelease(void* releaseBase, size_t releaseSize, void* decommitBase, size_t decommitSize)
+{
+ ASSERT(decommitBase >= releaseBase && (static_cast<char*>(decommitBase) + decommitSize) <= (static_cast<char*>(releaseBase) + releaseSize));
+#if OS(WINCE)
+ // On most platforms we can actually skip this final decommit; releasing the VM will
+ // implicitly decommit any physical memory in the region. This is not true on WINCE.
+ decommit(decommitBase, decommitSize);
+#else
+ UNUSED_PARAM(decommitBase);
+ UNUSED_PARAM(decommitSize);
+#endif
+ releaseDecommitted(releaseBase, releaseSize);
+}
+
+inline void OSAllocator::decommitAndRelease(void* base, size_t size)
+{
+ decommitAndRelease(base, size, base, size);
+}
+
+} // namespace WTF
+
+using WTF::OSAllocator;
+
+#endif // OSAllocator_h
diff --git a/JavaScriptCore/wtf/OSAllocatorPosix.cpp b/JavaScriptCore/wtf/OSAllocatorPosix.cpp
new file mode 100644
index 0000000..5546cef
--- /dev/null
+++ b/JavaScriptCore/wtf/OSAllocatorPosix.cpp
@@ -0,0 +1,121 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "OSAllocator.h"
+
+#include <errno.h>
+#include <sys/mman.h>
+#include <wtf/Assertions.h>
+#include <wtf/UnusedParam.h>
+
+namespace WTF {
+
+void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable, bool executable)
+{
+ void* result = reserveAndCommit(bytes, usage, writable, executable);
+#if HAVE(MADV_FREE_REUSE)
+ // To support the "reserve then commit" model, we have to initially decommit.
+ while (madvise(result, bytes, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
+#endif
+ return result;
+}
+
+void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable)
+{
+ // All POSIX reservations start out logically committed.
+ int protection = PROT_READ;
+ if (writable)
+ protection |= PROT_WRITE;
+ if (executable)
+ protection |= PROT_EXEC;
+
+ int flags = MAP_PRIVATE | MAP_ANON;
+
+#if OS(DARWIN) && !defined(BUILDING_ON_TIGER)
+ int fd = usage;
+#else
+ int fd = -1;
+#endif
+
+ void* result = 0;
+#if (OS(DARWIN) && CPU(X86_64))
+ if (executable) {
+ // Cook up an address to allocate at, using the following recipe:
+ // 17 bits of zero, stay in userspace kids.
+ // 26 bits of randomness for ASLR.
+ // 21 bits of zero, at least stay aligned within one level of the pagetables.
+ //
+ // 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 userspace (in the address range
+ // 0x200000000000 .. 0x5fffffffffff).
+ intptr_t randomLocation = 0;
+ randomLocation = arc4random() & ((1 << 25) - 1);
+ randomLocation += (1 << 24);
+ randomLocation <<= 21;
+ result = reinterpret_cast<void*>(randomLocation);
+ }
+#endif
+
+ result = mmap(result, bytes, protection, flags, fd, 0);
+ if (result == MAP_FAILED)
+ CRASH();
+ return result;
+}
+
+void OSAllocator::commit(void* address, size_t bytes, bool, bool)
+{
+#if HAVE(MADV_FREE_REUSE)
+ while (madvise(address, bytes, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { }
+#else
+ // Non-MADV_FREE_REUSE reservations automatically commit on demand.
+ UNUSED_PARAM(address);
+ UNUSED_PARAM(bytes);
+#endif
+}
+
+void OSAllocator::decommit(void* address, size_t bytes)
+{
+#if HAVE(MADV_FREE_REUSE)
+ while (madvise(address, bytes, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
+#elif HAVE(MADV_FREE)
+ while (madvise(address, bytes, MADV_FREE) == -1 && errno == EAGAIN) { }
+#elif HAVE(MADV_DONTNEED)
+ while (madvise(address, bytes, MADV_DONTNEED) == -1 && errno == EAGAIN) { }
+#else
+ UNUSED_PARAM(address);
+ UNUSED_PARAM(bytes);
+#endif
+}
+
+void OSAllocator::releaseDecommitted(void* address, size_t bytes)
+{
+ int result = munmap(address, bytes);
+ if (result == -1)
+ CRASH();
+}
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/OSAllocatorSymbian.cpp b/JavaScriptCore/wtf/OSAllocatorSymbian.cpp
new file mode 100644
index 0000000..e746fde
--- /dev/null
+++ b/JavaScriptCore/wtf/OSAllocatorSymbian.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "OSAllocator.h"
+
+#include <wtf/FastMalloc.h>
+
+namespace WTF {
+
+void* OSAllocator::reserveUncommitted(size_t bytes, Usage, bool, bool)
+{
+ return fastMalloc(bytes);
+}
+
+void* OSAllocator::reserveAndCommit(size_t bytes, Usage, bool, bool)
+{
+ return fastMalloc(bytes);
+}
+
+void OSAllocator::commit(void*, size_t, bool, bool)
+{
+}
+
+void OSAllocator::decommit(void*, size_t)
+{
+}
+
+void OSAllocator::releaseDecommitted(void* address, size_t)
+{
+ fastFree(address);
+}
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/OSAllocatorWin.cpp b/JavaScriptCore/wtf/OSAllocatorWin.cpp
new file mode 100644
index 0000000..e7beb8a
--- /dev/null
+++ b/JavaScriptCore/wtf/OSAllocatorWin.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "OSAllocator.h"
+
+#include "windows.h"
+#include <wtf/Assertions.h>
+
+namespace WTF {
+
+static inline DWORD protection(bool writable, bool executable)
+{
+ return executable ?
+ (writable ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ) :
+ (writable ? PAGE_READWRITE : PAGE_READONLY);
+}
+
+void* OSAllocator::reserveUncommitted(size_t bytes, Usage, bool writable, bool executable)
+{
+ void* result = VirtualAlloc(0, bytes, MEM_RESERVE, protection(writable, executable));
+ if (!result)
+ CRASH();
+ return result;
+}
+
+void* OSAllocator::reserveAndCommit(size_t bytes, Usage, bool writable, bool executable)
+{
+ void* result = VirtualAlloc(0, bytes, MEM_RESERVE | MEM_COMMIT, protection(writable, executable));
+ if (!result)
+ CRASH();
+ return result;
+}
+
+void OSAllocator::commit(void* address, size_t bytes, bool writable, bool executable)
+{
+ void* result = VirtualAlloc(address, bytes, MEM_COMMIT, protection(writable, executable));
+ if (!result)
+ CRASH();
+}
+
+void OSAllocator::decommit(void* address, size_t bytes)
+{
+ bool result = VirtualFree(address, bytes, MEM_DECOMMIT);
+ if (!result)
+ CRASH();
+}
+
+void OSAllocator::releaseDecommitted(void* address, size_t bytes)
+{
+ // According to http://msdn.microsoft.com/en-us/library/aa366892(VS.85).aspx,
+ // dwSize must be 0 if dwFreeType is MEM_RELEASE.
+ bool result = VirtualFree(address, 0, MEM_RELEASE);
+ if (!result)
+ CRASH();
+}
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/PageAllocation.h b/JavaScriptCore/wtf/PageAllocation.h
index 26d53a5..232cd20 100644
--- a/JavaScriptCore/wtf/PageAllocation.h
+++ b/JavaScriptCore/wtf/PageAllocation.h
@@ -27,8 +27,11 @@
#define PageAllocation_h
#include <wtf/Assertions.h>
+#include <wtf/OSAllocator.h>
+#include <wtf/PageBlock.h>
#include <wtf/UnusedParam.h>
#include <wtf/VMTags.h>
+#include <algorithm>
#if OS(DARWIN)
#include <mach/mach_init.h>
@@ -74,287 +77,45 @@ namespace WTF {
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 {
- 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,
- };
+class PageAllocation : private PageBlock {
+public:
PageAllocation()
- : m_base(0)
- , m_size(0)
-#if OS(SYMBIAN)
- , m_chunk(0)
-#endif
- {
- }
-
- bool operator!() const { return !m_base; }
- void* base() const { return m_base; }
- size_t size() const { return m_size; }
-
- static PageAllocation allocate(size_t size, Usage usage = UnknownUsage, bool writable = true, bool executable = false)
{
- ASSERT(isPageAligned(size));
- return systemAllocate(size, usage, writable, executable);
}
-#if HAVE(PAGE_ALLOCATE_AT)
- static PageAllocation allocateAt(void* address, bool fixed, size_t size, Usage usage = UnknownUsage, bool writable = true, bool executable = false)
- {
- ASSERT(isPageAligned(address));
- ASSERT(isPageAligned(size));
- return systemAllocateAt(address, fixed, size, usage, writable, executable);
- }
-#endif
+ using PageBlock::operator bool;
+ using PageBlock::size;
+ using PageBlock::base;
-#if HAVE(PAGE_ALLOCATE_ALIGNED)
- static PageAllocation allocateAligned(size_t size, Usage usage = UnknownUsage)
+ static PageAllocation allocate(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false)
{
ASSERT(isPageAligned(size));
- ASSERT(isPowerOfTwo(size));
- return systemAllocateAligned(size, usage);
+ return PageAllocation(OSAllocator::reserveAndCommit(size, usage, writable, executable), size);
}
-#endif
void deallocate()
{
- ASSERT(m_base);
- systemDeallocate(true);
- }
-
- static size_t pageSize()
- {
- if (!s_pageSize)
- s_pageSize = systemPageSize();
- ASSERT(isPowerOfTwo(s_pageSize));
- return s_pageSize;
- }
+ // Clear base & size before calling release; if this is *inside* allocation
+ // then we won't be able to clear then after deallocating the memory.
+ PageAllocation tmp;
+ std::swap(tmp, *this);
-#ifndef NDEBUG
- static bool isPageAligned(void* address) { return !(reinterpret_cast<intptr_t>(address) & (pageSize() - 1)); }
- static bool isPageAligned(size_t size) { return !(size & (pageSize() - 1)); }
- static bool isPowerOfTwo(size_t size) { return !(size & (size - 1)); }
- static int lastError();
-#endif
+ ASSERT(tmp);
+ ASSERT(!*this);
-protected:
-#if OS(SYMBIAN)
- PageAllocation(void* base, size_t size, RChunk* chunk)
- : m_base(base)
- , m_size(size)
- , m_chunk(chunk)
- {
+ OSAllocator::decommitAndRelease(tmp.base(), tmp.size());
}
-#else
+
+private:
PageAllocation(void* base, size_t size)
- : m_base(base)
- , m_size(size)
+ : PageBlock(base, size)
{
}
-#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(MMAP)
-
-
-inline PageAllocation PageAllocation::systemAllocate(size_t size, Usage usage, bool writable, bool executable)
-{
- return systemAllocateAt(0, false, size, usage, writable, executable);
-}
-
-inline PageAllocation PageAllocation::systemAllocateAt(void* address, bool fixed, size_t size, Usage usage, bool writable, bool executable)
-{
- 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
- int fd = -1;
-#endif
-
- void* base = mmap(address, size, protection, flags, fd, 0);
- if (base == MAP_FAILED)
- base = 0;
- return PageAllocation(base, size);
-}
-
-inline PageAllocation PageAllocation::systemAllocateAligned(size_t size, Usage usage)
-{
-#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);
-#else
- size_t extra = size - pageSize();
-
- // Check for overflow.
- if ((size + extra) < size)
- return PageAllocation(0, size);
-
-#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
-
-
-}
+} // namespace WTF
using WTF::PageAllocation;
diff --git a/JavaScriptCore/wtf/PageAllocationAligned.cpp b/JavaScriptCore/wtf/PageAllocationAligned.cpp
new file mode 100644
index 0000000..6f54710
--- /dev/null
+++ b/JavaScriptCore/wtf/PageAllocationAligned.cpp
@@ -0,0 +1,87 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PageAllocationAligned.h"
+
+namespace WTF {
+
+PageAllocationAligned PageAllocationAligned::allocate(size_t size, size_t alignment, OSAllocator::Usage usage, bool writable, bool executable)
+{
+ ASSERT(isPageAligned(size));
+ ASSERT(isPageAligned(alignment));
+ ASSERT(isPowerOfTwo(alignment));
+ ASSERT(size >= alignment);
+ size_t alignmentMask = alignment - 1;
+
+#if OS(DARWIN)
+ int flags = VM_FLAGS_ANYWHERE;
+ if (usage != OSAllocator::UnknownUsage)
+ flags |= usage;
+ int protection = PROT_READ;
+ if (writable)
+ protection |= PROT_WRITE;
+ if (executable)
+ protection |= PROT_EXEC;
+
+ vm_address_t address = 0;
+ vm_map(current_task(), &address, size, alignmentMask, flags, MEMORY_OBJECT_NULL, 0, FALSE, protection, PROT_READ | PROT_WRITE | PROT_EXEC, VM_INHERIT_DEFAULT);
+ return PageAllocationAligned(reinterpret_cast<void*>(address), size);
+#else
+ size_t alignmentDelta = alignment - pageSize();
+
+ // Resererve with suffcient additional VM to correctly align.
+ size_t reservationSize = size + alignmentDelta;
+ void* reservationBase = OSAllocator::reserveUncommitted(reservationSize, usage, writable, executable);
+
+ // Select an aligned region within the reservation and commit.
+ void* alignedBase = reinterpret_cast<uintptr_t>(reservationBase) & alignmentMask
+ ? reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(reservationBase) & ~alignmentMask) + alignment)
+ : reservationBase;
+ OSAllocator::commit(alignedBase, size, writable, executable);
+
+ return PageAllocationAligned(alignedBase, size, reservationBase, reservationSize);
+#endif
+}
+
+void PageAllocationAligned::deallocate()
+{
+ // Clear base & size before calling release; if this is *inside* allocation
+ // then we won't be able to clear then after deallocating the memory.
+ PageAllocationAligned tmp;
+ std::swap(tmp, *this);
+
+ ASSERT(tmp);
+ ASSERT(!*this);
+
+#if OS(DARWIN)
+ vm_deallocate(current_task(), reinterpret_cast<vm_address_t>(tmp.base()), tmp.size());
+#else
+ ASSERT(tmp.m_reservation.contains(tmp.base(), tmp.size()));
+ OSAllocator::decommitAndRelease(tmp.m_reservation.base(), tmp.m_reservation.size(), tmp.base(), tmp.size());
+#endif
+}
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/PageAllocationAligned.h b/JavaScriptCore/wtf/PageAllocationAligned.h
new file mode 100644
index 0000000..282c9e3
--- /dev/null
+++ b/JavaScriptCore/wtf/PageAllocationAligned.h
@@ -0,0 +1,70 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PageAllocationAligned_h
+#define PageAllocationAligned_h
+
+#include <wtf/OSAllocator.h>
+#include <wtf/PageReservation.h>
+
+namespace WTF {
+
+class PageAllocationAligned : private PageBlock {
+public:
+ PageAllocationAligned()
+ {
+ }
+
+ using PageBlock::operator bool;
+ using PageBlock::size;
+ using PageBlock::base;
+
+ static PageAllocationAligned allocate(size_t size, size_t alignment, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false);
+
+ void deallocate();
+
+private:
+#if OS(DARWIN)
+ PageAllocationAligned(void* base, size_t size)
+ : PageBlock(base, size)
+ {
+ }
+#else
+ PageAllocationAligned(void* base, size_t size, void* reservationBase, size_t reservationSize)
+ : PageBlock(base, size)
+ , m_reservation(reservationBase, reservationSize)
+ {
+ }
+
+ PageBlock m_reservation;
+#endif
+};
+
+
+} // namespace WTF
+
+using WTF::PageAllocationAligned;
+
+#endif // PageAllocationAligned_h
diff --git a/JavaScriptCore/wtf/PageBlock.cpp b/JavaScriptCore/wtf/PageBlock.cpp
new file mode 100644
index 0000000..6fb68e5
--- /dev/null
+++ b/JavaScriptCore/wtf/PageBlock.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PageBlock.h"
+
+#if OS(UNIX) && !OS(SYMBIAN)
+#include <unistd.h>
+#endif
+
+#if OS(WINDOWS)
+#include <malloc.h>
+#include <windows.h>
+#endif
+
+#if OS(SYMBIAN)
+#include <e32hal.h>
+#include <e32std.h>
+#endif
+
+namespace WTF {
+
+static size_t s_pageSize;
+
+#if OS(UNIX) && !OS(SYMBIAN)
+
+inline size_t systemPageSize()
+{
+ return getpagesize();
+}
+
+#elif OS(WINDOWS)
+
+inline size_t systemPageSize()
+{
+ static size_t size = 0;
+ SYSTEM_INFO system_info;
+ GetSystemInfo(&system_info);
+ size = system_info.dwPageSize;
+ return size;
+}
+
+#elif OS(SYMBIAN)
+
+inline size_t systemPageSize()
+{
+ static TInt page_size = 0;
+ UserHal::PageSizeInBytes(page_size);
+ return page_size;
+}
+
+#endif
+
+size_t pageSize()
+{
+ if (!s_pageSize)
+ s_pageSize = systemPageSize();
+ ASSERT(isPowerOfTwo(s_pageSize));
+ return s_pageSize;
+}
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/PageBlock.h b/JavaScriptCore/wtf/PageBlock.h
new file mode 100644
index 0000000..07452b3
--- /dev/null
+++ b/JavaScriptCore/wtf/PageBlock.h
@@ -0,0 +1,83 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PageBlock_h
+#define PageBlock_h
+
+namespace WTF {
+
+size_t pageSize();
+inline bool isPageAligned(void* address) { return !(reinterpret_cast<intptr_t>(address) & (pageSize() - 1)); }
+inline bool isPageAligned(size_t size) { return !(size & (pageSize() - 1)); }
+inline bool isPowerOfTwo(size_t size) { return !(size & (size - 1)); }
+
+class PageBlock {
+public:
+ PageBlock();
+ PageBlock(const PageBlock&);
+ PageBlock(void*, size_t);
+
+ void* base() const { return m_base; }
+ size_t size() const { return m_size; }
+
+ operator bool() const { return !!m_base; }
+
+ bool contains(void* containedBase, size_t containedSize)
+ {
+ return containedBase >= m_base
+ && (static_cast<char*>(containedBase) + containedSize) <= (static_cast<char*>(m_base) + m_size);
+ }
+
+private:
+ void* m_base;
+ size_t m_size;
+};
+
+inline PageBlock::PageBlock()
+ : m_base(0)
+ , m_size(0)
+{
+}
+
+inline PageBlock::PageBlock(const PageBlock& other)
+ : m_base(other.m_base)
+ , m_size(other.m_size)
+{
+}
+
+inline PageBlock::PageBlock(void* base, size_t size)
+ : m_base(base)
+ , m_size(size)
+{
+}
+
+} // namespace WTF
+
+using WTF::pageSize;
+using WTF::isPageAligned;
+using WTF::isPageAligned;
+using WTF::isPowerOfTwo;
+
+#endif // PageBlock_h
diff --git a/JavaScriptCore/wtf/PageReservation.h b/JavaScriptCore/wtf/PageReservation.h
index cfc7cd9..8c097a4 100644
--- a/JavaScriptCore/wtf/PageReservation.h
+++ b/JavaScriptCore/wtf/PageReservation.h
@@ -49,208 +49,91 @@ namespace WTF {
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 {
+
+class PageReservation : private PageBlock {
public:
PageReservation()
+ : m_writable(false)
+ , m_executable(false)
+#ifndef NDEBUG
+ , m_committed(0)
+#endif
{
}
+
+ using PageBlock::operator bool;
+ using PageBlock::base;
+ using PageBlock::size;
- using PageAllocation::operator!;
- using PageAllocation::base;
- using PageAllocation::size;
-
- bool commit(void* start, size_t size)
+ void commit(void* start, size_t size)
{
- ASSERT(m_base);
+ ASSERT(*this);
ASSERT(isPageAligned(start));
ASSERT(isPageAligned(size));
+ ASSERT(contains(start, size));
- bool commited = systemCommit(start, size);
#ifndef NDEBUG
- if (commited)
- m_committed += size;
+ m_committed += size;
#endif
- return commited;
+ OSAllocator::commit(start, size, m_writable, m_executable);
}
+
void decommit(void* start, size_t size)
{
- ASSERT(m_base);
+ ASSERT(*this);
ASSERT(isPageAligned(start));
ASSERT(isPageAligned(size));
+ ASSERT(contains(start, size));
#ifndef NDEBUG
m_committed -= size;
#endif
- systemDecommit(start, size);
+ OSAllocator::decommit(start, size);
}
- static PageReservation reserve(size_t size, Usage usage = UnknownUsage, bool writable = true, bool executable = false)
+ static PageReservation reserve(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false)
{
ASSERT(isPageAligned(size));
- return systemReserve(size, usage, writable, executable);
+ return PageReservation(OSAllocator::reserveUncommitted(size, usage, writable, executable), size, 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)
- {
- ASSERT(isPageAligned(address));
- ASSERT(isPageAligned(size));
- return systemReserveAt(address, fixed, size, usage, writable, executable);
- }
-#endif
-
void deallocate()
{
- ASSERT(m_base);
ASSERT(!m_committed);
- systemDeallocate(false);
- }
-#ifndef NDEBUG
- using PageAllocation::lastError;
-#endif
+ // Clear base & size before calling release; if this is *inside* allocation
+ // then we won't be able to clear then after deallocating the memory.
+ PageReservation tmp;
+ std::swap(tmp, *this);
+
+ ASSERT(tmp);
+ ASSERT(!*this);
+
+ OSAllocator::releaseDecommitted(tmp.base(), tmp.size());
+ }
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
+ PageReservation(void* base, size_t size, bool writable, bool executable)
+ : PageBlock(base, size)
+ , m_writable(writable)
+ , m_executable(executable)
#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
+ bool m_writable;
+ bool m_executable;
#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.
- DWORD protection = executable ?
- (writable ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ) :
- (writable ? PAGE_READWRITE : PAGE_READONLY);
- PageReservation reservation(VirtualAlloc(0, size, MEM_RESERVE, protection), size);
- reservation.m_protection = protection;
- return reservation;
-}
-
-
-#elif OS(SYMBIAN)
-
-
-inline bool PageReservation::systemCommit(void* start, size_t size)
-{
- intptr_t offset = reinterpret_cast<intptr_t>(start) - reinterpret_cast<intptr_t>(m_base);
- m_chunk->Commit(offset, size);
- return true;
-}
-
-inline void PageReservation::systemDecommit(void* start, size_t size)
-{
- intptr_t offset = reinterpret_cast<intptr_t>(start) - reinterpret_cast<intptr_t>(m_base);
- 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;
diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h
index 7924a28..4143996 100644
--- a/JavaScriptCore/wtf/Platform.h
+++ b/JavaScriptCore/wtf/Platform.h
@@ -530,6 +530,9 @@
#if PLATFORM(MAC) && !PLATFORM(IOS)
#define WTF_PLATFORM_CI 1
#endif
+#if PLATFORM(MAC) || PLATFORM(IOS) || (PLATFORM(WIN) && PLATFORM(CG))
+#define WTF_PLATFORM_CA 1
+#endif
/* PLATFORM(SKIA) for Win/Linux, CG/CI for Mac */
#if PLATFORM(CHROMIUM)
@@ -823,13 +826,6 @@
#endif
-#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 */
#if PLATFORM(QT)
@@ -1124,6 +1120,10 @@
#define WTF_USE_PLATFORM_STRATEGIES 1
#endif
+#if PLATFORM(WIN)
+#define WTF_USE_CROSS_PLATFORM_CONTEXT_MENUS 1
+#endif
+
/* Geolocation request policy. pre-emptive policy is to acquire user permission before acquiring location.
Client based implementations will have option to choose between pre-emptive and nonpre-emptive permission policy.
pre-emptive permission policy is enabled by default for all client-based implementations. */
diff --git a/JavaScriptCore/wtf/PlatformRefPtr.h b/JavaScriptCore/wtf/PlatformRefPtr.h
index 8ac16cb..e4f1314 100644
--- a/JavaScriptCore/wtf/PlatformRefPtr.h
+++ b/JavaScriptCore/wtf/PlatformRefPtr.h
@@ -74,6 +74,13 @@ public:
derefPlatformPtr(ptr);
}
+ T* leakRef() WARN_UNUSED_RETURN
+ {
+ T* ptr = m_ptr;
+ m_ptr = 0;
+ return ptr;
+ }
+
// Hash table deleted values, which are only constructed and never copied or destroyed.
PlatformRefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
diff --git a/JavaScriptCore/wtf/RandomNumberSeed.h b/JavaScriptCore/wtf/RandomNumberSeed.h
index b53b506..9ea7c71 100644
--- a/JavaScriptCore/wtf/RandomNumberSeed.h
+++ b/JavaScriptCore/wtf/RandomNumberSeed.h
@@ -53,7 +53,7 @@ inline void initializeRandomNumberGenerator()
// On Darwin we use arc4random which initialises itself.
#elif OS(WINCE)
// initialize rand()
- srand(static_cast<unsigned>(time(0)));
+ srand(GetTickCount());
// use rand() to initialize the real RNG
unsigned long initializationBuffer[4];
diff --git a/JavaScriptCore/wtf/StackBounds.cpp b/JavaScriptCore/wtf/StackBounds.cpp
new file mode 100644
index 0000000..2691db1
--- /dev/null
+++ b/JavaScriptCore/wtf/StackBounds.cpp
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "StackBounds.h"
+
+#if OS(DARWIN)
+
+#include <mach/task.h>
+#include <mach/thread_act.h>
+#include <pthread.h>
+
+#elif OS(WINDOWS)
+
+#include <windows.h>
+
+#elif OS(HAIKU)
+
+#include <OS.h>
+
+#elif OS(SOLARIS)
+
+#include <thread.h>
+
+#elif OS(QNX)
+
+#include <fcntl.h>
+#include <sys/procfs.h>
+#include <stdio.h>
+#include <errno.h>
+
+#elif OS(UNIX)
+
+#include <pthread.h>
+#if HAVE(PTHREAD_NP_H)
+#include <pthread_np.h>
+#endif
+
+#endif
+
+namespace WTF {
+
+// Bug 26276 - Need a mechanism to determine stack extent
+//
+// These platforms should now be working correctly:
+// DARWIN, QNX, UNIX
+// These platforms are not:
+// WINDOWS, SOLARIS, OPENBSD, SYMBIAN, HAIKU, WINCE
+//
+// FIXME: remove this! - this code unsafely guesses at stack sizes!
+#if OS(WINDOWS) || OS(SOLARIS) || OS(OPENBSD) || OS(SYMBIAN) || OS(HAIKU) || OS(WINCE)
+// Based on the current limit used by the JSC parser, guess the stack size.
+static const ptrdiff_t estimatedStackSize = 128 * sizeof(void*) * 1024;
+// This method assumes the stack is growing downwards.
+static void* estimateStackBound(void* origin)
+{
+ return static_cast<char*>(origin) - estimatedStackSize;
+}
+#endif
+
+#if OS(DARWIN)
+
+void StackBounds::initialize()
+{
+ pthread_t thread = pthread_self();
+ m_origin = pthread_get_stackaddr_np(thread);
+ m_bound = static_cast<char*>(m_origin) - pthread_get_stacksize_np(thread);
+}
+
+#elif OS(WINDOWS)
+
+void StackBounds::initialize()
+{
+#if CPU(X86) && COMPILER(MSVC)
+ // offset 0x18 from the FS segment register gives a pointer to
+ // the thread information block for the current thread
+ NT_TIB* pTib;
+ __asm {
+ MOV EAX, FS:[18h]
+ MOV pTib, EAX
+ }
+ m_origin = static_cast<void*>(pTib->StackBase);
+#elif OS(WINDOWS) && CPU(X86) && COMPILER(GCC)
+ // offset 0x18 from the FS segment register gives a pointer to
+ // the thread information block for the current thread
+ NT_TIB* pTib;
+ asm ( "movl %%fs:0x18, %0\n"
+ : "=r" (pTib)
+ );
+ m_origin = static_cast<void*>(pTib->StackBase);
+#elif OS(WINDOWS) && CPU(X86_64)
+ PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb());
+ m_origin = reinterpret_cast<void*>(pTib->StackBase);
+#else
+#error Need a way to get the stack bounds on this platform (Windows)
+#endif
+ // Looks like we should be able to get pTib->StackLimit
+ m_bound = estimateStackBound(m_origin);
+}
+
+#elif OS(QNX)
+
+void StackBounds::initialize()
+{
+ void* stackBase = 0;
+ size_t stackSize = 0;
+ pthread_t thread = pthread_self();
+
+ struct _debug_thread_info threadInfo;
+ memset(&threadInfo, 0, sizeof(threadInfo));
+ threadInfo.tid = pthread_self();
+ int fd = open("/proc/self", O_RDONLY);
+ if (fd == -1) {
+ LOG_ERROR("Unable to open /proc/self (errno: %d)", errno);
+ CRASH();
+ }
+ devctl(fd, DCMD_PROC_TIDSTATUS, &threadInfo, sizeof(threadInfo), 0);
+ close(fd);
+ stackBase = reinterpret_cast<void*>(threadInfo.stkbase);
+ stackSize = threadInfo.stksize;
+ ASSERT(stackBase);
+
+ m_bound = stackBase;
+ m_origin = static_cast<char*>(stackBase) + stackSize;
+}
+
+#elif OS(SOLARIS)
+
+void StackBounds::initialize()
+{
+ stack_t s;
+ thr_stksegment(&s);
+ m_origin = s.ss_sp;
+ m_bound = estimateStackBound(m_origin);
+}
+
+#elif OS(OPENBSD)
+
+void StackBounds::initialize()
+{
+ pthread_t thread = pthread_self();
+ stack_t stack;
+ pthread_stackseg_np(thread, &stack);
+ m_origin = stack.ss_sp;
+ m_bound = estimateStackBound(m_origin);
+}
+
+#elif OS(SYMBIAN)
+
+void StackBounds::initialize()
+{
+ TThreadStackInfo info;
+ RThread thread;
+ thread.StackInfo(info);
+ m_origin = (void*)info.iBase;
+ m_bound = estimateStackBound(m_origin);
+}
+
+#elif OS(HAIKU)
+
+void StackBounds::initialize()
+{
+ thread_info threadInfo;
+ get_thread_info(find_thread(NULL), &threadInfo);
+ m_origin = threadInfo.stack_end;
+ m_bound = estimateStackBound(m_origin);
+}
+
+#elif OS(UNIX)
+
+void StackBounds::initialize()
+{
+ void* stackBase = 0;
+ size_t stackSize = 0;
+
+ pthread_t thread = pthread_self();
+ pthread_attr_t sattr;
+ pthread_attr_init(&sattr);
+#if HAVE(PTHREAD_NP_H) || OS(NETBSD)
+ // e.g. on FreeBSD 5.4, neundorf@kde.org
+ pthread_attr_get_np(thread, &sattr);
+#else
+ // FIXME: this function is non-portable; other POSIX systems may have different np alternatives
+ pthread_getattr_np(thread, &sattr);
+#endif
+ int rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize);
+ (void)rc; // FIXME: Deal with error code somehow? Seems fatal.
+ ASSERT(stackBase);
+ pthread_attr_destroy(&sattr);
+ m_bound = stackBase;
+ m_origin = static_cast<char*>(stackBase) + stackSize;
+}
+
+#elif OS(WINCE)
+
+} // namespace WTF
+// FIXME: this is not threadsafe, and should probably be removed.
+namespace JSC { JS_EXPORTDATA void* g_stackBase = 0; }
+namespace WTF {
+
+inline bool isPageWritable(void* page)
+{
+ MEMORY_BASIC_INFORMATION memoryInformation;
+ DWORD result = VirtualQuery(page, &memoryInformation, sizeof(memoryInformation));
+
+ // return false on error, including ptr outside memory
+ if (result != sizeof(memoryInformation))
+ return false;
+
+ DWORD protect = memoryInformation.Protect & ~(PAGE_GUARD | PAGE_NOCACHE);
+ return protect == PAGE_READWRITE
+ || protect == PAGE_WRITECOPY
+ || protect == PAGE_EXECUTE_READWRITE
+ || protect == PAGE_EXECUTE_WRITECOPY;
+}
+
+static void* getStackMax(void* previousFrame, bool& isGrowingDownward)
+{
+ // find the address of this stack frame by taking the address of a local variable
+ void* thisFrame = &thisFrame;
+ isGrowingDownward = previousFrame < &thisFrame;
+
+ if (JSC::g_stackBase)
+ return JSC::g_stackBase;
+
+ SYSTEM_INFO systemInfo;
+ GetSystemInfo(&systemInfo);
+ DWORD pageSize = systemInfo.dwPageSize;
+
+ // scan all of memory starting from this frame, and return the last writeable page found
+ register char* currentPage = (char*)((DWORD)thisFrame & ~(pageSize - 1));
+ if (isGrowingDownward) {
+ while (currentPage > 0) {
+ // check for underflow
+ if (currentPage >= (char*)pageSize)
+ currentPage -= pageSize;
+ else
+ currentPage = 0;
+ if (!isPageWritable(currentPage))
+ return currentPage + pageSize;
+ }
+ return 0;
+ } else {
+ while (true) {
+ // guaranteed to complete because isPageWritable returns false at end of memory
+ currentPage += pageSize;
+ if (!isPageWritable(currentPage))
+ return currentPage;
+ }
+ }
+}
+
+void StackBounds::initialize()
+{
+ bool isGrowingDownward
+ m_origin = getStackMax(isGrowingDownward);
+ m_bound = isGrowingDownward
+ ? static_cast<char*>(m_origin) - estimatedStackSize
+ : static_cast<char*>(m_origin) + estimatedStackSize;
+}
+
+#else
+#error Need a way to get the stack bounds on this platform
+#endif
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/StackBounds.h b/JavaScriptCore/wtf/StackBounds.h
new file mode 100644
index 0000000..afce860
--- /dev/null
+++ b/JavaScriptCore/wtf/StackBounds.h
@@ -0,0 +1,114 @@
+/*
+ * 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 COMPUTER, 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 COMPUTER, 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 StackBounds_h
+#define StackBounds_h
+
+namespace WTF {
+
+class StackBounds {
+ // recursionCheck() / recursionLimit() tests (by default)
+ // that we are at least this far from the end of the stack.
+ const static size_t s_defaultAvailabilityDelta = 4096;
+
+public:
+ StackBounds()
+ : m_origin(0)
+ , m_bound(0)
+ {
+ }
+
+ static StackBounds currentThreadStackBounds()
+ {
+ StackBounds bounds;
+ bounds.initialize();
+ bounds.checkConsistency();
+ return bounds;
+ }
+
+ void* origin() const
+ {
+ ASSERT(m_origin);
+ return m_origin;
+ }
+
+ void* current() const
+ {
+ checkConsistency();
+ void* currentPosition = &currentPosition;
+ return currentPosition;
+ }
+
+ void* recursionLimit(size_t minAvailableDelta = s_defaultAvailabilityDelta) const
+ {
+ checkConsistency();
+ return isGrowingDownward()
+ ? static_cast<char*>(m_bound) + minAvailableDelta
+ : static_cast<char*>(m_bound) - minAvailableDelta;
+ }
+
+ bool recursionCheck(size_t minAvailableDelta = s_defaultAvailabilityDelta) const
+ {
+ checkConsistency();
+ return isGrowingDownward()
+ ? current() >= recursionLimit(minAvailableDelta)
+ : current() <= recursionLimit(minAvailableDelta);
+ }
+
+private:
+ void initialize();
+
+
+ bool isGrowingDownward() const
+ {
+ ASSERT(m_origin && m_bound);
+#if OS(WINCE)
+ return m_origin > m_bound;
+#else
+ return true;
+#endif
+ }
+
+ void checkConsistency() const
+ {
+#if !ASSERT_DISABLED
+ void* currentPosition = &currentPosition;
+ ASSERT(m_origin != m_bound);
+ ASSERT(isGrowingDownward()
+ ? (currentPosition < m_origin && currentPosition > m_bound)
+ : (currentPosition > m_origin && currentPosition < m_bound));
+#endif
+ }
+
+ void* m_origin;
+ void* m_bound;
+};
+
+} // namespace WTF
+
+using WTF::StackBounds;
+
+#endif
diff --git a/JavaScriptCore/wtf/Vector3.h b/JavaScriptCore/wtf/Vector3.h
deleted file mode 100644
index 1850929..0000000
--- a/JavaScriptCore/wtf/Vector3.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2010 Google 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WTF_Vector3_h
-#define WTF_Vector3_h
-
-#include <math.h>
-
-namespace WTF {
-
-class Vector3 {
-public:
- Vector3()
- : m_x(0.0)
- , m_y(0.0)
- , m_z(0.0)
- {
- }
-
- Vector3(double x, double y, double z)
- : m_x(x)
- , m_y(y)
- , m_z(z)
- {
- }
-
- Vector3(const float p[3])
- : m_x(p[0])
- , m_y(p[1])
- , m_z(p[2])
- {
- }
-
- Vector3(const double p[3])
- : m_x(p[0])
- , m_y(p[1])
- , m_z(p[2])
- {
- }
-
- double abs() const
- {
- return sqrt(m_x * m_x + m_y * m_y + m_z * m_z);
- }
-
- bool isZero() const
- {
- return !m_x && !m_y && !m_z;
- }
-
- void normalize()
- {
- double absValue = abs();
- if (!absValue)
- return;
-
- double k = 1.0 / absValue;
- m_x *= k;
- m_y *= k;
- m_z *= k;
- }
-
- double x() const { return m_x; }
- double y() const { return m_y; }
- double z() const { return m_z; }
-
-private:
- double m_x;
- double m_y;
- double m_z;
-};
-
-inline Vector3 operator+(const Vector3& v1, const Vector3& v2)
-{
- return Vector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z());
-}
-
-inline Vector3 operator-(const Vector3& v1, const Vector3& v2)
-{
- return Vector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z());
-}
-
-inline Vector3 operator*(double k, const Vector3& v)
-{
- return Vector3(k * v.x(), k * v.y(), k * v.z());
-}
-
-inline Vector3 operator*(const Vector3& v, double k)
-{
- return Vector3(k * v.x(), k * v.y(), k * v.z());
-}
-
-inline double dot(const Vector3& v1, const Vector3& v2)
-{
- return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z();
-}
-
-inline Vector3 cross(const Vector3& v1, const Vector3& v2)
-{
- double x3 = v1.y() * v2.z() - v1.z() * v2.y();
- double y3 = v1.z() * v2.x() - v1.x() * v2.z();
- double z3 = v1.x() * v2.y() - v1.y() * v2.x();
- return Vector3(x3, y3, z3);
-}
-
-inline double distance(const Vector3& v1, const Vector3& v2)
-{
- return (v1 - v2).abs();
-}
-
-} // WTF
-
-#endif // WTF_Vector3_h
diff --git a/JavaScriptCore/wtf/WTFThreadData.cpp b/JavaScriptCore/wtf/WTFThreadData.cpp
index 702baed..05be8d1 100644
--- a/JavaScriptCore/wtf/WTFThreadData.cpp
+++ b/JavaScriptCore/wtf/WTFThreadData.cpp
@@ -42,9 +42,8 @@ WTFThreadData::WTFThreadData()
, m_defaultIdentifierTable(new JSC::IdentifierTable())
, m_currentIdentifierTable(m_defaultIdentifierTable)
#endif
+ , m_stackBounds(StackBounds::currentThreadStackBounds())
{
- char sample = 0;
- m_approximatedStackStart = &sample;
}
WTFThreadData::~WTFThreadData()
diff --git a/JavaScriptCore/wtf/WTFThreadData.h b/JavaScriptCore/wtf/WTFThreadData.h
index 5019c33..da1b6eb 100644
--- a/JavaScriptCore/wtf/WTFThreadData.h
+++ b/JavaScriptCore/wtf/WTFThreadData.h
@@ -30,6 +30,7 @@
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
+#include <wtf/StackBounds.h>
#include <wtf/text/StringHash.h>
// This was ENABLE(WORKERS) in WebCore, but this is not defined when compiling JSC.
@@ -113,9 +114,9 @@ public:
}
#endif
- char* approximatedStackStart() const
+ const StackBounds& stack() const
{
- return m_approximatedStackStart;
+ return m_stackBounds;
}
private:
@@ -135,7 +136,7 @@ private:
friend WTFThreadData& wtfThreadData();
friend class AtomicStringTable;
- char* m_approximatedStackStart;
+ StackBounds m_stackBounds;
};
inline WTFThreadData& wtfThreadData()
diff --git a/JavaScriptCore/wtf/PageAllocation.cpp b/JavaScriptCore/wtf/brew/StringBrew.cpp
index f3fe997..d8f2e59 100644
--- a/JavaScriptCore/wtf/PageAllocation.cpp
+++ b/JavaScriptCore/wtf/brew/StringBrew.cpp
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2010 Company 100, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -11,38 +10,34 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
-#include "PageAllocation.h"
-#include "PageReservation.h"
+#include "PlatformString.h"
-namespace WTF {
-
-size_t PageAllocation::s_pageSize = 0;
+#include <AEEstd.h>
-#ifndef NDEBUG
+namespace WTF {
-int PageAllocation::lastError()
+// String conversions
+String::String(const AECHAR* string)
{
-#if OS(WINCE)
- return GetLastError();
-#else
- return errno;
-#endif
-}
-
-#endif
+ // It is safe to cast AECHAR to UChar as both of them use 16 bits representation.
+ const UChar* str = reinterpret_cast<const UChar*>(string);
+ const size_t len = std_wstrlen(string);
+ m_impl = StringImpl::create(str, len);
}
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/gobject/GTypedefs.h b/JavaScriptCore/wtf/gobject/GTypedefs.h
index 76d1b1a..0b9a9ea 100644
--- a/JavaScriptCore/wtf/gobject/GTypedefs.h
+++ b/JavaScriptCore/wtf/gobject/GTypedefs.h
@@ -44,7 +44,6 @@ typedef struct _GDir GDir;
typedef struct _GdkAtom* GdkAtom;
typedef struct _GdkCursor GdkCursor;
typedef struct _GdkDragContext GdkDragContext;
-typedef struct _GdkDrawable GdkDrawable;
typedef struct _GdkEventConfigure GdkEventConfigure;
typedef struct _GdkEventExpose GdkEventExpose;
typedef struct _GdkPixbuf GdkPixbuf;
@@ -85,7 +84,9 @@ typedef struct _GtkWindow GtkWindow;
#ifdef GTK_API_VERSION_2
typedef struct _GdkRectangle GdkRectangle;
+typedef struct _GdkDrawable GdkWindow;
#else
+typedef struct _GdkWindow GdkWindow;
typedef struct _cairo_rectangle_int cairo_rectangle_int_t;
typedef cairo_rectangle_int_t GdkRectangle;
#endif
diff --git a/JavaScriptCore/wtf/haiku/StringHaiku.cpp b/JavaScriptCore/wtf/haiku/StringHaiku.cpp
new file mode 100644
index 0000000..fdf4e72
--- /dev/null
+++ b/JavaScriptCore/wtf/haiku/StringHaiku.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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 "PlatformString.h"
+
+#include <String.h>
+#include <wtf/text/CString.h>
+
+namespace WTF {
+
+// String conversions
+String::String(const BString& string)
+{
+ if (string.Length())
+ m_impl = String::fromUTF8(string.String(), string.Length()).impl();
+ else
+ m_impl = StringImpl::empty();
+}
+
+String::operator BString() const
+{
+ BString string;
+ string.SetTo(utf8().data());
+
+ return string;
+}
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/text/AtomicString.cpp b/JavaScriptCore/wtf/text/AtomicString.cpp
index c49a837..acbcd34 100644
--- a/JavaScriptCore/wtf/text/AtomicString.cpp
+++ b/JavaScriptCore/wtf/text/AtomicString.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,9 +27,12 @@
#include <wtf/HashSet.h>
#include <wtf/Threading.h>
#include <wtf/WTFThreadData.h>
+#include <wtf/unicode/UTF8.h>
namespace WTF {
+using namespace Unicode;
+
COMPILE_ASSERT(sizeof(AtomicString) == sizeof(String), atomic_string_and_string_must_be_same_size);
class AtomicStringTable {
@@ -85,7 +89,7 @@ struct CStringTranslator {
if (d[i] != c)
return false;
}
- return s[length] == 0;
+ return !s[length];
}
static void translate(StringImpl*& location, const char* const& c, unsigned hash)
@@ -206,12 +210,44 @@ struct HashAndCharactersTranslator {
}
};
+struct HashAndUTF8Characters {
+ unsigned hash;
+ const char* characters;
+ unsigned length;
+ unsigned utf16Length;
+};
+
+struct HashAndUTF8CharactersTranslator {
+ static unsigned hash(const HashAndUTF8Characters& buffer)
+ {
+ return buffer.hash;
+ }
+
+ static bool equal(StringImpl* const& string, const HashAndUTF8Characters& buffer)
+ {
+ return equalUTF16WithUTF8(string->characters(), string->characters() + string->length(), buffer.characters, buffer.characters + buffer.length);
+ }
+
+ static void translate(StringImpl*& location, const HashAndUTF8Characters& buffer, unsigned hash)
+ {
+ UChar* target;
+ location = StringImpl::createUninitialized(buffer.utf16Length, target).releaseRef();
+
+ const char* source = buffer.characters;
+ if (convertUTF8ToUTF16(&source, source + buffer.length, &target, target + buffer.utf16Length) != conversionOK)
+ ASSERT_NOT_REACHED();
+
+ location->setHash(hash);
+ location->setIsAtomic(true);
+ }
+};
+
PassRefPtr<StringImpl> AtomicString::add(const UChar* s, unsigned length)
{
if (!s)
return 0;
- if (length == 0)
+ if (!length)
return StringImpl::empty();
UCharBuffer buf = { s, length };
@@ -227,7 +263,7 @@ PassRefPtr<StringImpl> AtomicString::add(const UChar* s, unsigned length, unsign
ASSERT(s);
ASSERT(existingHash);
- if (length == 0)
+ if (!length)
return StringImpl::empty();
HashAndCharacters buffer = { existingHash, s, length };
@@ -246,7 +282,7 @@ PassRefPtr<StringImpl> AtomicString::add(const UChar* s)
while (s[length] != UChar(0))
length++;
- if (length == 0)
+ if (!length)
return StringImpl::empty();
UCharBuffer buf = {s, length};
@@ -262,7 +298,7 @@ PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl* r)
if (!r || r->isAtomic())
return r;
- if (r->length() == 0)
+ if (!r->length())
return StringImpl::empty();
StringImpl* result = *stringTable().add(r).first;
@@ -276,7 +312,7 @@ AtomicStringImpl* AtomicString::find(const UChar* s, unsigned length, unsigned e
ASSERT(s);
ASSERT(existingHash);
- if (length == 0)
+ if (!length)
return static_cast<AtomicStringImpl*>(StringImpl::empty());
HashAndCharacters buffer = { existingHash, s, length };
@@ -290,7 +326,7 @@ void AtomicString::remove(StringImpl* r)
{
stringTable().remove(r);
}
-
+
AtomicString AtomicString::lower() const
{
// Note: This is a hot function in the Dromaeo benchmark.
@@ -303,4 +339,36 @@ AtomicString AtomicString::lower() const
return AtomicString(newImpl);
}
+AtomicString AtomicString::fromUTF8(const char* characters, size_t length)
+{
+ if (!characters)
+ return AtomicString();
+
+ if (!length)
+ return emptyAtom;
+
+ HashAndUTF8Characters buffer;
+ buffer.characters = characters;
+ buffer.length = length;
+ buffer.hash = calculateStringHashFromUTF8(characters, characters + length, buffer.utf16Length);
+
+ if (!buffer.hash)
+ return AtomicString();
+
+ pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<HashAndUTF8Characters, HashAndUTF8CharactersTranslator>(buffer);
+
+ // If the string is newly-translated, then we need to adopt it.
+ // The boolean in the pair tells us if that is so.
+ AtomicString atomicString;
+ atomicString.m_string = addResult.second ? adoptRef(*addResult.first) : *addResult.first;
+ return atomicString;
}
+
+AtomicString AtomicString::fromUTF8(const char* characters)
+{
+ if (!characters)
+ return AtomicString();
+ return fromUTF8(characters, strlen(characters));
+}
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/text/AtomicString.h b/JavaScriptCore/wtf/text/AtomicString.h
index 06e63f4..ab5b366 100644
--- a/JavaScriptCore/wtf/text/AtomicString.h
+++ b/JavaScriptCore/wtf/text/AtomicString.h
@@ -108,6 +108,11 @@ public:
operator QString() const { return m_string; }
#endif
+ // AtomicString::fromUTF8 will return a null string if
+ // the input data contains invalid UTF-8 sequences.
+ static AtomicString fromUTF8(const char*, size_t);
+ static AtomicString fromUTF8(const char*);
+
private:
String m_string;
diff --git a/JavaScriptCore/wtf/text/CString.cpp b/JavaScriptCore/wtf/text/CString.cpp
index db6443f..981d77a 100644
--- a/JavaScriptCore/wtf/text/CString.cpp
+++ b/JavaScriptCore/wtf/text/CString.cpp
@@ -49,8 +49,11 @@ void CString::init(const char* str, size_t length)
if (!str)
return;
- if (length >= numeric_limits<size_t>::max())
- CRASH();
+ // We need to be sure we can add 1 to length without overflowing.
+ // Since the passed-in length is the length of an actual existing
+ // string, and we know the string doesn't occupy the entire address
+ // space, we can assert here and there's no need for a runtime check.
+ ASSERT(length < numeric_limits<size_t>::max());
m_buffer = CStringBuffer::create(length + 1);
memcpy(m_buffer->mutableData(), str, length);
diff --git a/JavaScriptCore/wtf/text/StringConcatenate.h b/JavaScriptCore/wtf/text/StringConcatenate.h
index b54a108..92a2d06 100644
--- a/JavaScriptCore/wtf/text/StringConcatenate.h
+++ b/JavaScriptCore/wtf/text/StringConcatenate.h
@@ -68,7 +68,7 @@ template<>
class StringTypeAdapter<char*> {
public:
StringTypeAdapter<char*>(char* buffer)
- : m_buffer((unsigned char*)buffer)
+ : m_buffer(buffer)
, m_length(strlen(buffer))
{
}
@@ -77,12 +77,14 @@ public:
void writeTo(UChar* destination)
{
- for (unsigned i = 0; i < m_length; ++i)
- destination[i] = m_buffer[i];
+ for (unsigned i = 0; i < m_length; ++i) {
+ unsigned char c = m_buffer[i];
+ destination[i] = c;
+ }
}
private:
- const unsigned char* m_buffer;
+ const char* m_buffer;
unsigned m_length;
};
@@ -90,7 +92,7 @@ template<>
class StringTypeAdapter<const char*> {
public:
StringTypeAdapter<const char*>(const char* buffer)
- : m_buffer((unsigned char*)buffer)
+ : m_buffer(buffer)
, m_length(strlen(buffer))
{
}
@@ -99,35 +101,59 @@ public:
void writeTo(UChar* destination)
{
- for (unsigned i = 0; i < m_length; ++i)
- destination[i] = m_buffer[i];
+ for (unsigned i = 0; i < m_length; ++i) {
+ unsigned char c = m_buffer[i];
+ destination[i] = c;
+ }
}
private:
- const unsigned char* m_buffer;
+ const char* m_buffer;
unsigned m_length;
};
template<>
+class StringTypeAdapter<Vector<char> > {
+public:
+ StringTypeAdapter<Vector<char> >(const Vector<char>& buffer)
+ : m_buffer(buffer)
+ {
+ }
+
+ size_t length() { return m_buffer.size(); }
+
+ void writeTo(UChar* destination)
+ {
+ for (size_t i = 0; i < m_buffer.size(); ++i) {
+ unsigned char c = m_buffer[i];
+ destination[i] = c;
+ }
+ }
+
+private:
+ const Vector<char>& m_buffer;
+};
+
+template<>
class StringTypeAdapter<String> {
public:
- StringTypeAdapter<String>(String& string)
- : m_data(string.characters())
- , m_length(string.length())
+ StringTypeAdapter<String>(const String& string)
+ : m_buffer(string)
{
}
- unsigned length() { return m_length; }
+ unsigned length() { return m_buffer.length(); }
void writeTo(UChar* destination)
{
- for (unsigned i = 0; i < m_length; ++i)
- destination[i] = m_data[i];
+ const UChar* data = m_buffer.characters();
+ unsigned length = m_buffer.length();
+ for (unsigned i = 0; i < length; ++i)
+ destination[i] = data[i];
}
private:
- const UChar* m_data;
- unsigned m_length;
+ const String& m_buffer;
};
inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow)
diff --git a/JavaScriptCore/wtf/text/StringImpl.h b/JavaScriptCore/wtf/text/StringImpl.h
index 99d0e9d..dc1dbb2 100644
--- a/JavaScriptCore/wtf/text/StringImpl.h
+++ b/JavaScriptCore/wtf/text/StringImpl.h
@@ -53,6 +53,7 @@ namespace WTF {
struct CStringTranslator;
struct HashAndCharactersTranslator;
+struct HashAndUTF8CharactersTranslator;
struct UCharBufferTranslator;
enum TextCaseSensitivity { TextCaseSensitive, TextCaseInsensitive };
@@ -66,6 +67,7 @@ class StringImpl : public StringImplBase {
friend struct JSC::IdentifierUCharBufferTranslator;
friend struct WTF::CStringTranslator;
friend struct WTF::HashAndCharactersTranslator;
+ friend struct WTF::HashAndUTF8CharactersTranslator;
friend struct WTF::UCharBufferTranslator;
friend class AtomicStringImpl;
private:
diff --git a/JavaScriptCore/wtf/text/WTFString.h b/JavaScriptCore/wtf/text/WTFString.h
index e9d6ae4..4d853d2 100644
--- a/JavaScriptCore/wtf/text/WTFString.h
+++ b/JavaScriptCore/wtf/text/WTFString.h
@@ -276,6 +276,13 @@ public:
// to ever prefer copy() over plain old assignment.
String threadsafeCopy() const;
+ // Prevent Strings from being implicitly convertable to bool as it will be ambiguous on any platform that
+ // allows implicit conversion to another pointer type (e.g., Mac allows implicit conversion to NSString*).
+ typedef struct ImplicitConversionFromWTFStringToBoolDisallowedA* (String::*UnspecifiedBoolTypeA);
+ typedef struct ImplicitConversionFromWTFStringToBoolDisallowedB* (String::*UnspecifiedBoolTypeB);
+ operator UnspecifiedBoolTypeA() const;
+ operator UnspecifiedBoolTypeB() const;
+
#if PLATFORM(CF)
String(CFStringRef);
CFStringRef createCFString() const;
@@ -309,6 +316,8 @@ public:
String(const AECHAR*);
#endif
+ // String::fromUTF8 will return a null string if
+ // the input data contains invalid UTF-8 sequences.
static String fromUTF8(const char*, size_t);
static String fromUTF8(const char*);
diff --git a/JavaScriptCore/wtf/unicode/UTF8.cpp b/JavaScriptCore/wtf/unicode/UTF8.cpp
index 40c5609..dc24ed5 100644
--- a/JavaScriptCore/wtf/unicode/UTF8.cpp
+++ b/JavaScriptCore/wtf/unicode/UTF8.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,10 +26,16 @@
#include "config.h"
#include "UTF8.h"
+#include <wtf/StringHasher.h>
+
+#include "ASCIICType.h"
namespace WTF {
namespace Unicode {
+// FIXME: Use definition from CharacterNames.h.
+static const UChar replacementCharacter = 0xFFFD;
+
inline int inlineUTF8SequenceLengthNonASCII(char b0)
{
if ((b0 & 0xC0) != 0xC0)
@@ -44,12 +51,12 @@ inline int inlineUTF8SequenceLengthNonASCII(char b0)
inline int inlineUTF8SequenceLength(char b0)
{
- return (b0 & 0x80) == 0 ? 1 : inlineUTF8SequenceLengthNonASCII(b0);
+ return isASCII(b0) ? 1 : inlineUTF8SequenceLengthNonASCII(b0);
}
int UTF8SequenceLength(char b0)
{
- return (b0 & 0x80) == 0 ? 1 : inlineUTF8SequenceLengthNonASCII(b0);
+ return isASCII(b0) ? 1 : inlineUTF8SequenceLengthNonASCII(b0);
}
int decodeUTF8Sequence(const char* sequence)
@@ -172,7 +179,7 @@ ConversionResult convertUTF16ToUTF8(
bytesToWrite = 4;
} else {
bytesToWrite = 3;
- ch = 0xFFFD;
+ ch = replacementCharacter;
}
target += bytesToWrite;
@@ -231,6 +238,23 @@ static bool isLegalUTF8(const unsigned char* source, int length)
static const UChar32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
+static inline UChar32 readUTF8Sequence(const char*& sequence, unsigned length)
+{
+ UChar32 character = 0;
+
+ // The cases all fall through.
+ switch (length) {
+ case 6: character += static_cast<unsigned char>(*sequence++); character <<= 6;
+ case 5: character += static_cast<unsigned char>(*sequence++); character <<= 6;
+ case 4: character += static_cast<unsigned char>(*sequence++); character <<= 6;
+ case 3: character += static_cast<unsigned char>(*sequence++); character <<= 6;
+ case 2: character += static_cast<unsigned char>(*sequence++); character <<= 6;
+ case 1: character += static_cast<unsigned char>(*sequence++);
+ }
+
+ return character - offsetsFromUTF8[length - 1];
+}
+
ConversionResult convertUTF8ToUTF16(
const char** sourceStart, const char* sourceEnd,
UChar** targetStart, UChar* targetEnd, bool strict)
@@ -239,60 +263,52 @@ ConversionResult convertUTF8ToUTF16(
const char* source = *sourceStart;
UChar* target = *targetStart;
while (source < sourceEnd) {
- UChar32 ch = 0;
- int extraBytesToRead = inlineUTF8SequenceLength(*source) - 1;
- if (source + extraBytesToRead >= sourceEnd) {
+ int utf8SequenceLength = inlineUTF8SequenceLength(*source);
+ if (sourceEnd - source < utf8SequenceLength) {
result = sourceExhausted;
break;
}
// Do this check whether lenient or strict
- if (!isLegalUTF8(reinterpret_cast<const unsigned char*>(source), extraBytesToRead + 1)) {
+ if (!isLegalUTF8(reinterpret_cast<const unsigned char*>(source), utf8SequenceLength)) {
result = sourceIllegal;
break;
}
- // The cases all fall through.
- switch (extraBytesToRead) {
- case 5: ch += static_cast<unsigned char>(*source++); ch <<= 6; // remember, illegal UTF-8
- case 4: ch += static_cast<unsigned char>(*source++); ch <<= 6; // remember, illegal UTF-8
- case 3: ch += static_cast<unsigned char>(*source++); ch <<= 6;
- case 2: ch += static_cast<unsigned char>(*source++); ch <<= 6;
- case 1: ch += static_cast<unsigned char>(*source++); ch <<= 6;
- case 0: ch += static_cast<unsigned char>(*source++);
- }
- ch -= offsetsFromUTF8[extraBytesToRead];
+
+ UChar32 character = readUTF8Sequence(source, utf8SequenceLength);
if (target >= targetEnd) {
- source -= (extraBytesToRead + 1); // Back up source pointer!
- result = targetExhausted; break;
+ source -= utf8SequenceLength; // Back up source pointer!
+ result = targetExhausted;
+ break;
}
- if (ch <= 0xFFFF) {
+
+ if (U_IS_BMP(character)) {
// UTF-16 surrogate values are illegal in UTF-32
- if (ch >= 0xD800 && ch <= 0xDFFF) {
+ if (U_IS_SURROGATE(character)) {
if (strict) {
- source -= (extraBytesToRead + 1); // return to the illegal value itself
+ source -= utf8SequenceLength; // return to the illegal value itself
result = sourceIllegal;
break;
} else
- *target++ = 0xFFFD;
- } else
- *target++ = (UChar)ch; // normal case
- } else if (ch > 0x10FFFF) {
- if (strict) {
- result = sourceIllegal;
- source -= (extraBytesToRead + 1); // return to the start
- break; // Bail out; shouldn't continue
+ *target++ = replacementCharacter;
} else
- *target++ = 0xFFFD;
- } else {
+ *target++ = character; // normal case
+ } else if (U_IS_SUPPLEMENTARY(character)) {
// target is a character in range 0xFFFF - 0x10FFFF
if (target + 1 >= targetEnd) {
- source -= (extraBytesToRead + 1); // Back up source pointer!
+ source -= utf8SequenceLength; // Back up source pointer!
result = targetExhausted;
break;
}
- ch -= 0x0010000UL;
- *target++ = (UChar)((ch >> 10) + 0xD800);
- *target++ = (UChar)((ch & 0x03FF) + 0xDC00);
+ *target++ = U16_LEAD(character);
+ *target++ = U16_TRAIL(character);
+ } else {
+ if (strict) {
+ source -= utf8SequenceLength; // return to the start
+ result = sourceIllegal;
+ break; // Bail out; shouldn't continue
+ } else
+ *target++ = replacementCharacter;
}
}
*sourceStart = source;
@@ -300,5 +316,86 @@ ConversionResult convertUTF8ToUTF16(
return result;
}
+unsigned calculateStringHashFromUTF8(const char* data, const char* dataEnd, unsigned& utf16Length)
+{
+ if (!data)
+ return 0;
+
+ WTF::StringHasher stringHasher;
+ utf16Length = 0;
+
+ while (data < dataEnd) {
+ if (isASCII(*data)) {
+ stringHasher.addCharacter(*data++);
+ utf16Length++;
+ continue;
+ }
+
+ int utf8SequenceLength = inlineUTF8SequenceLengthNonASCII(*data);
+
+ if (dataEnd - data < utf8SequenceLength)
+ return false;
+
+ if (!isLegalUTF8(reinterpret_cast<const unsigned char*>(data), utf8SequenceLength))
+ return 0;
+
+ UChar32 character = readUTF8Sequence(data, utf8SequenceLength);
+ ASSERT(!isASCII(character));
+
+ if (U_IS_BMP(character)) {
+ // UTF-16 surrogate values are illegal in UTF-32
+ if (U_IS_SURROGATE(character))
+ return 0;
+ stringHasher.addCharacter(static_cast<UChar>(character)); // normal case
+ utf16Length++;
+ } else if (U_IS_SUPPLEMENTARY(character)) {
+ stringHasher.addCharacters(static_cast<UChar>(U16_LEAD(character)),
+ static_cast<UChar>(U16_TRAIL(character)));
+ utf16Length += 2;
+ } else
+ return 0;
+ }
+
+ return stringHasher.hash();
}
+
+bool equalUTF16WithUTF8(const UChar* a, const UChar* aEnd, const char* b, const char* bEnd)
+{
+ while (b < bEnd) {
+ if (isASCII(*b)) {
+ if (*a++ != *b++)
+ return false;
+ continue;
+ }
+
+ int utf8SequenceLength = inlineUTF8SequenceLengthNonASCII(*b);
+
+ if (bEnd - b < utf8SequenceLength)
+ return false;
+
+ if (!isLegalUTF8(reinterpret_cast<const unsigned char*>(b), utf8SequenceLength))
+ return 0;
+
+ UChar32 character = readUTF8Sequence(b, utf8SequenceLength);
+ ASSERT(!isASCII(character));
+
+ if (U_IS_BMP(character)) {
+ // UTF-16 surrogate values are illegal in UTF-32
+ if (U_IS_SURROGATE(character))
+ return false;
+ if (*a++ != character)
+ return false;
+ } else if (U_IS_SUPPLEMENTARY(character)) {
+ if (*a++ != U16_LEAD(character))
+ return false;
+ if (*a++ != U16_TRAIL(character))
+ return false;
+ } else
+ return false;
+ }
+
+ return a == aEnd;
}
+
+} // namespace Unicode
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/unicode/UTF8.h b/JavaScriptCore/wtf/unicode/UTF8.h
index a5ed93e..1f4baca 100644
--- a/JavaScriptCore/wtf/unicode/UTF8.h
+++ b/JavaScriptCore/wtf/unicode/UTF8.h
@@ -29,7 +29,7 @@
#include "Unicode.h"
namespace WTF {
- namespace Unicode {
+namespace Unicode {
// Given a first byte, gives the length of the UTF-8 sequence it begins.
// Returns 0 for bytes that are not legal starts of UTF-8 sequences.
@@ -69,7 +69,12 @@ namespace WTF {
ConversionResult convertUTF16ToUTF8(
const UChar** sourceStart, const UChar* sourceEnd,
char** targetStart, char* targetEnd, bool strict = true);
- }
-}
+
+ unsigned calculateStringHashFromUTF8(const char* data, const char* dataEnd, unsigned& utf16Length);
+
+ bool equalUTF16WithUTF8(const UChar* a, const UChar* aEnd, const char* b, const char* bEnd);
+
+} // namespace Unicode
+} // namespace WTF
#endif // WTF_UTF8_h
diff --git a/JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h b/JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h
index f865ef1..8959912 100644
--- a/JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h
+++ b/JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 1999-2004, International Business Machines Corporation and others. All Rights Reserved.
* Copyright (C) 2006 George Staikos <staikos@kde.org>
* Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
* Copyright (C) 2007 Apple Computer, Inc. All rights reserved.
@@ -38,11 +39,28 @@
#define U16_TRAIL(supplementary) (UChar)(((supplementary)&0x3ff)|0xdc00)
#define U16_LENGTH(c) ((uint32_t)(c) <= 0xffff ? 1 : 2)
+#define U_IS_SUPPLEMENTARY(c) ((UChar32)((c)-0x10000)<=0xfffff)
#define U_IS_SURROGATE(c) (((c)&0xfffff800)==0xd800)
#define U16_IS_SINGLE(c) !U_IS_SURROGATE(c)
#define U16_IS_SURROGATE(c) U_IS_SURROGATE(c)
#define U16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0)
+#define U16_GET(s, start, i, length, c) { \
+ (c)=(s)[i]; \
+ if(U16_IS_SURROGATE(c)) { \
+ uint16_t __c2; \
+ if(U16_IS_SURROGATE_LEAD(c)) { \
+ if((i)+1<(length) && U16_IS_TRAIL(__c2=(s)[(i)+1])) { \
+ (c)=U16_GET_SUPPLEMENTARY((c), __c2); \
+ } \
+ } else { \
+ if((i)-1>=(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \
+ (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
+ } \
+ } \
+ } \
+}
+
#define U16_PREV(s, start, i, c) { \
(c)=(s)[--(i)]; \
if(U16_IS_TRAIL(c)) { \
@@ -54,6 +72,12 @@
} \
}
+#define U16_BACK_1(s, start, i) { \
+ if(U16_IS_TRAIL((s)[--(i)]) && (i)>(start) && U16_IS_LEAD((s)[(i)-1])) { \
+ --(i); \
+ } \
+}
+
#define U16_NEXT(s, i, length, c) { \
(c)=(s)[(i)++]; \
if(U16_IS_LEAD(c)) { \
@@ -65,7 +89,12 @@
} \
}
+#define U16_FWD_1(s, i, length) { \
+ if(U16_IS_LEAD((s)[(i)++]) && (i)<(length) && U16_IS_TRAIL((s)[i])) { \
+ ++(i); \
+ } \
+}
+
#define U_MASK(x) ((uint32_t)1<<(x))
#endif
-
diff --git a/JavaScriptCore/wtf/wtf.pri b/JavaScriptCore/wtf/wtf.pri
index 1780334..c5617ce 100644
--- a/JavaScriptCore/wtf/wtf.pri
+++ b/JavaScriptCore/wtf/wtf.pri
@@ -16,9 +16,11 @@ SOURCES += \
wtf/qt/MainThreadQt.cpp \
wtf/qt/StringQt.cpp \
wtf/qt/ThreadingQt.cpp \
- wtf/PageAllocation.cpp \
+ wtf/PageAllocationAligned.cpp \
+ wtf/PageBlock.cpp \
wtf/RandomNumber.cpp \
wtf/RefCountedLeakCounter.cpp \
+ wtf/StackBounds.cpp \
wtf/ThreadingNone.cpp \
wtf/Threading.cpp \
wtf/TypeTraits.cpp \
@@ -43,3 +45,6 @@ contains(DEFINES, USE_GSTREAMER=1) {
SOURCES += wtf/TCSystemAlloc.cpp
}
+unix:!symbian: SOURCES += wtf/OSAllocatorPosix.cpp
+symbian: SOURCES += wtf/OSAllocatorSymbian.cpp
+win*|wince*: SOURCES += wtf/OSAllocatorWin.cpp
diff --git a/JavaScriptCore/wtf/wx/StringWx.cpp b/JavaScriptCore/wtf/wx/StringWx.cpp
new file mode 100644
index 0000000..59d500b
--- /dev/null
+++ b/JavaScriptCore/wtf/wx/StringWx.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007 Vaclav Slavik, Kevin Ollivier <kevino@theolliviers.com>
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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 "PlatformString.h"
+
+#include <unicode/ustring.h>
+#include <wtf/text/CString.h>
+#include <wx/defs.h>
+#include <wx/string.h>
+
+namespace WTF {
+
+String::String(const wxString& wxstr)
+{
+#if !wxUSE_UNICODE
+ #error "This code only works in Unicode build of wxWidgets"
+#endif
+
+#if SIZEOF_WCHAR_T == sizeof(UChar)
+
+ m_impl = StringImpl::create(wxstr.wc_str(), wxstr.length());
+
+#else // SIZEOF_WCHAR_T == 4
+
+ // NB: we can't simply use wxstr.mb_str(wxMBConvUTF16()) here because
+ // the number of characters in UTF-16 encoding of the string may differ
+ // from the number of UTF-32 values and we can't get the length from
+ // returned buffer:
+
+#if defined(wxUSE_UNICODE_UTF8) && wxUSE_UNICODE_UTF8
+ // in wx3's UTF8 mode, wc_str() returns a buffer, not raw pointer
+ wxWCharBuffer wideString(wxstr.wc_str());
+#else
+ const wxChar *wideString = wxstr.wc_str();
+#endif
+ size_t wideLength = wxstr.length();
+
+ UChar* data;
+ wxMBConvUTF16 conv;
+ unsigned utf16Length = conv.FromWChar(0, 0, wideString, wideLength);
+ m_impl = StringImpl::createUninitialized(utf16Length, data)
+ conv.FromWChar(data, utf16Length, wideString, wideLength);
+
+#endif // SIZEOF_WCHAR_T == 4
+}
+
+String::operator wxString() const
+{
+ return wxString(utf8().data(), wxConvUTF8);
+}
+
+} // namespace WTF