diff options
author | Ben Murdoch <benm@google.com> | 2009-08-11 17:01:47 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2009-08-11 18:21:02 +0100 |
commit | 0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5 (patch) | |
tree | 2943df35f62d885c89d01063cc528dd73b480fea /JavaScriptCore/wtf | |
parent | 7e7a70bfa49a1122b2597a1e6367d89eb4035eca (diff) | |
download | external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.zip external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.gz external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.bz2 |
Merge in WebKit r47029.
Diffstat (limited to 'JavaScriptCore/wtf')
56 files changed, 2302 insertions, 252 deletions
diff --git a/JavaScriptCore/wtf/Assertions.cpp b/JavaScriptCore/wtf/Assertions.cpp index 6e04fe1..819ed9a 100644 --- a/JavaScriptCore/wtf/Assertions.cpp +++ b/JavaScriptCore/wtf/Assertions.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,7 +35,7 @@ #include <CoreFoundation/CFString.h> #endif -#if COMPILER(MSVC) && !PLATFORM(WIN_CE) +#if COMPILER(MSVC) && !PLATFORM(WINCE) #ifndef WINVER #define WINVER 0x0500 #endif @@ -45,6 +46,10 @@ #include <crtdbg.h> #endif +#if PLATFORM(WINCE) +#include <winbase.h> +#endif + extern "C" { WTF_ATTRIBUTE_PRINTF(1, 0) @@ -54,7 +59,7 @@ static void vprintf_stderr_common(const char* format, va_list args) if (strstr(format, "%@")) { CFStringRef cfFormat = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8); CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, cfFormat, args); - + int length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8); char* buffer = (char*)malloc(length + 1); @@ -66,7 +71,7 @@ static void vprintf_stderr_common(const char* format, va_list args) CFRelease(str); CFRelease(cfFormat); } else -#elif COMPILER(MSVC) && !PLATFORM(WIN_CE) +#elif COMPILER(MSVC) && !defined(WINCEBASIC) if (IsDebuggerPresent()) { size_t size = 1024; @@ -77,7 +82,20 @@ static void vprintf_stderr_common(const char* format, va_list args) break; if (_vsnprintf(buffer, size, format, args) != -1) { +#if PLATFORM(WINCE) + // WinCE only supports wide chars + wchar_t* wideBuffer = (wchar_t*)malloc(size * sizeof(wchar_t)); + if (wideBuffer == NULL) + break; + for (unsigned int i = 0; i < size; ++i) { + if (!(wideBuffer[i] = buffer[i])) + break; + } + OutputDebugStringW(wideBuffer); + free(wideBuffer); +#else OutputDebugStringA(buffer); +#endif free(buffer); break; } @@ -101,7 +119,7 @@ static void printf_stderr_common(const char* format, ...) static void printCallSite(const char* file, int line, const char* function) { -#if PLATFORM(WIN) && defined _DEBUG +#if PLATFORM(WIN) && !PLATFORM(WINCE) && defined _DEBUG _CrtDbgReport(_CRT_WARN, file, line, NULL, "%s\n", function); #else printf_stderr_common("(%s:%d %s)\n", file, line, function); diff --git a/JavaScriptCore/wtf/Assertions.h b/JavaScriptCore/wtf/Assertions.h index 9643517..59efd84 100644 --- a/JavaScriptCore/wtf/Assertions.h +++ b/JavaScriptCore/wtf/Assertions.h @@ -128,7 +128,7 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann /* ASSERT, ASSERT_WITH_MESSAGE, ASSERT_NOT_REACHED */ -#if PLATFORM(WIN_CE) +#if PLATFORM(WINCE) && !PLATFORM(TORCHMOBILE) /* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */ #include <windows.h> #undef min @@ -136,8 +136,8 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann #undef ERROR #endif -#if PLATFORM(WIN_OS) -/* FIXME: Change to use something other than ASSERT to avoid this conflict with win32. */ +#if PLATFORM(WIN_OS) || PLATFORM(SYMBIAN) +/* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */ #undef ASSERT #endif diff --git a/JavaScriptCore/wtf/ByteArray.h b/JavaScriptCore/wtf/ByteArray.h index 33f0877..96e9cc2 100644 --- a/JavaScriptCore/wtf/ByteArray.h +++ b/JavaScriptCore/wtf/ByteArray.h @@ -26,8 +26,8 @@ #ifndef ByteArray_h #define ByteArray_h -#include "wtf/PassRefPtr.h" -#include "wtf/RefCounted.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> namespace WTF { class ByteArray : public RefCountedBase { diff --git a/JavaScriptCore/wtf/CrossThreadRefCounted.h b/JavaScriptCore/wtf/CrossThreadRefCounted.h index 281dfa6..6a05211 100644 --- a/JavaScriptCore/wtf/CrossThreadRefCounted.h +++ b/JavaScriptCore/wtf/CrossThreadRefCounted.h @@ -51,7 +51,7 @@ namespace WTF { // with respect to the original and any other copies. The underlying m_data is jointly // owned by the original instance and all copies. template<class T> - class CrossThreadRefCounted : Noncopyable { + class CrossThreadRefCounted : public Noncopyable { public: static PassRefPtr<CrossThreadRefCounted<T> > create(T* data) { diff --git a/JavaScriptCore/wtf/CurrentTime.cpp b/JavaScriptCore/wtf/CurrentTime.cpp index 74984c1..45c724a 100644 --- a/JavaScriptCore/wtf/CurrentTime.cpp +++ b/JavaScriptCore/wtf/CurrentTime.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. * Copyright (C) 2008 Google Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -33,6 +34,7 @@ #include "CurrentTime.h" #if PLATFORM(WIN_OS) + // Windows is first since we want to use hires timers, despite PLATFORM(CF) // being defined. // If defined, WIN32_LEAN_AND_MEAN disables timeBeginPeriod/timeEndPeriod. @@ -40,9 +42,17 @@ #include <windows.h> #include <math.h> #include <stdint.h> +#include <time.h> + +#if USE(QUERY_PERFORMANCE_COUNTER) +#if PLATFORM(WINCE) +extern "C" time_t mktime(struct tm *t); +#else #include <sys/timeb.h> #include <sys/types.h> -#include <time.h> +#endif +#endif + #elif PLATFORM(CF) #include <CoreFoundation/CFDate.h> #elif PLATFORM(GTK) @@ -59,6 +69,8 @@ const double msPerSecond = 1000.0; #if PLATFORM(WIN_OS) +#if USE(QUERY_PERFORMANCE_COUNTER) + static LARGE_INTEGER qpcFrequency; static bool syncedTime; @@ -107,7 +119,7 @@ static double highResUpTime() static double lowResUTCTime() { -#if PLATFORM(WIN_CE) +#if PLATFORM(WINCE) SYSTEMTIME systemTime; GetSystemTime(&systemTime); struct tm tmtime; @@ -120,11 +132,11 @@ static double lowResUTCTime() tmtime.tm_sec = systemTime.wSecond; time_t timet = mktime(&tmtime); return timet * msPerSecond + systemTime.wMilliseconds; -#else // PLATFORM(WIN_CE) +#else struct _timeb timebuffer; _ftime(&timebuffer); return timebuffer.time * msPerSecond + timebuffer.millitm; -#endif // PLATFORM(WIN_CE) +#endif } static bool qpcAvailable() @@ -184,6 +196,55 @@ double currentTime() return utc / 1000.0; } +#else + +static double currentSystemTime() +{ + FILETIME ft; + GetCurrentFT(&ft); + + // As per Windows documentation for FILETIME, copy the resulting FILETIME structure to a + // ULARGE_INTEGER structure using memcpy (using memcpy instead of direct assignment can + // prevent alignment faults on 64-bit Windows). + + ULARGE_INTEGER t; + memcpy(&t, &ft, sizeof(t)); + + // Windows file times are in 100s of nanoseconds. + // To convert to seconds, we have to divide by 10,000,000, which is more quickly + // done by multiplying by 0.0000001. + + // Between January 1, 1601 and January 1, 1970, there were 369 complete years, + // of which 89 were leap years (1700, 1800, and 1900 were not leap years). + // That is a total of 134774 days, which is 11644473600 seconds. + + return t.QuadPart * 0.0000001 - 11644473600.0; +} + +double currentTime() +{ + static bool init = false; + static double lastTime; + static DWORD lastTickCount; + if (!init) { + lastTime = currentSystemTime(); + lastTickCount = GetTickCount(); + init = true; + return lastTime; + } + + DWORD tickCountNow = GetTickCount(); + DWORD elapsed = tickCountNow - lastTickCount; + double timeNow = lastTime + (double)elapsed / 1000.; + if (elapsed >= 0x7FFFFFFF) { + lastTime = timeNow; + lastTickCount = tickCountNow; + } + return timeNow; +} + +#endif // USE(QUERY_PERFORMANCE_COUNTER) + #elif PLATFORM(CF) double currentTime() diff --git a/JavaScriptCore/wtf/DateMath.cpp b/JavaScriptCore/wtf/DateMath.cpp index 3d3ede2..6a5b22f 100644 --- a/JavaScriptCore/wtf/DateMath.cpp +++ b/JavaScriptCore/wtf/DateMath.cpp @@ -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) 2007-2009 Torch Mobile, Inc. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. @@ -64,6 +65,11 @@ #include <notify.h> #endif +#if PLATFORM(WINCE) && !PLATFORM(QT) +extern "C" size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t); +extern "C" struct tm * localtime(const time_t *timer); +#endif + #if HAVE(SYS_TIME_H) #include <sys/time.h> #endif @@ -300,7 +306,7 @@ double getCurrentUTCTimeWithMicroseconds() void getLocalTime(const time_t* localTime, struct tm* localTM) { -#if COMPILER(MSVC7) || COMPILER(MINGW) || PLATFORM(WIN_CE) +#if COMPILER(MSVC7) || COMPILER(MINGW) || PLATFORM(WINCE) *localTM = *localtime(localTime); #elif COMPILER(MSVC) localtime_s(localTM, localTime); @@ -361,13 +367,34 @@ int equivalentYearForDST(int year) static int32_t calculateUTCOffset() { + time_t localTime = time(0); tm localt; - memset(&localt, 0, sizeof(localt)); - - // get the difference between this time zone and UTC on Jan 01, 2000 12:00:00 AM + getLocalTime(&localTime, &localt); + + // Get the difference between this time zone and UTC on the 1st of January of this year. + localt.tm_sec = 0; + localt.tm_min = 0; + localt.tm_hour = 0; localt.tm_mday = 1; - localt.tm_year = 100; - time_t utcOffset = 946684800 - mktime(&localt); + localt.tm_mon = 0; + // Not setting localt.tm_year! + localt.tm_wday = 0; + localt.tm_yday = 0; + localt.tm_isdst = 0; +#if HAVE(TM_GMTOFF) + localt.tm_gmtoff = 0; +#endif +#if HAVE(TM_ZONE) + localt.tm_zone = 0; +#endif + +#if HAVE(TIMEGM) + time_t utcOffset = timegm(&localt) - mktime(&localt); +#else + // Using a canned date of 01/01/2009 on platforms with weaker date-handling foo. + localt.tm_year = 109; + time_t utcOffset = 1230768000 - mktime(&localt); +#endif return static_cast<int32_t>(utcOffset * 1000); } @@ -496,7 +523,7 @@ void msToGregorianDateTime(double ms, bool outputIsUTC, GregorianDateTime& tm) tm.year = year - 1900; tm.isDST = dstOff != 0.0; - tm.utcOffset = static_cast<long>((dstOff + utcOff) / msPerSecond); + tm.utcOffset = outputIsUTC ? 0 : static_cast<long>((dstOff + utcOff) / msPerSecond); tm.timeZone = NULL; } @@ -819,7 +846,7 @@ double parseDateFromNullTerminatedCharacters(const char* dateString) return NaN; int sgn = (o < 0) ? -1 : 1; - o = abs(o); + o = labs(o); if (*dateString != ':') { offset = ((o / 100) * 60 + (o % 100)) * sgn; } else { // GMT+05:00 diff --git a/JavaScriptCore/wtf/DateMath.h b/JavaScriptCore/wtf/DateMath.h index 8690a49..6110f76 100644 --- a/JavaScriptCore/wtf/DateMath.h +++ b/JavaScriptCore/wtf/DateMath.h @@ -109,14 +109,17 @@ struct GregorianDateTime : Noncopyable { , year(inTm.tm_year) , isDST(inTm.tm_isdst) { -#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !COMPILER(RVCT) +#if HAVE(TM_GMTOFF) utcOffset = static_cast<int>(inTm.tm_gmtoff); +#else + utcOffset = static_cast<int>(getUTCOffset() / msPerSecond + (isDST ? secondsPerHour : 0)); +#endif +#if HAVE(TM_ZONE) int inZoneSize = strlen(inTm.tm_zone) + 1; timeZone = new char[inZoneSize]; strncpy(timeZone, inTm.tm_zone, inZoneSize); #else - utcOffset = static_cast<int>(getUTCOffset() / msPerSecond + (isDST ? secondsPerHour : 0)); timeZone = 0; #endif } @@ -136,8 +139,10 @@ struct GregorianDateTime : Noncopyable { ret.tm_year = year; ret.tm_isdst = isDST; -#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !COMPILER(RVCT) +#if HAVE(TM_GMTOFF) ret.tm_gmtoff = static_cast<long>(utcOffset); +#endif +#if HAVE(TM_ZONE) ret.tm_zone = timeZone; #endif diff --git a/JavaScriptCore/wtf/Deque.h b/JavaScriptCore/wtf/Deque.h index c371d38..3c3d378 100644 --- a/JavaScriptCore/wtf/Deque.h +++ b/JavaScriptCore/wtf/Deque.h @@ -44,7 +44,7 @@ namespace WTF { template<typename T> class DequeConstReverseIterator; template<typename T> - class Deque { + class Deque : public FastAllocBase { public: typedef DequeIterator<T> iterator; typedef DequeConstIterator<T> const_iterator; diff --git a/JavaScriptCore/wtf/FastAllocBase.h b/JavaScriptCore/wtf/FastAllocBase.h index 71e6bfa..9fcbbc1 100644 --- a/JavaScriptCore/wtf/FastAllocBase.h +++ b/JavaScriptCore/wtf/FastAllocBase.h @@ -79,9 +79,9 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include "Assertions.h" #include "FastMalloc.h" #include "TypeTraits.h" -#include <wtf/Assertions.h> namespace WTF { @@ -397,4 +397,7 @@ namespace WTF { } // namespace WTF +// Using WTF::FastAllocBase to avoid using FastAllocBase's explicit qualification by WTF::. +using WTF::FastAllocBase; + #endif // FastAllocBase_h diff --git a/JavaScriptCore/wtf/FastMalloc.cpp b/JavaScriptCore/wtf/FastMalloc.cpp index c65ba85..c14b755 100644 --- a/JavaScriptCore/wtf/FastMalloc.cpp +++ b/JavaScriptCore/wtf/FastMalloc.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2005, 2007, Google Inc. // All rights reserved. -// Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. +// Copyright (C) 2005, 2006, 2007, 2008, 2009 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 @@ -89,13 +89,19 @@ #endif #endif -#if !defined(USE_SYSTEM_MALLOC) && defined(NDEBUG) +#if !(defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) && defined(NDEBUG) #define FORCE_SYSTEM_MALLOC 0 #else #define FORCE_SYSTEM_MALLOC 1 #endif -#define TCMALLOC_TRACK_DECOMMITED_SPANS (HAVE(VIRTUALALLOC) || HAVE(MADV_FREE_REUSE)) +// Use a background thread to periodically scavenge memory to release back to the system +// https://bugs.webkit.org/show_bug.cgi?id=27900: don't turn this on for Tiger until we have figured out why it caused a crash. +#if defined(BUILDING_ON_TIGER) +#define USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY 0 +#else +#define USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY 1 +#endif #ifndef NDEBUG namespace WTF { @@ -1043,11 +1049,7 @@ struct Span { #endif }; -#if TCMALLOC_TRACK_DECOMMITED_SPANS #define ASSERT_SPAN_COMMITTED(span) ASSERT(!span->decommitted) -#else -#define ASSERT_SPAN_COMMITTED(span) -#endif #ifdef SPAN_HISTORY void Event(Span* span, char op, int v = 0) { @@ -1193,6 +1195,32 @@ template <> class MapSelector<32> { // contiguous runs of pages (called a "span"). // ------------------------------------------------------------------------- +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY +// The central page heap collects spans of memory that have been deleted but are still committed until they are released +// back to the system. We use a background thread to periodically scan the list of free spans and release some back to the +// system. Every 5 seconds, the background thread wakes up and does the following: +// - Check if we needed to commit memory in the last 5 seconds. If so, skip this scavenge because it's a sign that we are short +// of free committed pages and so we should not release them back to the system yet. +// - Otherwise, go through the list of free spans (from largest to smallest) and release up to a fraction of the free committed pages +// back to the system. +// - If the number of free committed pages reaches kMinimumFreeCommittedPageCount, we can stop the scavenging and block the +// scavenging thread until the number of free committed pages goes above kMinimumFreeCommittedPageCount. + +// Background thread wakes up every 5 seconds to scavenge as long as there is memory available to return to the system. +static const int kScavengeTimerDelayInSeconds = 5; + +// Number of free committed pages that we want to keep around. +static const size_t kMinimumFreeCommittedPageCount = 512; + +// During a scavenge, we'll release up to a fraction of the free committed pages. +#if PLATFORM(WIN) +// We are slightly less aggressive in releasing memory on Windows due to performance reasons. +static const int kMaxScavengeAmountFactor = 3; +#else +static const int kMaxScavengeAmountFactor = 2; +#endif +#endif + class TCMalloc_PageHeap { public: void init(); @@ -1292,6 +1320,14 @@ class TCMalloc_PageHeap { // Bytes allocated from system uint64_t system_bytes_; +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + // Number of pages kept in free lists that are still committed. + Length free_committed_pages_; + + // Number of pages that we committed in the last scavenge wait interval. + Length pages_committed_since_last_scavenge_; +#endif + bool GrowHeap(Length n); // REQUIRES span->length >= n @@ -1314,9 +1350,11 @@ class TCMalloc_PageHeap { // span of exactly the specified length. Else, returns NULL. Span* AllocLarge(Length n); +#if !USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY // Incrementally release some memory to the system. // IncrementalScavenge(n) is called whenever n pages are freed. void IncrementalScavenge(Length n); +#endif // Number of pages to deallocate before doing more scavenging int64_t scavenge_counter_; @@ -1327,6 +1365,24 @@ class TCMalloc_PageHeap { #if defined(WTF_CHANGES) && PLATFORM(DARWIN) friend class FastMallocZone; #endif + +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + static NO_RETURN void* runScavengerThread(void*); + + NO_RETURN void scavengerThread(); + + void scavenge(); + + inline bool shouldContinueScavenging() const; + + pthread_mutex_t m_scavengeMutex; + + pthread_cond_t m_scavengeCondition; + + // Keeps track of whether the background thread is actively scavenging memory every kScavengeTimerDelayInSeconds, or + // it's blocked waiting for more pages to be deleted. + bool m_scavengeThreadActive; +#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY }; void TCMalloc_PageHeap::init() @@ -1335,6 +1391,12 @@ void TCMalloc_PageHeap::init() pagemap_cache_ = PageMapCache(0); free_pages_ = 0; system_bytes_ = 0; + +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + free_committed_pages_ = 0; + pages_committed_since_last_scavenge_ = 0; +#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + scavenge_counter_ = 0; // Start scavenging at kMaxPages list scavenge_index_ = kMaxPages-1; @@ -1345,8 +1407,68 @@ void TCMalloc_PageHeap::init() DLL_Init(&free_[i].normal); DLL_Init(&free_[i].returned); } + +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + pthread_mutex_init(&m_scavengeMutex, 0); + pthread_cond_init(&m_scavengeCondition, 0); + m_scavengeThreadActive = true; + pthread_t thread; + pthread_create(&thread, 0, runScavengerThread, this); +#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY +} + +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY +void* TCMalloc_PageHeap::runScavengerThread(void* context) +{ + static_cast<TCMalloc_PageHeap*>(context)->scavengerThread(); +#if COMPILER(MSVC) + // Without this, Visual Studio will complain that this method does not return a value. + return 0; +#endif +} + +void TCMalloc_PageHeap::scavenge() +{ + // If we have to commit memory in the last 5 seconds, it means we don't have enough free committed pages + // for the amount of allocations that we do. So hold off on releasing memory back to the system. + if (pages_committed_since_last_scavenge_ > 0) { + pages_committed_since_last_scavenge_ = 0; + return; + } + Length pagesDecommitted = 0; + for (int i = kMaxPages; i >= 0; i--) { + SpanList* slist = (static_cast<size_t>(i) == kMaxPages) ? &large_ : &free_[i]; + if (!DLL_IsEmpty(&slist->normal)) { + // Release the last span on the normal portion of this list + Span* s = slist->normal.prev; + // Only decommit up to a fraction of the free committed pages if pages_allocated_since_last_scavenge_ > 0. + if ((pagesDecommitted + s->length) * kMaxScavengeAmountFactor > free_committed_pages_) + continue; + DLL_Remove(s); + TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift), + static_cast<size_t>(s->length << kPageShift)); + if (!s->decommitted) { + pagesDecommitted += s->length; + s->decommitted = true; + } + DLL_Prepend(&slist->returned, s); + // We can stop scavenging if the number of free committed pages left is less than or equal to the minimum number we want to keep around. + if (free_committed_pages_ <= kMinimumFreeCommittedPageCount + pagesDecommitted) + break; + } + } + pages_committed_since_last_scavenge_ = 0; + ASSERT(free_committed_pages_ >= pagesDecommitted); + free_committed_pages_ -= pagesDecommitted; +} + +inline bool TCMalloc_PageHeap::shouldContinueScavenging() const +{ + return free_committed_pages_ > kMinimumFreeCommittedPageCount; } +#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + inline Span* TCMalloc_PageHeap::New(Length n) { ASSERT(Check()); ASSERT(n > 0); @@ -1369,12 +1491,21 @@ inline Span* TCMalloc_PageHeap::New(Length n) { Span* result = ll->next; Carve(result, n, released); -#if TCMALLOC_TRACK_DECOMMITED_SPANS if (result->decommitted) { TCMalloc_SystemCommit(reinterpret_cast<void*>(result->start << kPageShift), static_cast<size_t>(n << kPageShift)); result->decommitted = false; - } +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + pages_committed_since_last_scavenge_ += n; #endif + } +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + else { + // The newly allocated memory is from a span that's in the normal span list (already committed). Update the + // free committed pages count. + ASSERT(free_committed_pages_ >= n); + free_committed_pages_ -= n; + } +#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY ASSERT(Check()); free_pages_ -= n; return result; @@ -1431,12 +1562,21 @@ Span* TCMalloc_PageHeap::AllocLarge(Length n) { if (best != NULL) { Carve(best, n, from_released); -#if TCMALLOC_TRACK_DECOMMITED_SPANS if (best->decommitted) { TCMalloc_SystemCommit(reinterpret_cast<void*>(best->start << kPageShift), static_cast<size_t>(n << kPageShift)); best->decommitted = false; - } +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + pages_committed_since_last_scavenge_ += n; #endif + } +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + else { + // The newly allocated memory is from a span that's in the normal span list (already committed). Update the + // free committed pages count. + ASSERT(free_committed_pages_ >= n); + free_committed_pages_ -= n; + } +#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY ASSERT(Check()); free_pages_ -= n; return best; @@ -1461,14 +1601,10 @@ Span* TCMalloc_PageHeap::Split(Span* span, Length n) { return leftover; } -#if !TCMALLOC_TRACK_DECOMMITED_SPANS -static ALWAYS_INLINE void propagateDecommittedState(Span*, Span*) { } -#else static ALWAYS_INLINE void propagateDecommittedState(Span* destination, Span* source) { destination->decommitted = source->decommitted; } -#endif inline void TCMalloc_PageHeap::Carve(Span* span, Length n, bool released) { ASSERT(n > 0); @@ -1495,9 +1631,6 @@ inline void TCMalloc_PageHeap::Carve(Span* span, Length n, bool released) { } } -#if !TCMALLOC_TRACK_DECOMMITED_SPANS -static ALWAYS_INLINE void mergeDecommittedStates(Span*, Span*) { } -#else static ALWAYS_INLINE void mergeDecommittedStates(Span* destination, Span* other) { if (destination->decommitted && !other->decommitted) { @@ -1509,7 +1642,6 @@ static ALWAYS_INLINE void mergeDecommittedStates(Span* destination, Span* other) destination->decommitted = true; } } -#endif inline void TCMalloc_PageHeap::Delete(Span* span) { ASSERT(Check()); @@ -1526,10 +1658,10 @@ inline void TCMalloc_PageHeap::Delete(Span* span) { // necessary. We do not bother resetting the stale pagemap // entries for the pieces we are merging together because we only // care about the pagemap entries for the boundaries. - // - // Note that the spans we merge into "span" may come out of - // a "returned" list. For simplicity, we move these into the - // "normal" list of the appropriate size class. +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + // Track the total size of the neighboring free spans that are committed. + Length neighboringCommittedSpansLength = 0; +#endif const PageID p = span->start; const Length n = span->length; Span* prev = GetDescriptor(p-1); @@ -1537,6 +1669,10 @@ inline void TCMalloc_PageHeap::Delete(Span* span) { // Merge preceding span into this span ASSERT(prev->start + prev->length == p); const Length len = prev->length; +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + if (!prev->decommitted) + neighboringCommittedSpansLength += len; +#endif mergeDecommittedStates(span, prev); DLL_Remove(prev); DeleteSpan(prev); @@ -1550,6 +1686,10 @@ inline void TCMalloc_PageHeap::Delete(Span* span) { // Merge next span into this span ASSERT(next->start == p+n); const Length len = next->length; +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + if (!next->decommitted) + neighboringCommittedSpansLength += len; +#endif mergeDecommittedStates(span, next); DLL_Remove(next); DeleteSpan(next); @@ -1560,17 +1700,40 @@ inline void TCMalloc_PageHeap::Delete(Span* span) { Event(span, 'D', span->length); span->free = 1; - if (span->length < kMaxPages) { - DLL_Prepend(&free_[span->length].normal, span); + if (span->decommitted) { + if (span->length < kMaxPages) + DLL_Prepend(&free_[span->length].returned, span); + else + DLL_Prepend(&large_.returned, span); } else { - DLL_Prepend(&large_.normal, span); + if (span->length < kMaxPages) + DLL_Prepend(&free_[span->length].normal, span); + else + DLL_Prepend(&large_.normal, span); } free_pages_ += n; +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + if (span->decommitted) { + // If the merged span is decommitted, that means we decommitted any neighboring spans that were + // committed. Update the free committed pages count. + free_committed_pages_ -= neighboringCommittedSpansLength; + } else { + // If the merged span remains committed, add the deleted span's size to the free committed pages count. + free_committed_pages_ += n; + } + + // Make sure the scavenge thread becomes active if we have enough freed pages to release some back to the system. + if (!m_scavengeThreadActive && shouldContinueScavenging()) + pthread_cond_signal(&m_scavengeCondition); +#else IncrementalScavenge(n); +#endif + ASSERT(Check()); } +#if !USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY void TCMalloc_PageHeap::IncrementalScavenge(Length n) { // Fast path; not yet time to release memory scavenge_counter_ -= n; @@ -1591,9 +1754,7 @@ void TCMalloc_PageHeap::IncrementalScavenge(Length n) { DLL_Remove(s); TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift), static_cast<size_t>(s->length << kPageShift)); -#if TCMALLOC_TRACK_DECOMMITED_SPANS s->decommitted = true; -#endif DLL_Prepend(&slist->returned, s); scavenge_counter_ = std::max<size_t>(64UL, std::min<size_t>(kDefaultReleaseDelay, kDefaultReleaseDelay - (free_pages_ / kDefaultReleaseDelay))); @@ -1610,6 +1771,7 @@ void TCMalloc_PageHeap::IncrementalScavenge(Length n) { // Nothing to scavenge, delay for a while scavenge_counter_ = kDefaultReleaseDelay; } +#endif void TCMalloc_PageHeap::RegisterSizeClass(Span* span, size_t sc) { // Associate span object with all interior pages as well @@ -1721,6 +1883,10 @@ bool TCMalloc_PageHeap::GrowHeap(Length n) { } ask = actual_size >> kPageShift; +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + pages_committed_since_last_scavenge_ += ask; +#endif + uint64_t old_system_bytes = system_bytes_; system_bytes_ += (ask << kPageShift); const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift; @@ -2101,6 +2267,34 @@ static inline TCMalloc_PageHeap* getPageHeap() #define pageheap getPageHeap() +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY +#if PLATFORM(WIN) +static void sleep(unsigned seconds) +{ + ::Sleep(seconds * 1000); +} +#endif + +void TCMalloc_PageHeap::scavengerThread() +{ + while (1) { + if (!shouldContinueScavenging()) { + pthread_mutex_lock(&m_scavengeMutex); + m_scavengeThreadActive = false; + // Block until there are enough freed pages to release back to the system. + pthread_cond_wait(&m_scavengeCondition, &m_scavengeMutex); + m_scavengeThreadActive = true; + pthread_mutex_unlock(&m_scavengeMutex); + } + sleep(kScavengeTimerDelayInSeconds); + { + SpinLockHolder h(&pageheap_lock); + pageheap->scavenge(); + } + } +} +#endif + // If TLS is available, we also store a copy // of the per-thread object in a __thread variable // since __thread variables are faster to read diff --git a/JavaScriptCore/wtf/FastMalloc.h b/JavaScriptCore/wtf/FastMalloc.h index 9e13cf9..787251f 100644 --- a/JavaScriptCore/wtf/FastMalloc.h +++ b/JavaScriptCore/wtf/FastMalloc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -28,18 +28,18 @@ namespace WTF { // These functions call CRASH() if an allocation fails. - void* fastMalloc(size_t n); - void* fastZeroedMalloc(size_t n); - void* fastCalloc(size_t n_elements, size_t element_size); - void* fastRealloc(void* p, size_t n); + void* fastMalloc(size_t); + void* fastZeroedMalloc(size_t); + void* fastCalloc(size_t numElements, size_t elementSize); + void* fastRealloc(void*, size_t); - // These functions return NULL if an allocation fails. - void* tryFastMalloc(size_t n); - void* tryFastZeroedMalloc(size_t n); - void* tryFastCalloc(size_t n_elements, size_t element_size); - void* tryFastRealloc(void* p, size_t n); + // These functions return 0 if an allocation fails. + void* tryFastMalloc(size_t); + void* tryFastZeroedMalloc(size_t); + void* tryFastCalloc(size_t numElements, size_t elementSize); + void* tryFastRealloc(void*, size_t); - void fastFree(void* p); + void fastFree(void*); #ifndef NDEBUG void fastMallocForbid(); @@ -172,15 +172,24 @@ using WTF::fastMallocAllow; #define WTF_PRIVATE_INLINE inline #endif -#ifndef _CRTDBG_MAP_ALLOC +#if !defined(_CRTDBG_MAP_ALLOC) && !(defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) -#if !defined(USE_SYSTEM_MALLOC) || !(USE_SYSTEM_MALLOC) -WTF_PRIVATE_INLINE void* operator new(size_t s) { return fastMalloc(s); } +// The nothrow functions here are actually not all that helpful, because fastMalloc will +// call CRASH() rather than returning 0, and returning 0 is what nothrow is all about. +// But since WebKit code never uses exceptions or nothrow at all, this is probably OK. +// Long term we will adopt FastAllocBase.h everywhere, and and replace this with +// debug-only code to make sure we don't use the system malloc via the default operator +// new by accident. + +WTF_PRIVATE_INLINE void* operator new(size_t size) { return fastMalloc(size); } +WTF_PRIVATE_INLINE void* operator new(size_t size, const std::nothrow_t&) throw() { return fastMalloc(size); } WTF_PRIVATE_INLINE void operator delete(void* p) { fastFree(p); } -WTF_PRIVATE_INLINE void* operator new[](size_t s) { return fastMalloc(s); } +WTF_PRIVATE_INLINE void operator delete(void* p, const std::nothrow_t&) throw() { fastFree(p); } +WTF_PRIVATE_INLINE void* operator new[](size_t size) { return fastMalloc(size); } +WTF_PRIVATE_INLINE void* operator new[](size_t size, const std::nothrow_t&) throw() { return fastMalloc(size); } WTF_PRIVATE_INLINE void operator delete[](void* p) { fastFree(p); } -#endif +WTF_PRIVATE_INLINE void operator delete[](void* p, const std::nothrow_t&) throw() { fastFree(p); } -#endif // _CRTDBG_MAP_ALLOC +#endif #endif /* WTF_FastMalloc_h */ diff --git a/JavaScriptCore/wtf/GOwnPtr.h b/JavaScriptCore/wtf/GOwnPtr.h index 8d03ff2..4993348 100644 --- a/JavaScriptCore/wtf/GOwnPtr.h +++ b/JavaScriptCore/wtf/GOwnPtr.h @@ -37,7 +37,7 @@ namespace WTF { template<> void freeOwnedGPtr<GDir>(GDir*); template<> void freeOwnedGPtr<GHashTable>(GHashTable*); - template <typename T> class GOwnPtr : Noncopyable { + template <typename T> class GOwnPtr : public Noncopyable { public: explicit GOwnPtr(T* ptr = 0) : m_ptr(ptr) { } ~GOwnPtr() { freeOwnedGPtr(m_ptr); } diff --git a/JavaScriptCore/wtf/HashCountedSet.h b/JavaScriptCore/wtf/HashCountedSet.h index 6fc0234..1a422d8 100644 --- a/JavaScriptCore/wtf/HashCountedSet.h +++ b/JavaScriptCore/wtf/HashCountedSet.h @@ -22,13 +22,14 @@ #define WTF_HashCountedSet_h #include "Assertions.h" +#include "FastAllocBase.h" #include "HashMap.h" #include "Vector.h" namespace WTF { template<typename Value, typename HashFunctions = typename DefaultHash<Value>::Hash, - typename Traits = HashTraits<Value> > class HashCountedSet { + typename Traits = HashTraits<Value> > class HashCountedSet : public FastAllocBase { private: typedef HashMap<Value, unsigned, HashFunctions, Traits> ImplType; public: diff --git a/JavaScriptCore/wtf/HashMap.h b/JavaScriptCore/wtf/HashMap.h index c5b75ff..3de5ee6 100644 --- a/JavaScriptCore/wtf/HashMap.h +++ b/JavaScriptCore/wtf/HashMap.h @@ -29,7 +29,7 @@ namespace WTF { template<typename KeyArg, typename MappedArg, typename HashArg = typename DefaultHash<KeyArg>::Hash, typename KeyTraitsArg = HashTraits<KeyArg>, typename MappedTraitsArg = HashTraits<MappedArg> > - class HashMap { + class HashMap : public FastAllocBase { private: typedef KeyTraitsArg KeyTraits; typedef MappedTraitsArg MappedTraits; diff --git a/JavaScriptCore/wtf/HashSet.h b/JavaScriptCore/wtf/HashSet.h index da99f2c..990670d 100644 --- a/JavaScriptCore/wtf/HashSet.h +++ b/JavaScriptCore/wtf/HashSet.h @@ -21,6 +21,7 @@ #ifndef WTF_HashSet_h #define WTF_HashSet_h +#include "FastAllocBase.h" #include "HashTable.h" namespace WTF { @@ -32,7 +33,7 @@ namespace WTF { template<typename T> struct IdentityExtractor; template<typename ValueArg, typename HashArg = typename DefaultHash<ValueArg>::Hash, - typename TraitsArg = HashTraits<ValueArg> > class HashSet { + typename TraitsArg = HashTraits<ValueArg> > class HashSet : public FastAllocBase { private: typedef HashArg HashFunctions; typedef TraitsArg ValueTraits; @@ -175,28 +176,28 @@ namespace WTF { } template<typename Value, typename HashFunctions, typename Traits> - template<typename T, typename Translator> + template<typename T, typename HashTranslator> typename HashSet<Value, HashFunctions, Traits>::iterator inline HashSet<Value, HashFunctions, Traits>::find(const T& value) { - typedef HashSetTranslatorAdapter<ValueType, ValueTraits, T, Translator> Adapter; + typedef HashSetTranslatorAdapter<ValueType, ValueTraits, T, HashTranslator> Adapter; return m_impl.template find<T, Adapter>(value); } template<typename Value, typename HashFunctions, typename Traits> - template<typename T, typename Translator> + template<typename T, typename HashTranslator> typename HashSet<Value, HashFunctions, Traits>::const_iterator inline HashSet<Value, HashFunctions, Traits>::find(const T& value) const { - typedef HashSetTranslatorAdapter<ValueType, ValueTraits, T, Translator> Adapter; + typedef HashSetTranslatorAdapter<ValueType, ValueTraits, T, HashTranslator> Adapter; return m_impl.template find<T, Adapter>(value); } template<typename Value, typename HashFunctions, typename Traits> - template<typename T, typename Translator> + template<typename T, typename HashTranslator> inline bool HashSet<Value, HashFunctions, Traits>::contains(const T& value) const { - typedef HashSetTranslatorAdapter<ValueType, ValueTraits, T, Translator> Adapter; + typedef HashSetTranslatorAdapter<ValueType, ValueTraits, T, HashTranslator> Adapter; return m_impl.template contains<T, Adapter>(value); } @@ -207,11 +208,11 @@ namespace WTF { } template<typename Value, typename HashFunctions, typename Traits> - template<typename T, typename Translator> + template<typename T, typename HashTranslator> pair<typename HashSet<Value, HashFunctions, Traits>::iterator, bool> HashSet<Value, HashFunctions, Traits>::add(const T& value) { - typedef HashSetTranslatorAdapter<ValueType, ValueTraits, T, Translator> Adapter; + typedef HashSetTranslatorAdapter<ValueType, ValueTraits, T, HashTranslator> Adapter; return m_impl.template addPassingHashCode<T, T, Adapter>(value, value); } diff --git a/JavaScriptCore/wtf/Locker.h b/JavaScriptCore/wtf/Locker.h index 9feec1f..41813d3 100644 --- a/JavaScriptCore/wtf/Locker.h +++ b/JavaScriptCore/wtf/Locker.h @@ -32,7 +32,7 @@ namespace WTF { -template <typename T> class Locker : Noncopyable { +template <typename T> class Locker : public Noncopyable { public: Locker(T& lockable) : m_lockable(lockable) { m_lockable.lock(); } ~Locker() { m_lockable.unlock(); } diff --git a/JavaScriptCore/wtf/MainThread.cpp b/JavaScriptCore/wtf/MainThread.cpp index 3c19b7a..e999094 100644 --- a/JavaScriptCore/wtf/MainThread.cpp +++ b/JavaScriptCore/wtf/MainThread.cpp @@ -29,9 +29,9 @@ #include "config.h" #include "MainThread.h" +#include "StdLibExtras.h" #include "CurrentTime.h" #include "Deque.h" -#include "StdLibExtras.h" #include "Threading.h" namespace WTF { diff --git a/JavaScriptCore/wtf/MathExtras.h b/JavaScriptCore/wtf/MathExtras.h index 76488b4..324300d 100644 --- a/JavaScriptCore/wtf/MathExtras.h +++ b/JavaScriptCore/wtf/MathExtras.h @@ -39,10 +39,8 @@ #endif #if COMPILER(MSVC) -#if PLATFORM(WIN_CE) +#if PLATFORM(WINCE) #include <stdlib.h> -#else -#include <xmath.h> #endif #include <limits> diff --git a/JavaScriptCore/wtf/MessageQueue.h b/JavaScriptCore/wtf/MessageQueue.h index 9549f37..12291cc 100644 --- a/JavaScriptCore/wtf/MessageQueue.h +++ b/JavaScriptCore/wtf/MessageQueue.h @@ -45,11 +45,12 @@ namespace WTF { }; template<typename DataType> - class MessageQueue : Noncopyable { + class MessageQueue : public Noncopyable { public: - MessageQueue() : m_killed(false) {} + MessageQueue() : m_killed(false) { } void append(const DataType&); + bool appendAndCheckEmpty(const DataType&); void prepend(const DataType&); bool waitForMessage(DataType&); template<typename Predicate> @@ -81,6 +82,17 @@ namespace WTF { m_condition.signal(); } + // Returns true if the queue was empty before the item was added. + template<typename DataType> + inline bool MessageQueue<DataType>::appendAndCheckEmpty(const DataType& message) + { + MutexLocker lock(m_mutex); + bool wasEmpty = m_queue.isEmpty(); + m_queue.append(message); + m_condition.signal(); + return wasEmpty; + } + template<typename DataType> inline void MessageQueue<DataType>::prepend(const DataType& message) { diff --git a/JavaScriptCore/wtf/Noncopyable.h b/JavaScriptCore/wtf/Noncopyable.h index f241c7c..60a46e2 100644 --- a/JavaScriptCore/wtf/Noncopyable.h +++ b/JavaScriptCore/wtf/Noncopyable.h @@ -24,9 +24,11 @@ // We don't want argument-dependent lookup to pull in everything from the WTF // namespace when you use Noncopyable, so put it in its own namespace. +#include "FastAllocBase.h" + namespace WTFNoncopyable { - class Noncopyable { + class Noncopyable : public FastAllocBase { Noncopyable(const Noncopyable&); Noncopyable& operator=(const Noncopyable&); protected: @@ -34,8 +36,17 @@ namespace WTFNoncopyable { ~Noncopyable() { } }; + class NoncopyableCustomAllocated { + NoncopyableCustomAllocated(const NoncopyableCustomAllocated&); + NoncopyableCustomAllocated& operator=(const NoncopyableCustomAllocated&); + protected: + NoncopyableCustomAllocated() { } + ~NoncopyableCustomAllocated() { } + }; + } // namespace WTFNoncopyable using WTFNoncopyable::Noncopyable; +using WTFNoncopyable::NoncopyableCustomAllocated; #endif // WTF_Noncopyable_h diff --git a/JavaScriptCore/wtf/OwnArrayPtr.h b/JavaScriptCore/wtf/OwnArrayPtr.h index 344f813..61375c7 100644 --- a/JavaScriptCore/wtf/OwnArrayPtr.h +++ b/JavaScriptCore/wtf/OwnArrayPtr.h @@ -27,7 +27,7 @@ namespace WTF { - template <typename T> class OwnArrayPtr : Noncopyable { + template <typename T> class OwnArrayPtr : public Noncopyable { public: explicit OwnArrayPtr(T* ptr = 0) : m_ptr(ptr) { } ~OwnArrayPtr() { safeDelete(); } @@ -46,8 +46,12 @@ namespace WTF { bool operator!() const { return !m_ptr; } // This conversion operator allows implicit conversion to bool but not to other integer types. +#if COMPILER(WINSCW) + operator bool() const { return m_ptr; } +#else typedef T* OwnArrayPtr::*UnspecifiedBoolType; operator UnspecifiedBoolType() const { return m_ptr ? &OwnArrayPtr::m_ptr : 0; } +#endif void swap(OwnArrayPtr& o) { std::swap(m_ptr, o.m_ptr); } diff --git a/JavaScriptCore/wtf/OwnFastMallocPtr.h b/JavaScriptCore/wtf/OwnFastMallocPtr.h index 5c0d064..c88235a 100644 --- a/JavaScriptCore/wtf/OwnFastMallocPtr.h +++ b/JavaScriptCore/wtf/OwnFastMallocPtr.h @@ -27,7 +27,7 @@ namespace WTF { - template<class T> class OwnFastMallocPtr : Noncopyable { + template<class T> class OwnFastMallocPtr : public Noncopyable { public: explicit OwnFastMallocPtr(T* ptr) : m_ptr(ptr) { diff --git a/JavaScriptCore/wtf/OwnPtr.h b/JavaScriptCore/wtf/OwnPtr.h index 9e4bd32..b7e62b1 100644 --- a/JavaScriptCore/wtf/OwnPtr.h +++ b/JavaScriptCore/wtf/OwnPtr.h @@ -34,7 +34,7 @@ namespace WTF { template <typename T> class PassOwnPtr; - template <typename T> class OwnPtr : Noncopyable { + template <typename T> class OwnPtr : public Noncopyable { public: typedef typename RemovePointer<T>::Type ValueType; typedef ValueType* PtrType; diff --git a/JavaScriptCore/wtf/OwnPtrCommon.h b/JavaScriptCore/wtf/OwnPtrCommon.h index 6cd8bdd..6d91a54 100644 --- a/JavaScriptCore/wtf/OwnPtrCommon.h +++ b/JavaScriptCore/wtf/OwnPtrCommon.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2009 Torch Mobile, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,6 +30,7 @@ #if PLATFORM(WIN) typedef struct HBITMAP__* HBITMAP; typedef struct HBRUSH__* HBRUSH; +typedef struct HDC__* HDC; typedef struct HFONT__* HFONT; typedef struct HPALETTE__* HPALETTE; typedef struct HPEN__* HPEN; @@ -47,6 +49,7 @@ namespace WTF { #if PLATFORM(WIN) void deleteOwnedPtr(HBITMAP); void deleteOwnedPtr(HBRUSH); + void deleteOwnedPtr(HDC); void deleteOwnedPtr(HFONT); void deleteOwnedPtr(HPALETTE); void deleteOwnedPtr(HPEN); diff --git a/JavaScriptCore/wtf/OwnPtrWin.cpp b/JavaScriptCore/wtf/OwnPtrWin.cpp index b08d7dc..67a32ff 100644 --- a/JavaScriptCore/wtf/OwnPtrWin.cpp +++ b/JavaScriptCore/wtf/OwnPtrWin.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009 Torch Mobile, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -42,6 +43,12 @@ void deleteOwnedPtr(HBRUSH ptr) DeleteObject(ptr); } +void deleteOwnedPtr(HDC ptr) +{ + if (ptr) + DeleteDC(ptr); +} + void deleteOwnedPtr(HFONT ptr) { if (ptr) diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h index e34f7c3..230458f 100644 --- a/JavaScriptCore/wtf/Platform.h +++ b/JavaScriptCore/wtf/Platform.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +28,11 @@ #define WTF_Platform_h /* PLATFORM handles OS, operating environment, graphics API, and CPU */ -#define PLATFORM(WTF_FEATURE) (defined( WTF_PLATFORM_##WTF_FEATURE ) && WTF_PLATFORM_##WTF_FEATURE) -#define COMPILER(WTF_FEATURE) (defined( WTF_COMPILER_##WTF_FEATURE ) && WTF_COMPILER_##WTF_FEATURE) -#define HAVE(WTF_FEATURE) (defined( HAVE_##WTF_FEATURE ) && HAVE_##WTF_FEATURE) -#define USE(WTF_FEATURE) (defined( WTF_USE_##WTF_FEATURE ) && WTF_USE_##WTF_FEATURE) -#define ENABLE(WTF_FEATURE) (defined( ENABLE_##WTF_FEATURE ) && ENABLE_##WTF_FEATURE) +#define PLATFORM(WTF_FEATURE) (defined WTF_PLATFORM_##WTF_FEATURE && WTF_PLATFORM_##WTF_FEATURE) +#define COMPILER(WTF_FEATURE) (defined WTF_COMPILER_##WTF_FEATURE && WTF_COMPILER_##WTF_FEATURE) +#define HAVE(WTF_FEATURE) (defined HAVE_##WTF_FEATURE && HAVE_##WTF_FEATURE) +#define USE(WTF_FEATURE) (defined WTF_USE_##WTF_FEATURE && WTF_USE_##WTF_FEATURE) +#define ENABLE(WTF_FEATURE) (defined ENABLE_##WTF_FEATURE && ENABLE_##WTF_FEATURE) /* Operating systems - low-level dependencies */ @@ -56,12 +57,12 @@ #define WTF_PLATFORM_WIN_OS 1 #endif -/* PLATFORM(WIN_CE) */ +/* PLATFORM(WINCE) */ /* Operating system level dependencies for Windows CE that should be used */ /* regardless of operating environment */ /* Note that for this platform PLATFORM(WIN_OS) is also defined. */ #if defined(_WIN32_WCE) -#define WTF_PLATFORM_WIN_CE 1 +#define WTF_PLATFORM_WINCE 1 #endif /* PLATFORM(LINUX) */ @@ -92,12 +93,10 @@ #define WTF_PLATFORM_SOLARIS 1 #endif -#if defined (__S60__) || defined (__SYMBIAN32__) +#if defined (__SYMBIAN32__) /* we are cross-compiling, it is not really windows */ #undef WTF_PLATFORM_WIN_OS #undef WTF_PLATFORM_WIN -#undef WTF_PLATFORM_CAIRO -#define WTF_PLATFORM_S60 1 #define WTF_PLATFORM_SYMBIAN 1 #endif @@ -114,7 +113,7 @@ /* should be used regardless of operating environment */ #if PLATFORM(DARWIN) \ || PLATFORM(FREEBSD) \ - || PLATFORM(S60) \ + || PLATFORM(SYMBIAN) \ || PLATFORM(NETBSD) \ || defined(unix) \ || defined(__unix) \ @@ -190,7 +189,7 @@ /* Makes PLATFORM(WIN) default to PLATFORM(CAIRO) */ /* FIXME: This should be changed from a blacklist to a whitelist */ -#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(WX) && !PLATFORM(CHROMIUM) +#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(WX) && !PLATFORM(CHROMIUM) && !PLATFORM(WINCE) #define WTF_PLATFORM_CAIRO 1 #endif @@ -246,18 +245,45 @@ #define WTF_PLATFORM_ARM 1 #if defined(__ARMEB__) #define WTF_PLATFORM_BIG_ENDIAN 1 +#ifdef MANUAL_MERGE_REQUIRED #elif !defined(__ARM_EABI__) && !defined(__ARMEB__) && !defined(__VFP_FP__) #if !defined(ANDROID) +#else // MANUAL_MERGE_REQUIRED +#elif !defined(__ARM_EABI__) && !defined(__EABI__) && !defined(__VFP_FP__) +#endif // MANUAL_MERGE_REQUIRED #define WTF_PLATFORM_MIDDLE_ENDIAN 1 #endif +#ifdef MANUAL_MERGE_REQUIRED #endif #if !defined(__ARM_EABI__) +#else // MANUAL_MERGE_REQUIRED +#if !defined(__ARM_EABI__) && !defined(__EABI__) +#endif // MANUAL_MERGE_REQUIRED #define WTF_PLATFORM_FORCE_PACK 1 #endif +#define ARM_ARCH_VERSION 3 +#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) +#undef ARM_ARCH_VERSION +#define ARM_ARCH_VERSION 4 +#endif +#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \ + || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \ + || defined(__ARM_ARCH_5TEJ__) +#undef ARM_ARCH_VERSION +#define ARM_ARCH_VERSION 5 +#endif +#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6ZK__) +#undef ARM_ARCH_VERSION +#define ARM_ARCH_VERSION 6 #endif #if defined(__ARM_ARCH_7A__) -#define WTF_PLATFORM_ARM_V7 1 +#undef ARM_ARCH_VERSION +#define ARM_ARCH_VERSION 7 #endif +#endif /* ARM */ +#define PLATFORM_ARM_ARCH(N) (PLATFORM(ARM) && ARM_ARCH_VERSION >= N) /* PLATFORM(X86) */ #if defined(__i386__) \ @@ -285,12 +311,12 @@ #define WTF_PLATFORM_BIG_ENDIAN 1 #endif -/* PLATFORM(WIN_CE) && PLATFORM(QT) +/* PLATFORM(WINCE) && PLATFORM(QT) We can not determine the endianess at compile time. For Qt for Windows CE the endianess is specified in the device specific makespec */ -#if PLATFORM(WIN_CE) && PLATFORM(QT) +#if PLATFORM(WINCE) && PLATFORM(QT) # include <QtGlobal> # undef WTF_PLATFORM_BIG_ENDIAN # undef WTF_PLATFORM_MIDDLE_ENDIAN @@ -318,6 +344,7 @@ /* --gnu option of the RVCT compiler also defines __GNUC__ */ #if defined(__GNUC__) && !COMPILER(RVCT) #define WTF_COMPILER_GCC 1 +#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #endif /* COMPILER(MINGW) */ @@ -346,11 +373,43 @@ #define ENABLE_JSC_MULTIPLE_THREADS 1 #endif +/* On Windows, use QueryPerformanceCounter by default */ +#if PLATFORM(WIN_OS) +#define WTF_USE_QUERY_PERFORMANCE_COUNTER 1 +#endif + +#if PLATFORM(WINCE) && !PLATFORM(QT) +#undef ENABLE_JSC_MULTIPLE_THREADS +#define ENABLE_JSC_MULTIPLE_THREADS 0 +#define USE_SYSTEM_MALLOC 0 +#define ENABLE_ICONDATABASE 0 +#define ENABLE_JAVASCRIPT_DEBUGGER 0 +#define ENABLE_FTPDIR 0 +#define ENABLE_PAN_SCROLLING 0 +#define ENABLE_WML 1 +#define HAVE_ACCESSIBILITY 0 + +#define NOMINMAX // Windows min and max conflict with standard macros +#define NOSHLWAPI // shlwapi.h not available on WinCe + +// MSDN documentation says these functions are provided with uspce.lib. But we cannot find this file. +#define __usp10__ // disable "usp10.h" + +#define _INC_ASSERT // disable "assert.h" +#define assert(x) + +// _countof is only included in CE6; for CE5 we need to define it ourself +#ifndef _countof +#define _countof(x) (sizeof(x) / sizeof((x)[0])) +#endif + +#endif /* PLATFORM(WINCE) && !PLATFORM(QT) */ + /* for Unicode, KDE uses Qt */ #if PLATFORM(KDE) || PLATFORM(QT) #define WTF_USE_QT4_UNICODE 1 -#elif PLATFORM(SYMBIAN) -#define WTF_USE_SYMBIAN_UNICODE 1 +#elif PLATFORM(WINCE) +#define WTF_USE_WINCE_UNICODE 1 #elif PLATFORM(GTK) /* The GTK+ Unicode backend is configurable */ #else @@ -409,6 +468,16 @@ #endif #endif /* !defined(HAVE_ACCESSIBILITY) */ +#if PLATFORM(UNIX) && !PLATFORM(SYMBIAN) +#define HAVE_SIGNAL_H 1 +#endif + +#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !PLATFORM(SYMBIAN) && !COMPILER(RVCT) +#define HAVE_TM_GMTOFF 1 +#define HAVE_TM_ZONE 1 +#define HAVE_TIMEGM 1 +#endif + #if PLATFORM(DARWIN) #define HAVE_ERRNO_H 1 @@ -433,7 +502,7 @@ #elif PLATFORM(WIN_OS) #define HAVE_FLOAT_H 1 -#if PLATFORM(WIN_CE) +#if PLATFORM(WINCE) #define HAVE_ERRNO_H 0 #else #define HAVE_SYS_TIMEB_H 1 @@ -545,15 +614,22 @@ #define ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL 0 #endif -#if !defined(WTF_USE_ALTERNATE_JSIMMEDIATE) && PLATFORM(X86_64) && PLATFORM(MAC) -#define WTF_USE_ALTERNATE_JSIMMEDIATE 1 +#if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64) +#if PLATFORM(X86_64) && (PLATFORM(MAC) || (PLATFORM(LINUX) && !PLATFORM(QT))) +#define WTF_USE_JSVALUE64 1 +#elif PLATFORM(PPC64) || PLATFORM(QT) /* All Qt layout tests crash in JSVALUE32_64 mode. */ +#define WTF_USE_JSVALUE32 1 +#else +#define WTF_USE_JSVALUE32_64 1 #endif +#endif /* !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64) */ #if !defined(ENABLE_REPAINT_THROTTLING) #define ENABLE_REPAINT_THROTTLING 0 #endif #if !defined(ENABLE_JIT) + /* The JIT is tested & working on x86_64 Mac */ #if PLATFORM(X86_64) && PLATFORM(MAC) #define ENABLE_JIT 1 @@ -561,7 +637,7 @@ #elif PLATFORM(X86) && PLATFORM(MAC) #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 -#elif PLATFORM(ARM_V7) && PLATFORM(IPHONE) +#elif PLATFORM_ARM_ARCH(7) && PLATFORM(IPHONE) /* Under development, temporarily disabled until 16Mb link range limit in assembler is fixed. */ #define ENABLE_JIT 0 #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0 @@ -569,8 +645,23 @@ #elif PLATFORM(X86) && PLATFORM(WIN) #define ENABLE_JIT 1 #endif + +#if PLATFORM(X86) && PLATFORM(QT) +#if PLATFORM(WIN_OS) && COMPILER(MINGW) && GCC_VERSION >= 40100 + #define ENABLE_JIT 1 + #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 +#elif PLATFORM(WIN_OS) && COMPILER(MSVC) + #define ENABLE_JIT 1 + #define WTF_USE_JIT_STUB_ARGUMENT_REGISTER 1 +#elif PLATFORM(LINUX) && GCC_VERSION >= 40100 + #define ENABLE_JIT 1 + #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 #endif +#endif /* PLATFORM(QT) && PLATFORM(X86) */ +#endif /* !defined(ENABLE_JIT) */ + +#if ENABLE(JIT) #ifndef ENABLE_JIT_OPTIMIZE_CALL #define ENABLE_JIT_OPTIMIZE_CALL 1 #endif @@ -580,12 +671,10 @@ #ifndef ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS #define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1 #endif -#ifndef ENABLE_JIT_OPTIMIZE_ARITHMETIC -#define ENABLE_JIT_OPTIMIZE_ARITHMETIC 1 -#endif #ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS #define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1 #endif +#endif #if PLATFORM(X86) && COMPILER(MSVC) #define JSC_HOST_CALL __fastcall @@ -606,15 +695,29 @@ #endif /* Yet Another Regex Runtime. */ +#if !defined(ENABLE_YARR_JIT) + /* YARR supports x86 & x86-64, and has been tested on Mac and Windows. */ -#if (!defined(ENABLE_YARR_JIT) && PLATFORM(X86) && PLATFORM(MAC)) \ - || (!defined(ENABLE_YARR_JIT) && PLATFORM(X86_64) && PLATFORM(MAC)) \ +#if (PLATFORM(X86) && PLATFORM(MAC)) \ + || (PLATFORM(X86_64) && PLATFORM(MAC)) \ /* Under development, temporarily disabled until 16Mb link range limit in assembler is fixed. */ \ - || (!defined(ENABLE_YARR_JIT) && PLATFORM(ARM_V7) && PLATFORM(IPHONE) && 0) \ - || (!defined(ENABLE_YARR_JIT) && PLATFORM(X86) && PLATFORM(WIN)) + || (PLATFORM_ARM_ARCH(7) && PLATFORM(IPHONE) && 0) \ + || (PLATFORM(X86) && PLATFORM(WIN)) +#define ENABLE_YARR 1 +#define ENABLE_YARR_JIT 1 +#endif + +#if PLATFORM(X86) && PLATFORM(QT) +#if (PLATFORM(WIN_OS) && COMPILER(MINGW) && GCC_VERSION >= 40100) \ + || (PLATFORM(WIN_OS) && COMPILER(MSVC)) \ + || (PLATFORM(LINUX) && GCC_VERSION >= 40100) #define ENABLE_YARR 1 #define ENABLE_YARR_JIT 1 #endif +#endif + +#endif /* !defined(ENABLE_YARR_JIT) */ + /* Sanity Check */ #if ENABLE(YARR_JIT) && !ENABLE(YARR) #error "YARR_JIT requires YARR" @@ -625,7 +728,7 @@ #endif /* Setting this flag prevents the assembler from using RWX memory; this may improve security but currectly comes at a significant performance cost. */ -#if PLATFORM(ARM_V7) && PLATFORM(IPHONE) +#if PLATFORM(IPHONE) #define ENABLE_ASSEMBLER_WX_EXCLUSIVE 1 #else #define ENABLE_ASSEMBLER_WX_EXCLUSIVE 0 @@ -650,4 +753,15 @@ #define WTF_USE_FONT_FAST_PATH 1 #endif +/* Accelerated compositing */ +#if PLATFORM(MAC) +#if !defined(BUILDING_ON_TIGER) +#define WTF_USE_ACCELERATED_COMPOSITING 1 +#endif +#endif + +#if PLATFORM(IPHONE) +#define WTF_USE_ACCELERATED_COMPOSITING 1 +#endif + #endif /* WTF_Platform_h */ diff --git a/JavaScriptCore/wtf/PtrAndFlags.h b/JavaScriptCore/wtf/PtrAndFlags.h index 477e893..485c595 100644 --- a/JavaScriptCore/wtf/PtrAndFlags.h +++ b/JavaScriptCore/wtf/PtrAndFlags.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Google Inc. All rights reserved. + * Copyright (C) 2009 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 @@ -37,14 +37,29 @@ namespace WTF { template<class T, typename FlagEnum> class PtrAndFlags { public: PtrAndFlags() : m_ptrAndFlags(0) {} + PtrAndFlags(T* ptr) : m_ptrAndFlags(0) { set(ptr); } bool isFlagSet(FlagEnum flagNumber) const { ASSERT(flagNumber < 2); return m_ptrAndFlags & (1 << flagNumber); } void setFlag(FlagEnum flagNumber) { ASSERT(flagNumber < 2); m_ptrAndFlags |= (1 << flagNumber);} void clearFlag(FlagEnum flagNumber) { ASSERT(flagNumber < 2); m_ptrAndFlags &= ~(1 << flagNumber);} T* get() const { return reinterpret_cast<T*>(m_ptrAndFlags & ~3); } - void set(T* ptr) { ASSERT(!(reinterpret_cast<intptr_t>(ptr) & 3)); m_ptrAndFlags = reinterpret_cast<intptr_t>(ptr) | (m_ptrAndFlags & 3);} + void set(T* ptr) + { + ASSERT(!(reinterpret_cast<intptr_t>(ptr) & 3)); + m_ptrAndFlags = reinterpret_cast<intptr_t>(ptr) | (m_ptrAndFlags & 3); +#ifndef NDEBUG + m_leaksPtr = ptr; +#endif + } + + bool operator!() const { return !get(); } + T* operator->() const { return reinterpret_cast<T*>(m_ptrAndFlags & ~3); } + private: intptr_t m_ptrAndFlags; +#ifndef NDEBUG + void* m_leaksPtr; // Only used to allow tools like leaks on OSX to detect that the memory is referenced. +#endif }; } // namespace WTF diff --git a/JavaScriptCore/wtf/RandomNumber.cpp b/JavaScriptCore/wtf/RandomNumber.cpp index c94d5a4..0e6e208 100644 --- a/JavaScriptCore/wtf/RandomNumber.cpp +++ b/JavaScriptCore/wtf/RandomNumber.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. - * (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,6 +34,12 @@ #include <stdint.h> #include <stdlib.h> +#if PLATFORM(WINCE) +extern "C" { +#include "wince/mt19937ar.c" +} +#endif + namespace WTF { double weakRandomNumber() @@ -74,6 +80,8 @@ double randomNumber() // Mask off the low 53bits fullRandom &= (1LL << 53) - 1; return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53); +#elif PLATFORM(WINCE) + return genrand_res53(); #else uint32_t part1 = rand() & (RAND_MAX - 1); uint32_t part2 = rand() & (RAND_MAX - 1); diff --git a/JavaScriptCore/wtf/RandomNumberSeed.h b/JavaScriptCore/wtf/RandomNumberSeed.h index f994fd9..a66433e 100644 --- a/JavaScriptCore/wtf/RandomNumberSeed.h +++ b/JavaScriptCore/wtf/RandomNumberSeed.h @@ -38,6 +38,12 @@ #include <unistd.h> #endif +#if PLATFORM(WINCE) +extern "C" { +void init_by_array(unsigned long init_key[],int key_length); +} +#endif + // Internal JavaScriptCore usage only namespace WTF { @@ -45,8 +51,19 @@ inline void initializeRandomNumberGenerator() { #if PLATFORM(DARWIN) // On Darwin we use arc4random which initialises itself. +#elif PLATFORM(WINCE) + // initialize rand() + srand(static_cast<unsigned>(time(0))); + + // use rand() to initialize the real RNG + unsigned long initializationBuffer[4]; + initializationBuffer[0] = (rand() << 16) | rand(); + initializationBuffer[1] = (rand() << 16) | rand(); + initializationBuffer[2] = (rand() << 16) | rand(); + initializationBuffer[3] = (rand() << 16) | rand(); + init_by_array(initializationBuffer, 4); #elif COMPILER(MSVC) && defined(_CRT_RAND_S) - // On Windows we use rand_s which intialises itself + // On Windows we use rand_s which initialises itself #elif PLATFORM(UNIX) // srandomdev is not guaranteed to exist on linux so we use this poor seed, this should be improved timeval time; diff --git a/JavaScriptCore/wtf/RefCounted.h b/JavaScriptCore/wtf/RefCounted.h index c174145..761a856 100644 --- a/JavaScriptCore/wtf/RefCounted.h +++ b/JavaScriptCore/wtf/RefCounted.h @@ -29,7 +29,7 @@ namespace WTF { // This base class holds the non-template methods and attributes. // The RefCounted class inherits from it reducing the template bloat // generated by the compiler (technique called template hoisting). -class RefCountedBase : Noncopyable { +class RefCountedBase { public: void ref() { @@ -101,7 +101,7 @@ private: }; -template<class T> class RefCounted : public RefCountedBase { +template<class T> class RefCounted : public RefCountedBase, public Noncopyable { public: void deref() { @@ -115,8 +115,23 @@ protected: } }; +template<class T> class RefCountedCustomAllocated : public RefCountedBase, public NoncopyableCustomAllocated { +public: + void deref() + { + if (derefBase()) + delete static_cast<T*>(this); + } + +protected: + ~RefCountedCustomAllocated() + { + } +}; + } // namespace WTF using WTF::RefCounted; +using WTF::RefCountedCustomAllocated; #endif // RefCounted_h diff --git a/JavaScriptCore/wtf/RefPtr.h b/JavaScriptCore/wtf/RefPtr.h index 929e745..74cd0ea 100644 --- a/JavaScriptCore/wtf/RefPtr.h +++ b/JavaScriptCore/wtf/RefPtr.h @@ -23,6 +23,7 @@ #include <algorithm> #include "AlwaysInline.h" +#include "FastAllocBase.h" namespace WTF { @@ -32,7 +33,7 @@ namespace WTF { enum HashTableDeletedValueType { HashTableDeletedValue }; - template <typename T> class RefPtr { + template <typename T> class RefPtr : public FastAllocBase { public: RefPtr() : m_ptr(0) { } RefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); } diff --git a/JavaScriptCore/wtf/RefPtrHashMap.h b/JavaScriptCore/wtf/RefPtrHashMap.h index 1cbebb4..9433025 100644 --- a/JavaScriptCore/wtf/RefPtrHashMap.h +++ b/JavaScriptCore/wtf/RefPtrHashMap.h @@ -42,7 +42,7 @@ namespace WTF { }; template<typename T, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> - class HashMap<RefPtr<T>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> { + class HashMap<RefPtr<T>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> : public FastAllocBase { private: typedef KeyTraitsArg KeyTraits; typedef MappedTraitsArg MappedTraits; diff --git a/JavaScriptCore/wtf/SegmentedVector.h b/JavaScriptCore/wtf/SegmentedVector.h new file mode 100644 index 0000000..065c19c --- /dev/null +++ b/JavaScriptCore/wtf/SegmentedVector.h @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2008 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. + * 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 SegmentedVector_h +#define SegmentedVector_h + +#include <wtf/Vector.h> + +namespace WTF { + + // An iterator for SegmentedVector. It supports only the pre ++ operator + template <typename T, size_t SegmentSize> class SegmentedVector; + template <typename T, size_t SegmentSize> class SegmentedVectorIterator { + private: + friend class SegmentedVector<T, SegmentSize>; + public: + typedef SegmentedVectorIterator<T, SegmentSize> Iterator; + + ~SegmentedVectorIterator() { } + + T& operator*() const { return m_vector.m_segments.at(m_segment)->at(m_index); } + T* operator->() const { return &m_vector.m_segments.at(m_segment)->at(m_index); } + + // Only prefix ++ operator supported + Iterator& operator++() + { + ASSERT(m_index != SegmentSize); + ++m_index; + if (m_index >= m_vector.m_segments.at(m_segment)->size()) { + if (m_segment + 1 < m_vector.m_segments.size()) { + ASSERT(m_vector.m_segments.at(m_segment)->size() > 0); + ++m_segment; + m_index = 0; + } else { + // Points to the "end" symbol + m_segment = 0; + m_index = SegmentSize; + } + } + return *this; + } + + bool operator==(const Iterator& other) const + { + return (m_index == other.m_index && m_segment = other.m_segment && &m_vector == &other.m_vector); + } + + bool operator!=(const Iterator& other) const + { + return (m_index != other.m_index || m_segment != other.m_segment || &m_vector != &other.m_vector); + } + + SegmentedVectorIterator& operator=(const SegmentedVectorIterator<T, SegmentSize>& other) + { + m_vector = other.m_vector; + m_segment = other.m_segment; + m_index = other.m_index; + return *this; + } + + private: + SegmentedVectorIterator(SegmentedVector<T, SegmentSize>& vector, size_t segment, size_t index) + : m_vector(vector) + , m_segment(segment) + , m_index(index) + { + } + + SegmentedVector<T, SegmentSize>& m_vector; + size_t m_segment; + size_t m_index; + }; + + // SegmentedVector is just like Vector, but it doesn't move the values + // stored in its buffer when it grows. Therefore, it is safe to keep + // pointers into a SegmentedVector. + template <typename T, size_t SegmentSize> class SegmentedVector { + friend class SegmentedVectorIterator<T, SegmentSize>; + public: + typedef SegmentedVectorIterator<T, SegmentSize> Iterator; + + SegmentedVector() + : m_size(0) + { + m_segments.append(&m_inlineSegment); + } + + ~SegmentedVector() + { + deleteAllSegments(); + } + + size_t size() const { return m_size; } + + T& at(size_t index) + { + if (index < SegmentSize) + return m_inlineSegment[index]; + return segmentFor(index)->at(subscriptFor(index)); + } + + T& operator[](size_t index) + { + return at(index); + } + + T& last() + { + return at(size() - 1); + } + + template <typename U> void append(const U& value) + { + ++m_size; + + if (m_size <= SegmentSize) { + m_inlineSegment.uncheckedAppend(value); + return; + } + + if (!segmentExistsFor(m_size - 1)) + m_segments.append(new Segment); + segmentFor(m_size - 1)->uncheckedAppend(value); + } + + T& alloc() + { + append<T>(T()); + return last(); + } + + void removeLast() + { + if (m_size <= SegmentSize) + m_inlineSegment.removeLast(); + else + segmentFor(m_size - 1)->removeLast(); + --m_size; + } + + void grow(size_t size) + { + ASSERT(size > m_size); + ensureSegmentsFor(size); + m_size = size; + } + + void clear() + { + deleteAllSegments(); + m_segments.resize(1); + m_inlineSegment.clear(); + m_size = 0; + } + + Iterator begin() + { + return Iterator(*this, 0, m_size ? 0 : SegmentSize); + } + + Iterator end() + { + return Iterator(*this, 0, SegmentSize); + } + + private: + typedef Vector<T, SegmentSize> Segment; + + void deleteAllSegments() + { + // Skip the first segment, because it's our inline segment, which was + // not created by new. + for (size_t i = 1; i < m_segments.size(); i++) + delete m_segments[i]; + } + + bool segmentExistsFor(size_t index) + { + return index / SegmentSize < m_segments.size(); + } + + Segment* segmentFor(size_t index) + { + return m_segments[index / SegmentSize]; + } + + size_t subscriptFor(size_t index) + { + return index % SegmentSize; + } + + void ensureSegmentsFor(size_t size) + { + size_t segmentCount = m_size / SegmentSize; + if (m_size % SegmentSize) + ++segmentCount; + segmentCount = std::max<size_t>(segmentCount, 1); // We always have at least our inline segment. + + size_t neededSegmentCount = size / SegmentSize; + if (size % SegmentSize) + ++neededSegmentCount; + + // Fill up to N - 1 segments. + size_t end = neededSegmentCount - 1; + for (size_t i = segmentCount - 1; i < end; ++i) + ensureSegment(i, SegmentSize); + + // Grow segment N to accomodate the remainder. + ensureSegment(end, subscriptFor(size - 1) + 1); + } + + void ensureSegment(size_t segmentIndex, size_t size) + { + ASSERT(segmentIndex <= m_segments.size()); + if (segmentIndex == m_segments.size()) + m_segments.append(new Segment); + m_segments[segmentIndex]->grow(size); + } + + size_t m_size; + Segment m_inlineSegment; + Vector<Segment*, 32> m_segments; + }; + +} // namespace WTF + +#endif // SegmentedVector_h diff --git a/JavaScriptCore/wtf/StdLibExtras.h b/JavaScriptCore/wtf/StdLibExtras.h index afc5e8a..d21d1ff 100644 --- a/JavaScriptCore/wtf/StdLibExtras.h +++ b/JavaScriptCore/wtf/StdLibExtras.h @@ -41,6 +41,11 @@ static type& name = *new type arguments #endif +// OBJECT_OFFSETOF: Like the C++ offsetof macro, but you can use it with classes. +// The magic number 0x4000 is insignificant. We use it to avoid using NULL, since +// NULL can cause compiler problems, especially in cases of multiple inheritance. +#define OBJECT_OFFSETOF(class, field) (reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<class*>(0x4000)->field)) - 0x4000) + namespace WTF { /* diff --git a/JavaScriptCore/wtf/StringExtras.h b/JavaScriptCore/wtf/StringExtras.h index 926fd61..1c23390 100644 --- a/JavaScriptCore/wtf/StringExtras.h +++ b/JavaScriptCore/wtf/StringExtras.h @@ -45,7 +45,7 @@ inline int snprintf(char* buffer, size_t count, const char* format, ...) return result; } -#if COMPILER(MSVC7) || PLATFORM(WIN_CE) +#if COMPILER(MSVC7) || PLATFORM(WINCE) inline int vsnprintf(char* buffer, size_t count, const char* format, va_list args) { @@ -54,7 +54,7 @@ inline int vsnprintf(char* buffer, size_t count, const char* format, va_list arg #endif -#if PLATFORM(WIN_CE) +#if PLATFORM(WINCE) inline int strnicmp(const char* string1, const char* string2, size_t count) { diff --git a/JavaScriptCore/wtf/TCSystemAlloc.cpp b/JavaScriptCore/wtf/TCSystemAlloc.cpp index 478ce63..659bb0e 100644 --- a/JavaScriptCore/wtf/TCSystemAlloc.cpp +++ b/JavaScriptCore/wtf/TCSystemAlloc.cpp @@ -31,6 +31,14 @@ // Author: Sanjay Ghemawat #include "config.h" +#include "TCSystemAlloc.h" + +#include <algorithm> +#include <fcntl.h> +#include "Assertions.h" +#include "TCSpinLock.h" +#include "UnusedParam.h" + #if HAVE(STDINT_H) #include <stdint.h> #elif HAVE(INTTYPES_H) @@ -38,6 +46,7 @@ #else #include <sys/types.h> #endif + #if PLATFORM(WIN_OS) #include "windows.h" #else @@ -45,16 +54,13 @@ #include <unistd.h> #include <sys/mman.h> #endif -#include <fcntl.h> -#include "Assertions.h" -#include "TCSystemAlloc.h" -#include "TCSpinLock.h" -#include "UnusedParam.h" #ifndef MAP_ANONYMOUS #define MAP_ANONYMOUS MAP_ANON #endif +using namespace std; + // Structure for discovering alignment union MemoryAligner { void* p; @@ -441,6 +447,32 @@ void TCMalloc_SystemRelease(void* start, size_t length) ASSERT_UNUSED(newAddress, newAddress == start || newAddress == reinterpret_cast<void*>(MAP_FAILED)); } +#elif HAVE(VIRTUALALLOC) + +void TCMalloc_SystemRelease(void* start, size_t length) +{ + if (VirtualFree(start, length, MEM_DECOMMIT)) + return; + + // The decommit may fail if the memory region consists of allocations + // from more than one call to VirtualAlloc. In this case, fall back to + // using VirtualQuery to retrieve the allocation boundaries and decommit + // them each individually. + + char* ptr = static_cast<char*>(start); + char* end = ptr + length; + MEMORY_BASIC_INFORMATION info; + while (ptr < end) { + size_t resultSize = VirtualQuery(ptr, &info, sizeof(info)); + ASSERT_UNUSED(resultSize, resultSize == sizeof(info)); + + size_t decommitSize = min<size_t>(info.RegionSize, end - ptr); + BOOL success = VirtualFree(ptr, decommitSize, MEM_DECOMMIT); + ASSERT_UNUSED(success, success); + ptr += decommitSize; + } +} + #else // Platforms that don't support returning memory use an empty inline version of TCMalloc_SystemRelease @@ -457,8 +489,28 @@ void TCMalloc_SystemCommit(void* start, size_t length) #elif HAVE(VIRTUALALLOC) -void TCMalloc_SystemCommit(void*, size_t) +void TCMalloc_SystemCommit(void* start, size_t length) { + if (VirtualAlloc(start, length, MEM_COMMIT, PAGE_READWRITE) == start) + return; + + // The commit may fail if the memory region consists of allocations + // from more than one call to VirtualAlloc. In this case, fall back to + // using VirtualQuery to retrieve the allocation boundaries and commit them + // each individually. + + char* ptr = static_cast<char*>(start); + char* end = ptr + length; + MEMORY_BASIC_INFORMATION info; + while (ptr < end) { + size_t resultSize = VirtualQuery(ptr, &info, sizeof(info)); + ASSERT_UNUSED(resultSize, resultSize == sizeof(info)); + + size_t commitSize = min<size_t>(info.RegionSize, end - ptr); + void* newAddress = VirtualAlloc(ptr, commitSize, MEM_COMMIT, PAGE_READWRITE); + ASSERT_UNUSED(newAddress, newAddress == ptr); + ptr += commitSize; + } } #else diff --git a/JavaScriptCore/wtf/TCSystemAlloc.h b/JavaScriptCore/wtf/TCSystemAlloc.h index 8e3a01a..1c67788 100644 --- a/JavaScriptCore/wtf/TCSystemAlloc.h +++ b/JavaScriptCore/wtf/TCSystemAlloc.h @@ -64,7 +64,7 @@ extern void TCMalloc_SystemRelease(void* start, size_t length); extern void TCMalloc_SystemCommit(void* start, size_t length); -#if !HAVE(MADV_FREE_REUSE) && !HAVE(MADV_DONTNEED) && !HAVE(MMAP) +#if !HAVE(MADV_FREE_REUSE) && !HAVE(MADV_DONTNEED) && !HAVE(MMAP) && !HAVE(VIRTUALALLOC) inline void TCMalloc_SystemRelease(void*, size_t) { } #endif diff --git a/JavaScriptCore/wtf/ThreadSpecific.h b/JavaScriptCore/wtf/ThreadSpecific.h index b07a9a2..4d5d2f7 100644 --- a/JavaScriptCore/wtf/ThreadSpecific.h +++ b/JavaScriptCore/wtf/ThreadSpecific.h @@ -59,7 +59,7 @@ namespace WTF { void ThreadSpecificThreadExit(); #endif -template<typename T> class ThreadSpecific : Noncopyable { +template<typename T> class ThreadSpecific : public Noncopyable { public: ThreadSpecific(); T* operator->(); diff --git a/JavaScriptCore/wtf/Threading.cpp b/JavaScriptCore/wtf/Threading.cpp index bd25ee7..56bf438 100644 --- a/JavaScriptCore/wtf/Threading.cpp +++ b/JavaScriptCore/wtf/Threading.cpp @@ -30,7 +30,7 @@ namespace WTF { -struct NewThreadContext { +struct NewThreadContext : FastAllocBase { NewThreadContext(ThreadFunction entryPoint, void* data, const char* name) : entryPoint(entryPoint) , data(data) diff --git a/JavaScriptCore/wtf/Threading.h b/JavaScriptCore/wtf/Threading.h index e562f35..66e0d2a 100644 --- a/JavaScriptCore/wtf/Threading.h +++ b/JavaScriptCore/wtf/Threading.h @@ -59,7 +59,9 @@ #ifndef Threading_h #define Threading_h -#if PLATFORM(WIN_CE) +#include "Platform.h" + +#if PLATFORM(WINCE) #include <windows.h> #endif @@ -67,7 +69,7 @@ #include <wtf/Locker.h> #include <wtf/Noncopyable.h> -#if PLATFORM(WIN_OS) && !PLATFORM(WIN_CE) +#if PLATFORM(WIN_OS) && !PLATFORM(WINCE) #include <windows.h> #elif PLATFORM(DARWIN) #include <libkern/OSAtomic.h> @@ -128,18 +130,22 @@ void detachThread(ThreadIdentifier); #if USE(PTHREADS) typedef pthread_mutex_t PlatformMutex; +typedef pthread_rwlock_t PlatformReadWriteLock; typedef pthread_cond_t PlatformCondition; #elif PLATFORM(GTK) typedef GOwnPtr<GMutex> PlatformMutex; +typedef void* PlatformReadWriteLock; // FIXME: Implement. typedef GOwnPtr<GCond> PlatformCondition; #elif PLATFORM(QT) typedef QT_PREPEND_NAMESPACE(QMutex)* PlatformMutex; +typedef void* PlatformReadWriteLock; // FIXME: Implement. typedef QT_PREPEND_NAMESPACE(QWaitCondition)* PlatformCondition; #elif PLATFORM(WIN_OS) struct PlatformMutex { CRITICAL_SECTION m_internalMutex; size_t m_recursionCount; }; +typedef void* PlatformReadWriteLock; // FIXME: Implement. struct PlatformCondition { size_t m_waitersGone; size_t m_waitersBlocked; @@ -153,10 +159,11 @@ struct PlatformCondition { }; #else typedef void* PlatformMutex; +typedef void* PlatformReadWriteLock; typedef void* PlatformCondition; #endif -class Mutex : Noncopyable { +class Mutex : public Noncopyable { public: Mutex(); ~Mutex(); @@ -173,7 +180,24 @@ private: typedef Locker<Mutex> MutexLocker; -class ThreadCondition : Noncopyable { +class ReadWriteLock : public Noncopyable { +public: + ReadWriteLock(); + ~ReadWriteLock(); + + void readLock(); + bool tryReadLock(); + + void writeLock(); + bool tryWriteLock(); + + void unlock(); + +private: + PlatformReadWriteLock m_readWriteLock; +}; + +class ThreadCondition : public Noncopyable { public: ThreadCondition(); ~ThreadCondition(); @@ -192,7 +216,7 @@ private: #if PLATFORM(WIN_OS) #define WTF_USE_LOCKFREE_THREADSAFESHARED 1 -#if COMPILER(MINGW) || COMPILER(MSVC7) || PLATFORM(WIN_CE) +#if COMPILER(MINGW) || COMPILER(MSVC7) || PLATFORM(WINCE) inline void atomicIncrement(int* addend) { InterlockedIncrement(reinterpret_cast<long*>(addend)); } inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); } #else @@ -219,7 +243,7 @@ inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_ #endif -class ThreadSafeSharedBase : Noncopyable { +class ThreadSafeSharedBase : public Noncopyable { public: ThreadSafeSharedBase(int initialRefCount = 1) : m_refCount(initialRefCount) diff --git a/JavaScriptCore/wtf/ThreadingNone.cpp b/JavaScriptCore/wtf/ThreadingNone.cpp index e713102..46f23d2 100644 --- a/JavaScriptCore/wtf/ThreadingNone.cpp +++ b/JavaScriptCore/wtf/ThreadingNone.cpp @@ -48,8 +48,8 @@ void Mutex::unlock() { } ThreadCondition::ThreadCondition() { } ThreadCondition::~ThreadCondition() { } -void ThreadCondition::wait(Mutex& mutex) { } -bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime) { return false; } +void ThreadCondition::wait(Mutex&) { } +bool ThreadCondition::timedWait(Mutex&, double) { return false; } void ThreadCondition::signal() { } void ThreadCondition::broadcast() { } diff --git a/JavaScriptCore/wtf/ThreadingPthreads.cpp b/JavaScriptCore/wtf/ThreadingPthreads.cpp index 1aa5600..a321b40 100644 --- a/JavaScriptCore/wtf/ThreadingPthreads.cpp +++ b/JavaScriptCore/wtf/ThreadingPthreads.cpp @@ -268,6 +268,61 @@ void Mutex::unlock() ASSERT_UNUSED(result, !result); } + +ReadWriteLock::ReadWriteLock() +{ + pthread_rwlock_init(&m_readWriteLock, NULL); +} + +ReadWriteLock::~ReadWriteLock() +{ + pthread_rwlock_destroy(&m_readWriteLock); +} + +void ReadWriteLock::readLock() +{ + int result = pthread_rwlock_rdlock(&m_readWriteLock); + ASSERT_UNUSED(result, !result); +} + +bool ReadWriteLock::tryReadLock() +{ + int result = pthread_rwlock_tryrdlock(&m_readWriteLock); + + if (result == 0) + return true; + if (result == EBUSY || result == EAGAIN) + return false; + + ASSERT_NOT_REACHED(); + return false; +} + +void ReadWriteLock::writeLock() +{ + int result = pthread_rwlock_wrlock(&m_readWriteLock); + ASSERT_UNUSED(result, !result); +} + +bool ReadWriteLock::tryWriteLock() +{ + int result = pthread_rwlock_trywrlock(&m_readWriteLock); + + if (result == 0) + return true; + if (result == EBUSY || result == EAGAIN) + return false; + + ASSERT_NOT_REACHED(); + return false; +} + +void ReadWriteLock::unlock() +{ + int result = pthread_rwlock_unlock(&m_readWriteLock); + ASSERT_UNUSED(result, !result); +} + ThreadCondition::ThreadCondition() { pthread_cond_init(&m_condition, NULL); diff --git a/JavaScriptCore/wtf/ThreadingWin.cpp b/JavaScriptCore/wtf/ThreadingWin.cpp index ea18656..cccbda1 100644 --- a/JavaScriptCore/wtf/ThreadingWin.cpp +++ b/JavaScriptCore/wtf/ThreadingWin.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -89,7 +90,14 @@ #if !USE(PTHREADS) && PLATFORM(WIN_OS) #include "ThreadSpecific.h" #endif +#if !PLATFORM(WINCE) #include <process.h> +#endif +#if HAVE(ERRNO_H) +#include <errno.h> +#else +#define NO_ERRNO +#endif #include <windows.h> #include <wtf/CurrentTime.h> #include <wtf/HashMap.h> @@ -210,9 +218,21 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con unsigned threadIdentifier = 0; ThreadIdentifier threadID = 0; ThreadFunctionInvocation* invocation = new ThreadFunctionInvocation(entryPoint, data); +#if PLATFORM(WINCE) + // This is safe on WINCE, since CRT is in the core and innately multithreaded. + // On desktop Windows, need to use _beginthreadex (not available on WinCE) if using any CRT functions + HANDLE threadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)wtfThreadEntryPoint, invocation, 0, (LPDWORD)&threadIdentifier); +#else HANDLE threadHandle = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, wtfThreadEntryPoint, invocation, 0, &threadIdentifier)); +#endif if (!threadHandle) { +#if PLATFORM(WINCE) + LOG_ERROR("Failed to create thread at entry point %p with data %p: %ld", entryPoint, data, ::GetLastError()); +#elif defined(NO_ERRNO) + LOG_ERROR("Failed to create thread at entry point %p with data %p.", entryPoint, data); +#else LOG_ERROR("Failed to create thread at entry point %p with data %p: %ld", entryPoint, data, errno); +#endif return 0; } diff --git a/JavaScriptCore/wtf/Vector.h b/JavaScriptCore/wtf/Vector.h index dcfeb29..7cba4e4 100644 --- a/JavaScriptCore/wtf/Vector.h +++ b/JavaScriptCore/wtf/Vector.h @@ -21,16 +21,17 @@ #ifndef WTF_Vector_h #define WTF_Vector_h -#include "Assertions.h" -#include "FastMalloc.h" +#include "FastAllocBase.h" #include "Noncopyable.h" #include "NotFound.h" #include "VectorTraits.h" #include <limits> -#include <stdlib.h> -#include <string.h> #include <utility> +#if PLATFORM(QT) +#include <QDataStream> +#endif + namespace WTF { using std::min; @@ -267,7 +268,7 @@ namespace WTF { }; template<typename T> - class VectorBufferBase : Noncopyable { + class VectorBufferBase : public Noncopyable { public: void allocateBuffer(size_t newCapacity) { @@ -433,7 +434,7 @@ namespace WTF { }; template<typename T, size_t inlineCapacity = 0> - class Vector { + class Vector : public FastAllocBase { private: typedef VectorBuffer<T, inlineCapacity> Buffer; typedef VectorTypeOperations<T> TypeOperations; @@ -566,6 +567,32 @@ namespace WTF { Buffer m_buffer; }; +#if PLATFORM(QT) + template<typename T> + QDataStream& operator<<(QDataStream& stream, const Vector<T>& data) + { + stream << qint64(data.size()); + foreach (const T& i, data) + stream << i; + return stream; + } + + template<typename T> + QDataStream& operator>>(QDataStream& stream, Vector<T>& data) + { + data.clear(); + qint64 count; + T item; + stream >> count; + data.reserveCapacity(count); + for (qint64 i = 0; i < count; ++i) { + stream >> item; + data.append(item); + } + return stream; + } +#endif + template<typename T, size_t inlineCapacity> Vector<T, inlineCapacity>::Vector(const Vector& other) : m_size(other.size()) @@ -907,7 +934,7 @@ namespace WTF { inline void Vector<T, inlineCapacity>::remove(size_t position, size_t length) { ASSERT(position < size()); - ASSERT(position + length < size()); + ASSERT(position + length <= size()); T* beginSpot = begin() + position; T* endSpot = beginSpot + length; TypeOperations::destruct(beginSpot, endSpot); diff --git a/JavaScriptCore/wtf/dtoa.cpp b/JavaScriptCore/wtf/dtoa.cpp index 9509388..d75c17a 100644 --- a/JavaScriptCore/wtf/dtoa.cpp +++ b/JavaScriptCore/wtf/dtoa.cpp @@ -148,6 +148,7 @@ #include <wtf/AlwaysInline.h> #include <wtf/Assertions.h> #include <wtf/FastMalloc.h> +#include <wtf/Vector.h> #include <wtf/Threading.h> #include <stdio.h> @@ -255,6 +256,8 @@ typedef union { double d; uint32_t L[2]; } U; #define Big0 (Frac_mask1 | Exp_msk1 * (DBL_MAX_EXP + Bias - 1)) #define Big1 0xffffffff + +// FIXME: we should remove non-Pack_32 mode since it is unused and unmaintained #ifndef Pack_32 #define Pack_32 #endif @@ -278,25 +281,41 @@ typedef union { double d; uint32_t L[2]; } U; #define Kmax 15 struct BigInt { - BigInt() : sign(0), wds(0) { } - BigInt(const BigInt& other) : sign(other.sign), wds(other.wds) + BigInt() : sign(0) { } + int sign; + + void clear() + { + sign = 0; + m_words.clear(); + } + + size_t size() const + { + return m_words.size(); + } + + void resize(size_t s) { - for (int i = 0; i < 64; ++i) - x[i] = other.x[i]; + m_words.resize(s); + } + + uint32_t* words() + { + return m_words.data(); } - BigInt& operator=(const BigInt& other) + const uint32_t* words() const { - sign = other.sign; - wds = other.wds; - for (int i = 0; i < 64; ++i) - x[i] = other.x[i]; - return *this; + return m_words.data(); } - int sign; - int wds; - uint32_t x[64]; + void append(uint32_t w) + { + m_words.append(w); + } + + Vector<uint32_t, 16> m_words; }; static void multadd(BigInt& b, int m, int a) /* multiply by m and add a */ @@ -307,8 +326,8 @@ static void multadd(BigInt& b, int m, int a) /* multiply by m and add a */ uint32_t carry; #endif - int wds = b.wds; - uint32_t* x = b.x; + int wds = b.size(); + uint32_t* x = b.words(); int i = 0; carry = a; do { @@ -331,10 +350,8 @@ static void multadd(BigInt& b, int m, int a) /* multiply by m and add a */ #endif } while (++i < wds); - if (carry) { - b.x[wds++] = (uint32_t)carry; - b.wds = wds; - } + if (carry) + b.append((uint32_t)carry); } static void s2b(BigInt& b, const char* s, int nd0, int nd, uint32_t y9) @@ -346,12 +363,12 @@ static void s2b(BigInt& b, const char* s, int nd0, int nd, uint32_t y9) for (k = 0, y = 1; x > y; y <<= 1, k++) { } #ifdef Pack_32 b.sign = 0; - b.x[0] = y9; - b.wds = 1; + b.resize(1); + b.words()[0] = y9; #else b.sign = 0; - b.x[0] = y9 & 0xffff; - b.wds = (b->x[1] = y9 >> 16) ? 2 : 1; + b.resize((b->x[1] = y9 >> 16) ? 2 : 1); + b.words()[0] = y9 & 0xffff; #endif int i = 9; @@ -440,8 +457,8 @@ static int lo0bits (uint32_t* y) static void i2b(BigInt& b, int i) { b.sign = 0; - b.x[0] = i; - b.wds = 1; + b.resize(1); + b.words()[0] = i; } static void mult(BigInt& aRef, const BigInt& bRef) @@ -459,23 +476,24 @@ static void mult(BigInt& aRef, const BigInt& bRef) uint32_t carry, z; #endif - if (a->wds < b->wds) { + if (a->size() < b->size()) { const BigInt* tmp = a; a = b; b = tmp; } - wa = a->wds; - wb = b->wds; + wa = a->size(); + wb = b->size(); wc = wa + wb; + c.resize(wc); - for (xc = c.x, xa = xc + wc; xc < xa; xc++) + for (xc = c.words(), xa = xc + wc; xc < xa; xc++) *xc = 0; - xa = a->x; + xa = a->words(); xae = xa + wa; - xb = b->x; + xb = b->words(); xbe = xb + wb; - xc0 = c.x; + xc0 = c.words(); #ifdef USE_LONG_LONG for (; xb < xbe; xc0++) { if ((y = *xb++)) { @@ -537,8 +555,8 @@ static void mult(BigInt& aRef, const BigInt& bRef) } #endif #endif - for (xc0 = c.x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) { } - c.wds = wc; + for (xc0 = c.words(), xc = xc0 + wc; wc > 0 && !*--xc; --wc) { } + c.resize(wc); aRef = c; } @@ -617,14 +635,20 @@ static ALWAYS_INLINE void lshift(BigInt& b, int k) int n = k >> 4; #endif - int n1 = n + b.wds + 1; + int origSize = b.size(); + int n1 = n + origSize + 1; + + if (k &= 0x1f) + b.resize(b.size() + n + 1); + else + b.resize(b.size() + n); - const uint32_t* srcStart = b.x; - uint32_t* dstStart = b.x; - const uint32_t* src = srcStart + b.wds - 1; + const uint32_t* srcStart = b.words(); + uint32_t* dstStart = b.words(); + const uint32_t* src = srcStart + origSize - 1; uint32_t* dst = dstStart + n1 - 1; #ifdef Pack_32 - if (k &= 0x1f) { + if (k) { uint32_t hiSubword = 0; int s = 32 - k; for (; src >= srcStart; --src) { @@ -633,7 +657,8 @@ static ALWAYS_INLINE void lshift(BigInt& b, int k) } *dst = hiSubword; ASSERT(dst == dstStart + n); - b.wds = b.wds + n + (b.x[n1 - 1] != 0); + + b.resize(origSize + n + (b.words()[n1 - 1] != 0)); } #else if (k &= 0xf) { @@ -652,10 +677,11 @@ static ALWAYS_INLINE void lshift(BigInt& b, int k) do { *--dst = *src--; } while (src >= srcStart); - b.wds = b.wds + n; } for (dst = dstStart + n; dst != dstStart; ) *--dst = 0; + + ASSERT(b.size() <= 1 || b.words()[b.size() - 1]); } static int cmp(const BigInt& a, const BigInt& b) @@ -663,15 +689,15 @@ static int cmp(const BigInt& a, const BigInt& b) const uint32_t *xa, *xa0, *xb, *xb0; int i, j; - i = a.wds; - j = b.wds; - ASSERT(i <= 1 || a.x[i - 1]); - ASSERT(j <= 1 || b.x[j - 1]); + i = a.size(); + j = b.size(); + ASSERT(i <= 1 || a.words()[i - 1]); + ASSERT(j <= 1 || b.words()[j - 1]); if (i -= j) return i; - xa0 = a.x; + xa0 = a.words(); xa = xa0 + j; - xb0 = b.x; + xb0 = b.words(); xb = xb0 + j; for (;;) { if (*--xa != *--xb) @@ -692,8 +718,8 @@ static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef i = cmp(*a, *b); if (!i) { c.sign = 0; - c.wds = 1; - c.x[0] = 0; + c.resize(1); + c.words()[0] = 0; return; } if (i < 0) { @@ -704,15 +730,16 @@ static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef } else i = 0; - c.wds = 0; - c.sign = i; - wa = a->wds; - const uint32_t* xa = a->x; + wa = a->size(); + const uint32_t* xa = a->words(); const uint32_t* xae = xa + wa; - wb = b->wds; - const uint32_t* xb = b->x; + wb = b->size(); + const uint32_t* xb = b->words(); const uint32_t* xbe = xb + wb; - xc = c.x; + + c.resize(wa); + c.sign = i; + xc = c.words(); #ifdef USE_LONG_LONG unsigned long long borrow = 0; do { @@ -757,7 +784,7 @@ static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef #endif while (!*--xc) wa--; - c.wds = wa; + c.resize(wa); } static double ulp(U *x) @@ -804,8 +831,8 @@ static double b2d(const BigInt& a, int* e) #define d0 word0(&d) #define d1 word1(&d) - xa0 = a.x; - xa = xa0 + a.wds; + xa0 = a.words(); + xa = xa0 + a.size(); y = *--xa; ASSERT(y); k = hi0bits(y); @@ -860,11 +887,11 @@ static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits) b.sign = 0; #ifdef Pack_32 - b.wds = 1; + b.resize(1); #else - b.wds = 2; + b.resize(2); #endif - x = b.x; + x = b.words(); z = d0 & Frac_mask; d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ @@ -881,17 +908,21 @@ static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits) z >>= k; } else x[0] = y; + if (z) { + b.resize(2); + x[1] = z; + } + #ifndef Sudden_Underflow - i = + i = b.size(); #endif - b.wds = (x[1] = z) ? 2 : 1; } else { k = lo0bits(&z); x[0] = z; #ifndef Sudden_Underflow - i = + i = 1; #endif - b.wds = 1; + b.resize(1); k += 32; } #else @@ -929,7 +960,7 @@ static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits) k += 32; } while (!x[i]) --i; - b->wds = i + 1; + b->resize(i + 1); #endif #ifndef Sudden_Underflow if (de) { @@ -958,9 +989,9 @@ static double ratio(const BigInt& a, const BigInt& b) dval(&da) = b2d(a, &ka); dval(&db) = b2d(b, &kb); #ifdef Pack_32 - k = ka - kb + 32 * (a.wds - b.wds); + k = ka - kb + 32 * (a.size() - b.size()); #else - k = ka - kb + 16 * (a.wds - b.wds); + k = ka - kb + 16 * (a.size() - b.size()); #endif if (k > 0) word0(&da) += k * Exp_msk1; @@ -1452,12 +1483,12 @@ undfl: #endif ) { #ifdef SET_INEXACT - if (!delta->x[0] && delta->wds <= 1) + if (!delta->words()[0] && delta->size() <= 1) inexact = 0; #endif break; } - if (!delta.x[0] && delta.wds <= 1) { + if (!delta.words()[0] && delta.size() <= 1) { /* exact result */ #ifdef SET_INEXACT inexact = 0; @@ -1700,7 +1731,7 @@ ret: static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) { - int n; + size_t n; uint32_t *bx, *bxe, q, *sx, *sxe; #ifdef USE_LONG_LONG unsigned long long borrow, carry, y, ys; @@ -1710,14 +1741,16 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) uint32_t si, z, zs; #endif #endif + ASSERT(b.size() <= 1 || b.words()[b.size() - 1]); + ASSERT(S.size() <= 1 || S.words()[S.size() - 1]); - n = S.wds; - ASSERT_WITH_MESSAGE(b.wds <= n, "oversize b in quorem"); - if (b.wds < n) + n = S.size(); + ASSERT_WITH_MESSAGE(b.size() <= n, "oversize b in quorem"); + if (b.size() < n) return 0; - sx = S.x; + sx = S.words(); sxe = sx + --n; - bx = b.x; + bx = b.words(); bxe = bx + n; q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ ASSERT_WITH_MESSAGE(q <= 9, "oversized quotient in quorem"); @@ -1752,18 +1785,18 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) #endif } while (sx <= sxe); if (!*bxe) { - bx = b.x; + bx = b.words(); while (--bxe > bx && !*bxe) --n; - b.wds = n; + b.resize(n); } } if (cmp(b, S) >= 0) { q++; borrow = 0; carry = 0; - bx = b.x; - sx = S.x; + bx = b.words(); + sx = S.words(); do { #ifdef USE_LONG_LONG ys = *sx++ + carry; @@ -1791,12 +1824,12 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) #endif #endif } while (sx <= sxe); - bx = b.x; + bx = b.words(); bxe = bx + n; if (!*bxe) { while (--bxe > bx && !*bxe) --n; - b.wds = n; + b.resize(n); } } return q; @@ -2027,7 +2060,8 @@ void dtoa(char* result, double dd, int ndigits, int* decpt, int* sign, char** rv dval(&eps) = (ieps * dval(&u)) + 7.; word0(&eps) -= (P - 1) * Exp_msk1; if (ilim == 0) { - S = mhi = BigInt(); + S.clear(); + mhi.clear(); dval(&u) -= 5.; if (dval(&u) > dval(&eps)) goto one_digit; @@ -2090,7 +2124,8 @@ fast_failed: /* Yes. */ ds = tens[k]; if (ndigits < 0 && ilim <= 0) { - S = mhi = BigInt(); + S.clear(); + mhi.clear(); if (ilim < 0 || dval(&u) <= 5 * ds) goto no_digits; goto one_digit; @@ -2132,7 +2167,8 @@ bump_up: m2 = b2; m5 = b5; - mhi = mlo = BigInt(); + mhi.clear(); + mlo.clear(); if (leftright) { i = #ifndef Sudden_Underflow @@ -2186,10 +2222,10 @@ bump_up: * can do shifts and ors to compute the numerator for q. */ #ifdef Pack_32 - if ((i = ((s5 ? 32 - hi0bits(S.x[S.wds - 1]) : 1) + s2) & 0x1f)) + if ((i = ((s5 ? 32 - hi0bits(S.words()[S.size() - 1]) : 1) + s2) & 0x1f)) i = 32 - i; #else - if ((i = ((s5 ? 32 - hi0bits(S.x[S.wds - 1]) : 1) + s2) & 0xf)) + if ((i = ((s5 ? 32 - hi0bits(S.words()[S.size() - 1]) : 1) + s2) & 0xf)) i = 16 - i; #endif if (i > 4) { @@ -2252,7 +2288,7 @@ bump_up: goto ret; } if (j < 0 || (j == 0 && !(word1(&u) & 1))) { - if (!b.x[0] && b.wds <= 1) { + if (!b.words()[0] && b.size() <= 1) { #ifdef SET_INEXACT inexact = 0; #endif @@ -2287,7 +2323,7 @@ round_9_up: } else for (i = 1;; i++) { *s++ = dig = quorem(b,S) + '0'; - if (!b.x[0] && b.wds <= 1) { + if (!b.words()[0] && b.size() <= 1) { #ifdef SET_INEXACT inexact = 0; #endif diff --git a/JavaScriptCore/wtf/haiku/MainThreadHaiku.cpp b/JavaScriptCore/wtf/haiku/MainThreadHaiku.cpp new file mode 100644 index 0000000..4fd7b35 --- /dev/null +++ b/JavaScriptCore/wtf/haiku/MainThreadHaiku.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007 Kevin Ollivier + * Copyright (C) 2009 Maxime Simon + * + * 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. + */ + +#include "config.h" +#include "MainThread.h" + + +namespace WTF { + +void initializeMainThreadPlatform() +{ + notImplemented(); +} + +void scheduleDispatchFunctionsOnMainThread() +{ + notImplemented(); +} + +} // namespace WTF + diff --git a/JavaScriptCore/wtf/unicode/Collator.h b/JavaScriptCore/wtf/unicode/Collator.h index f04779d..51e8a06 100644 --- a/JavaScriptCore/wtf/unicode/Collator.h +++ b/JavaScriptCore/wtf/unicode/Collator.h @@ -39,7 +39,7 @@ struct UCollator; namespace WTF { - class Collator : Noncopyable { + class Collator : public Noncopyable { public: enum Result { Equal = 0, Greater = 1, Less = -1 }; diff --git a/JavaScriptCore/wtf/unicode/Unicode.h b/JavaScriptCore/wtf/unicode/Unicode.h index f86a9b7..d59439d 100644 --- a/JavaScriptCore/wtf/unicode/Unicode.h +++ b/JavaScriptCore/wtf/unicode/Unicode.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 George Staikos <staikos@kde.org> * Copyright (C) 2006, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -30,6 +31,8 @@ #include <wtf/unicode/icu/UnicodeIcu.h> #elif USE(GLIB_UNICODE) #include <wtf/unicode/glib/UnicodeGLib.h> +#elif USE(WINCE_UNICODE) +#include <wtf/unicode/wince/UnicodeWince.h> #else #error "Unknown Unicode implementation" #endif diff --git a/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp b/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp index 79dec79..6376bb3 100644 --- a/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp +++ b/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp @@ -37,6 +37,7 @@ #include <string.h> #if PLATFORM(DARWIN) +#include "RetainPtr.h" #include <CoreFoundation/CoreFoundation.h> #endif @@ -60,11 +61,16 @@ std::auto_ptr<Collator> Collator::userDefault() { #if PLATFORM(DARWIN) && PLATFORM(CF) // Mac OS X doesn't set UNIX locale to match user-selected one, so ICU default doesn't work. - CFStringRef collationOrder = (CFStringRef)CFPreferencesCopyValue(CFSTR("AppleCollationOrder"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !PLATFORM(IPHONE) + RetainPtr<CFLocaleRef> currentLocale(AdoptCF, CFLocaleCopyCurrent()); + CFStringRef collationOrder = (CFStringRef)CFLocaleGetValue(currentLocale.get(), kCFLocaleCollatorIdentifier); +#else + RetainPtr<CFStringRef> collationOrderRetainer(AdoptCF, (CFStringRef)CFPreferencesCopyValue(CFSTR("AppleCollationOrder"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost)); + CFStringRef collationOrder = collationOrderRetainer.get(); +#endif char buf[256]; if (collationOrder) { CFStringGetCString(collationOrder, buf, sizeof(buf), kCFStringEncodingASCII); - CFRelease(collationOrder); return std::auto_ptr<Collator>(new Collator(buf)); } else return std::auto_ptr<Collator>(new Collator("")); diff --git a/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp b/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp new file mode 100644 index 0000000..966f2a1 --- /dev/null +++ b/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2006 George Staikos <staikos@kde.org> + * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "UnicodeWince.h" + +#include <wchar.h> + +namespace WTF { +namespace Unicode { + +wchar_t toLower(wchar_t c) +{ + return towlower(c); +} + +wchar_t toUpper(wchar_t c) +{ + return towupper(c); +} + +wchar_t foldCase(wchar_t c) +{ + return towlower(c); +} + +bool isPrintableChar(wchar_t c) +{ + return !!iswprint(c); +} + +bool isSpace(wchar_t c) +{ + return !!iswspace(c); +} + +bool isLetter(wchar_t c) +{ + return !!iswalpha(c); +} + +bool isUpper(wchar_t c) +{ + return !!iswupper(c); +} + +bool isLower(wchar_t c) +{ + return !!iswlower(c); +} + +bool isDigit(wchar_t c) +{ + return !!iswdigit(c); +} + +bool isPunct(wchar_t c) +{ + return !!iswpunct(c); +} + +int toLower(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError) +{ + const UChar* sourceIterator = source; + const UChar* sourceEnd = source + sourceLength; + UChar* resultIterator = result; + UChar* resultEnd = result + resultLength; + + int remainingCharacters = 0; + if (sourceLength <= resultLength) + while (sourceIterator < sourceEnd) + *resultIterator++ = towlower(*sourceIterator++); + else + while (resultIterator < resultEnd) + *resultIterator++ = towlower(*sourceIterator++); + + if (sourceIterator < sourceEnd) + remainingCharacters += sourceEnd - sourceIterator; + *isError = (remainingCharacters != 0); + if (resultIterator < resultEnd) + *resultIterator = 0; + + return (resultIterator - result) + remainingCharacters; +} + +int toUpper(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError) +{ + const UChar* sourceIterator = source; + const UChar* sourceEnd = source + sourceLength; + UChar* resultIterator = result; + UChar* resultEnd = result + resultLength; + + int remainingCharacters = 0; + if (sourceLength <= resultLength) + while (sourceIterator < sourceEnd) + *resultIterator++ = towupper(*sourceIterator++); + else + while (resultIterator < resultEnd) + *resultIterator++ = towupper(*sourceIterator++); + + if (sourceIterator < sourceEnd) + remainingCharacters += sourceEnd - sourceIterator; + *isError = (remainingCharacters != 0); + if (resultIterator < resultEnd) + *resultIterator = 0; + + return (resultIterator - result) + remainingCharacters; +} + +int foldCase(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError) +{ + *isError = false; + if (resultLength < sourceLength) { + *isError = true; + return sourceLength; + } + for (int i = 0; i < sourceLength; ++i) + result[i] = foldCase(source[i]); + return sourceLength; +} + +wchar_t toTitleCase(wchar_t c) +{ + return towupper(c); +} + +Direction direction(UChar32 c) +{ + return static_cast<Direction>(UnicodeCE::direction(c)); +} + +CharCategory category(unsigned int c) +{ + return static_cast<CharCategory>(TO_MASK((__int8) UnicodeCE::category(c))); +} + +DecompositionType decompositionType(UChar32 c) +{ + return static_cast<DecompositionType>(UnicodeCE::decompositionType(c)); +} + +unsigned char combiningClass(UChar32 c) +{ + return UnicodeCE::combiningClass(c); +} + +wchar_t mirroredChar(UChar32 c) +{ + return UnicodeCE::mirroredChar(c); +} + +int digitValue(wchar_t c) +{ + return UnicodeCE::digitValue(c); +} + +} // namespace Unicode +} // namespace WTF diff --git a/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h b/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h new file mode 100644 index 0000000..db656ec --- /dev/null +++ b/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h @@ -0,0 +1,216 @@ +/* + * 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. + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef UNICODE_WINCE_H +#define UNICODE_WINCE_H + +#include "ce_unicode.h" + +#define TO_MASK(x) (1 << (x)) + +// some defines from ICU needed one or two places + +#define U16_IS_LEAD(c) (((c) & 0xfffffc00) == 0xd800) +#define U16_IS_TRAIL(c) (((c) & 0xfffffc00) == 0xdc00) +#define U16_SURROGATE_OFFSET ((0xd800 << 10UL) + 0xdc00 - 0x10000) +#define U16_GET_SUPPLEMENTARY(lead, trail) \ + (((UChar32)(lead) << 10UL) + (UChar32)(trail) - U16_SURROGATE_OFFSET) + +#define U16_LEAD(supplementary) (UChar)(((supplementary) >> 10) + 0xd7c0) +#define U16_TRAIL(supplementary) (UChar)(((supplementary) & 0x3ff) | 0xdc00) + +#define U_IS_SURROGATE(c) (((c) & 0xfffff800) == 0xd800) +#define U16_IS_SURROGATE(c) U_IS_SURROGATE(c) +#define U16_IS_SURROGATE_LEAD(c) (((c) & 0x400) == 0) + +#define U16_NEXT(s, i, length, c) { \ + (c)=(s)[(i)++]; \ + if (U16_IS_LEAD(c)) { \ + uint16_t __c2; \ + if ((i) < (length) && U16_IS_TRAIL(__c2 = (s)[(i)])) { \ + ++(i); \ + (c) = U16_GET_SUPPLEMENTARY((c), __c2); \ + } \ + } \ +} + +#define U16_PREV(s, start, i, c) { \ + (c)=(s)[--(i)]; \ + if (U16_IS_TRAIL(c)) { \ + uint16_t __c2; \ + if ((i) > (start) && U16_IS_LEAD(__c2 = (s)[(i) - 1])) { \ + --(i); \ + (c) = U16_GET_SUPPLEMENTARY(__c2, (c)); \ + } \ + } \ +} + +#define U16_IS_SINGLE(c) !U_IS_SURROGATE(c) + +namespace WTF { + + namespace Unicode { + + enum Direction { + LeftToRight = UnicodeCE::U_LEFT_TO_RIGHT, + RightToLeft = UnicodeCE::U_RIGHT_TO_LEFT, + EuropeanNumber = UnicodeCE::U_EUROPEAN_NUMBER, + EuropeanNumberSeparator = UnicodeCE::U_EUROPEAN_NUMBER_SEPARATOR, + EuropeanNumberTerminator = UnicodeCE::U_EUROPEAN_NUMBER_TERMINATOR, + ArabicNumber = UnicodeCE::U_ARABIC_NUMBER, + CommonNumberSeparator = UnicodeCE::U_COMMON_NUMBER_SEPARATOR, + BlockSeparator = UnicodeCE::U_BLOCK_SEPARATOR, + SegmentSeparator = UnicodeCE::U_SEGMENT_SEPARATOR, + WhiteSpaceNeutral = UnicodeCE::U_WHITE_SPACE_NEUTRAL, + OtherNeutral = UnicodeCE::U_OTHER_NEUTRAL, + LeftToRightEmbedding = UnicodeCE::U_LEFT_TO_RIGHT_EMBEDDING, + LeftToRightOverride = UnicodeCE::U_LEFT_TO_RIGHT_OVERRIDE, + RightToLeftArabic = UnicodeCE::U_RIGHT_TO_LEFT_ARABIC, + RightToLeftEmbedding = UnicodeCE::U_RIGHT_TO_LEFT_EMBEDDING, + RightToLeftOverride = UnicodeCE::U_RIGHT_TO_LEFT_OVERRIDE, + PopDirectionalFormat = UnicodeCE::U_POP_DIRECTIONAL_FORMAT, + NonSpacingMark = UnicodeCE::U_DIR_NON_SPACING_MARK, + BoundaryNeutral = UnicodeCE::U_BOUNDARY_NEUTRAL + }; + + enum DecompositionType { + DecompositionNone = UnicodeCE::U_DT_NONE, + DecompositionCanonical = UnicodeCE::U_DT_CANONICAL, + DecompositionCompat = UnicodeCE::U_DT_COMPAT, + DecompositionCircle = UnicodeCE::U_DT_CIRCLE, + DecompositionFinal = UnicodeCE::U_DT_FINAL, + DecompositionFont = UnicodeCE::U_DT_FONT, + DecompositionFraction = UnicodeCE::U_DT_FRACTION, + DecompositionInitial = UnicodeCE::U_DT_INITIAL, + DecompositionIsolated = UnicodeCE::U_DT_ISOLATED, + DecompositionMedial = UnicodeCE::U_DT_MEDIAL, + DecompositionNarrow = UnicodeCE::U_DT_NARROW, + DecompositionNoBreak = UnicodeCE::U_DT_NOBREAK, + DecompositionSmall = UnicodeCE::U_DT_SMALL, + DecompositionSquare = UnicodeCE::U_DT_SQUARE, + DecompositionSub = UnicodeCE::U_DT_SUB, + DecompositionSuper = UnicodeCE::U_DT_SUPER, + DecompositionVertical = UnicodeCE::U_DT_VERTICAL, + DecompositionWide = UnicodeCE::U_DT_WIDE, + }; + + enum CharCategory { + NoCategory = 0, + Other_NotAssigned = TO_MASK(UnicodeCE::U_GENERAL_OTHER_TYPES), + Letter_Uppercase = TO_MASK(UnicodeCE::U_UPPERCASE_LETTER), + Letter_Lowercase = TO_MASK(UnicodeCE::U_LOWERCASE_LETTER), + Letter_Titlecase = TO_MASK(UnicodeCE::U_TITLECASE_LETTER), + Letter_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_LETTER), + Letter_Other = TO_MASK(UnicodeCE::U_OTHER_LETTER), + + Mark_NonSpacing = TO_MASK(UnicodeCE::U_NON_SPACING_MARK), + Mark_Enclosing = TO_MASK(UnicodeCE::U_ENCLOSING_MARK), + Mark_SpacingCombining = TO_MASK(UnicodeCE::U_COMBINING_SPACING_MARK), + + Number_DecimalDigit = TO_MASK(UnicodeCE::U_DECIMAL_DIGIT_NUMBER), + Number_Letter = TO_MASK(UnicodeCE::U_LETTER_NUMBER), + Number_Other = TO_MASK(UnicodeCE::U_OTHER_NUMBER), + + Separator_Space = TO_MASK(UnicodeCE::U_SPACE_SEPARATOR), + Separator_Line = TO_MASK(UnicodeCE::U_LINE_SEPARATOR), + Separator_Paragraph = TO_MASK(UnicodeCE::U_PARAGRAPH_SEPARATOR), + + Other_Control = TO_MASK(UnicodeCE::U_CONTROL_CHAR), + Other_Format = TO_MASK(UnicodeCE::U_FORMAT_CHAR), + Other_PrivateUse = TO_MASK(UnicodeCE::U_PRIVATE_USE_CHAR), + Other_Surrogate = TO_MASK(UnicodeCE::U_SURROGATE), + + Punctuation_Dash = TO_MASK(UnicodeCE::U_DASH_PUNCTUATION), + Punctuation_Open = TO_MASK(UnicodeCE::U_START_PUNCTUATION), + Punctuation_Close = TO_MASK(UnicodeCE::U_END_PUNCTUATION), + Punctuation_Connector = TO_MASK(UnicodeCE::U_CONNECTOR_PUNCTUATION), + Punctuation_Other = TO_MASK(UnicodeCE::U_OTHER_PUNCTUATION), + + Symbol_Math = TO_MASK(UnicodeCE::U_MATH_SYMBOL), + Symbol_Currency = TO_MASK(UnicodeCE::U_CURRENCY_SYMBOL), + Symbol_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_SYMBOL), + Symbol_Other = TO_MASK(UnicodeCE::U_OTHER_SYMBOL), + + Punctuation_InitialQuote = TO_MASK(UnicodeCE::U_INITIAL_PUNCTUATION), + Punctuation_FinalQuote = TO_MASK(UnicodeCE::U_FINAL_PUNCTUATION) + }; + + CharCategory category(unsigned int); + + bool isSpace(wchar_t); + bool isLetter(wchar_t); + bool isPrintableChar(wchar_t); + bool isUpper(wchar_t); + bool isLower(wchar_t); + bool isPunct(wchar_t); + bool isDigit(wchar_t); + inline bool isSeparatorSpace(wchar_t c) { return category(c) == Separator_Space; } + inline bool isHighSurrogate(wchar_t c) { return (c & 0xfc00) == 0xd800; } + inline bool isLowSurrogate(wchar_t c) { return (c & 0xfc00) == 0xdc00; } + + wchar_t toLower(wchar_t); + wchar_t toUpper(wchar_t); + wchar_t foldCase(wchar_t); + wchar_t toTitleCase(wchar_t); + int toLower(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError); + int toUpper(wchar_t* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError); + int foldCase(UChar* result, int resultLength, const wchar_t* source, int sourceLength, bool* isError); + + int digitValue(wchar_t); + + wchar_t mirroredChar(UChar32); + unsigned char combiningClass(UChar32); + DecompositionType decompositionType(UChar32); + Direction direction(UChar32); + inline bool isArabicChar(UChar32) + { + return false; // FIXME: implement! + } + + inline bool hasLineBreakingPropertyComplexContext(UChar32) + { + return false; // FIXME: implement! + } + + inline int umemcasecmp(const wchar_t* a, const wchar_t* b, int len) + { + for (int i = 0; i < len; ++i) { + wchar_t c1 = foldCase(a[i]); + wchar_t c2 = foldCase(b[i]); + if (c1 != c2) + return c1 - c2; + } + return 0; + } + + inline UChar32 surrogateToUcs4(wchar_t high, wchar_t low) + { + return (UChar32(high) << 10) + low - 0x35fdc00; + } + + } // namespace Unicode + +} // namespace WTF + +#endif +// vim: ts=2 sw=2 et diff --git a/JavaScriptCore/wtf/win/MainThreadWin.cpp b/JavaScriptCore/wtf/win/MainThreadWin.cpp index b828b7d..c6dcb7d 100644 --- a/JavaScriptCore/wtf/win/MainThreadWin.cpp +++ b/JavaScriptCore/wtf/win/MainThreadWin.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,7 +32,7 @@ #include "Assertions.h" #include "Threading.h" -#if !PLATFORM(WIN_CE) +#if !PLATFORM(WINCE) #include <windows.h> #endif @@ -55,12 +56,21 @@ void initializeMainThreadPlatform() if (threadingWindowHandle) return; +#if PLATFORM(WINCE) + WNDCLASS wcex; + memset(&wcex, 0, sizeof(WNDCLASS)); +#else WNDCLASSEX wcex; memset(&wcex, 0, sizeof(WNDCLASSEX)); wcex.cbSize = sizeof(WNDCLASSEX); +#endif wcex.lpfnWndProc = ThreadingWindowWndProc; wcex.lpszClassName = kThreadingWindowClassName; +#if PLATFORM(WINCE) + RegisterClass(&wcex); +#else RegisterClassEx(&wcex); +#endif threadingWindowHandle = CreateWindow(kThreadingWindowClassName, 0, 0, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, 0, 0); diff --git a/JavaScriptCore/wtf/wince/FastMallocWince.h b/JavaScriptCore/wtf/wince/FastMallocWince.h new file mode 100644 index 0000000..93d9f75 --- /dev/null +++ b/JavaScriptCore/wtf/wince/FastMallocWince.h @@ -0,0 +1,177 @@ +/* + * This file is part of the KDE libraries + * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. All rights reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef FastMallocWince_h +#define FastMallocWince_h + +#include <new.h> + +#ifdef __cplusplus +#include <new> +#include "MemoryManager.h" +extern "C" { +#endif + +void* fastMalloc(size_t n); +void* fastCalloc(size_t n_elements, size_t element_size); +void fastFree(void* p); +void* fastRealloc(void* p, size_t n); +void* fastZeroedMalloc(size_t n); +// These functions return 0 if an allocation fails. +void* tryFastMalloc(size_t n); +void* tryFastZeroedMalloc(size_t n); +void* tryFastCalloc(size_t n_elements, size_t element_size); +void* tryFastRealloc(void* p, size_t n); +char* fastStrDup(const char*); + +#ifndef NDEBUG +void fastMallocForbid(); +void fastMallocAllow(); +#endif + +#if !defined(USE_SYSTEM_MALLOC) || !USE_SYSTEM_MALLOC + +#define malloc(n) fastMalloc(n) +#define calloc(n_elements, element_size) fastCalloc(n_elements, element_size) +#define realloc(p, n) fastRealloc(p, n) +#define free(p) fastFree(p) +#define strdup(p) fastStrDup(p) + +#else + +#define strdup(p) _strdup(p) + +#endif + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +#if !defined(USE_SYSTEM_MALLOC) || !USE_SYSTEM_MALLOC +static inline void* __cdecl operator new(size_t s) { return fastMalloc(s); } +static inline void __cdecl operator delete(void* p) { fastFree(p); } +static inline void* __cdecl operator new[](size_t s) { return fastMalloc(s); } +static inline void __cdecl operator delete[](void* p) { fastFree(p); } +static inline void* operator new(size_t s, const std::nothrow_t&) throw() { return fastMalloc(s); } +static inline void operator delete(void* p, const std::nothrow_t&) throw() { fastFree(p); } +static inline void* operator new[](size_t s, const std::nothrow_t&) throw() { return fastMalloc(s); } +static inline void operator delete[](void* p, const std::nothrow_t&) throw() { fastFree(p); } +#endif + +namespace WTF { + // This defines a type which holds an unsigned integer and is the same + // size as the minimally aligned memory allocation. + typedef unsigned long long AllocAlignmentInteger; + + namespace Internal { + enum AllocType { // Start with an unusual number instead of zero, because zero is common. + AllocTypeMalloc = 0x375d6750, // Encompasses fastMalloc, fastZeroedMalloc, fastCalloc, fastRealloc. + AllocTypeClassNew, // Encompasses class operator new from FastAllocBase. + AllocTypeClassNewArray, // Encompasses class operator new[] from FastAllocBase. + AllocTypeFastNew, // Encompasses fastNew. + AllocTypeFastNewArray, // Encompasses fastNewArray. + AllocTypeNew, // Encompasses global operator new. + AllocTypeNewArray // Encompasses global operator new[]. + }; + } + + +#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) + + // Malloc validation is a scheme whereby a tag is attached to an + // allocation which identifies how it was originally allocated. + // This allows us to verify that the freeing operation matches the + // allocation operation. If memory is allocated with operator new[] + // but freed with free or delete, this system would detect that. + // In the implementation here, the tag is an integer prepended to + // the allocation memory which is assigned one of the AllocType + // enumeration values. An alternative implementation of this + // scheme could store the tag somewhere else or ignore it. + // Users of FastMalloc don't need to know or care how this tagging + // is implemented. + + namespace Internal { + + // Return the AllocType tag associated with the allocated block p. + inline AllocType fastMallocMatchValidationType(const void* p) + { + const AllocAlignmentInteger* type = static_cast<const AllocAlignmentInteger*>(p) - 1; + return static_cast<AllocType>(*type); + } + + // Return the address of the AllocType tag associated with the allocated block p. + inline AllocAlignmentInteger* fastMallocMatchValidationValue(void* p) + { + return reinterpret_cast<AllocAlignmentInteger*>(static_cast<char*>(p) - sizeof(AllocAlignmentInteger)); + } + + // Set the AllocType tag to be associaged with the allocated block p. + inline void setFastMallocMatchValidationType(void* p, AllocType allocType) + { + AllocAlignmentInteger* type = static_cast<AllocAlignmentInteger*>(p) - 1; + *type = static_cast<AllocAlignmentInteger>(allocType); + } + + // Handle a detected alloc/free mismatch. By default this calls CRASH(). + void fastMallocMatchFailed(void* p); + + } // namespace Internal + + // This is a higher level function which is used by FastMalloc-using code. + inline void fastMallocMatchValidateMalloc(void* p, Internal::AllocType allocType) + { + if (!p) + return; + + Internal::setFastMallocMatchValidationType(p, allocType); + } + + // This is a higher level function which is used by FastMalloc-using code. + inline void fastMallocMatchValidateFree(void* p, Internal::AllocType allocType) + { + if (!p) + return; + + if (Internal::fastMallocMatchValidationType(p) != allocType) + Internal::fastMallocMatchFailed(p); + Internal::setFastMallocMatchValidationType(p, Internal::AllocTypeMalloc); // Set it to this so that fastFree thinks it's OK. + } + +#else + + inline void fastMallocMatchValidateMalloc(void*, Internal::AllocType) + { + } + + inline void fastMallocMatchValidateFree(void*, Internal::AllocType) + { + } + +#endif + +} // namespace WTF + +#endif + +#endif // FastMallocWince_h + diff --git a/JavaScriptCore/wtf/wince/MemoryManager.cpp b/JavaScriptCore/wtf/wince/MemoryManager.cpp new file mode 100644 index 0000000..b65b368 --- /dev/null +++ b/JavaScriptCore/wtf/wince/MemoryManager.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2008-2009 Torch Mobile Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "MemoryManager.h" + +#undef malloc +#undef calloc +#undef realloc +#undef free +#undef strdup +#undef _strdup +#undef VirtualAlloc +#undef VirtualFree + +#include <malloc.h> +#include <windows.h> + +namespace WTF { + +MemoryManager* memoryManager() +{ + static MemoryManager mm; + return &mm; +} + +MemoryManager::MemoryManager() +: m_allocationCanFail(false) +{ +} + +MemoryManager::~MemoryManager() +{ +} + +HBITMAP MemoryManager::createCompatibleBitmap(HDC hdc, int width, int height) +{ + return ::CreateCompatibleBitmap(hdc, width, height); +} + +HBITMAP MemoryManager::createDIBSection(const BITMAPINFO* pbmi, void** ppvBits) +{ + return ::CreateDIBSection(0, pbmi, DIB_RGB_COLORS, ppvBits, 0, 0); +} + +void* MemoryManager::m_malloc(size_t size) +{ + return malloc(size); +} + +void* MemoryManager::m_calloc(size_t num, size_t size) +{ + return calloc(num, size); +} + +void* MemoryManager::m_realloc(void* p, size_t size) +{ + return realloc(p, size); +} + +void MemoryManager::m_free(void* p) +{ + return free(p); +} + +bool MemoryManager::resizeMemory(void*, size_t) +{ + return false; +} + +void* MemoryManager::allocate64kBlock() +{ + return VirtualAlloc(0, 65536, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); +} + +void MemoryManager::free64kBlock(void* p) +{ + VirtualFree(p, 65536, MEM_RELEASE); +} + +bool MemoryManager::onIdle(DWORD& timeLimitMs) +{ + return false; +} + +LPVOID MemoryManager::virtualAlloc(LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect) +{ + return ::VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect); +} + +BOOL MemoryManager::virtualFree(LPVOID lpAddress, DWORD dwSize, DWORD dwFreeType) +{ + return ::VirtualFree(lpAddress, dwSize, dwFreeType); +} + + +#if defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC + +void *fastMalloc(size_t n) { return malloc(n); } +void *fastCalloc(size_t n_elements, size_t element_size) { return calloc(n_elements, element_size); } +void fastFree(void* p) { return free(p); } +void *fastRealloc(void* p, size_t n) { return realloc(p, n); } + +#else + +void *fastMalloc(size_t n) { return MemoryManager::m_malloc(n); } +void *fastCalloc(size_t n_elements, size_t element_size) { return MemoryManager::m_calloc(n_elements, element_size); } +void fastFree(void* p) { return MemoryManager::m_free(p); } +void *fastRealloc(void* p, size_t n) { return MemoryManager::m_realloc(p, n); } + +#endif + +#ifndef NDEBUG +void fastMallocForbid() {} +void fastMallocAllow() {} +#endif + +void* fastZeroedMalloc(size_t n) +{ + void* p = fastMalloc(n); + if (p) + memset(p, 0, n); + return p; +} + +void* tryFastMalloc(size_t n) +{ + MemoryAllocationCanFail canFail; + return fastMalloc(n); +} + +void* tryFastZeroedMalloc(size_t n) +{ + MemoryAllocationCanFail canFail; + return fastZeroedMalloc(n); +} + +void* tryFastCalloc(size_t n_elements, size_t element_size) +{ + MemoryAllocationCanFail canFail; + return fastCalloc(n_elements, element_size); +} + +void* tryFastRealloc(void* p, size_t n) +{ + MemoryAllocationCanFail canFail; + return fastRealloc(p, n); +} + +char* fastStrDup(const char* str) +{ + return _strdup(str); +} + +}
\ No newline at end of file diff --git a/JavaScriptCore/wtf/wince/MemoryManager.h b/JavaScriptCore/wtf/wince/MemoryManager.h new file mode 100644 index 0000000..f405612 --- /dev/null +++ b/JavaScriptCore/wtf/wince/MemoryManager.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2008-2009 Torch Mobile Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include <winbase.h> + +typedef struct HBITMAP__* HBITMAP; +typedef struct HDC__* HDC; +typedef void *HANDLE; +typedef struct tagBITMAPINFO BITMAPINFO; + +namespace WTF { + + class MemoryManager { + public: + MemoryManager(); + ~MemoryManager(); + + bool allocationCanFail() const { return m_allocationCanFail; } + void setAllocationCanFail(bool c) { m_allocationCanFail = c; } + + static HBITMAP createCompatibleBitmap(HDC hdc, int width, int height); + static HBITMAP createDIBSection(const BITMAPINFO* pbmi, void** ppvBits); + static void* m_malloc(size_t size); + static void* m_calloc(size_t num, size_t size); + static void* m_realloc(void* p, size_t size); + static void m_free(void*); + static bool resizeMemory(void* p, size_t newSize); + static void* allocate64kBlock(); + static void free64kBlock(void*); + static bool onIdle(DWORD& timeLimitMs); + static LPVOID virtualAlloc(LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect); + static BOOL virtualFree(LPVOID lpAddress, DWORD dwSize, DWORD dwFreeType); + + private: + friend MemoryManager* memoryManager(); + + bool m_allocationCanFail; + }; + + MemoryManager* memoryManager(); + + class MemoryAllocationCanFail { + public: + MemoryAllocationCanFail() : m_old(memoryManager()->allocationCanFail()) { memoryManager()->setAllocationCanFail(true); } + ~MemoryAllocationCanFail() { memoryManager()->setAllocationCanFail(m_old); } + private: + bool m_old; + }; + + class MemoryAllocationCannotFail { + public: + MemoryAllocationCannotFail() : m_old(memoryManager()->allocationCanFail()) { memoryManager()->setAllocationCanFail(false); } + ~MemoryAllocationCannotFail() { memoryManager()->setAllocationCanFail(m_old); } + private: + bool m_old; + }; +} + +using WTF::MemoryManager; +using WTF::memoryManager; +using WTF::MemoryAllocationCanFail; +using WTF::MemoryAllocationCannotFail; diff --git a/JavaScriptCore/wtf/wince/mt19937ar.c b/JavaScriptCore/wtf/wince/mt19937ar.c new file mode 100644 index 0000000..4715958 --- /dev/null +++ b/JavaScriptCore/wtf/wince/mt19937ar.c @@ -0,0 +1,170 @@ +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + 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. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT OWNER 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. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +#include <stdio.h> + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +static unsigned long mt[N]; /* the array for the state vector */ +static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ + +/* initializes mt[N] with a seed */ +void init_genrand(unsigned long s) +{ + mt[0]= s & 0xffffffffUL; + for (mti=1; mti<N; mti++) { + mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +/* slight change for C++, 2004/2/26 */ +void init_by_array(unsigned long init_key[],int key_length) +{ + int i, j, k; + init_genrand(19650218UL); + i=1; j=0; + k = (N>key_length ? N : key_length); + for (; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + + init_key[j] + j; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; j++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=N-1; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) + - i; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + } + + mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ +} + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void) +{ + unsigned long y; + static unsigned long mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + if (mti == N+1) /* if init_genrand() has not been called, */ + init_genrand(5489UL); /* a default initial seed is used */ + + for (kk=0;kk<N-M;kk++) { + y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); + mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL]; + } + for (;kk<N-1;kk++) { + y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); + mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +/* generates a random number on [0,0x7fffffff]-interval */ +long genrand_int31(void) +{ + return (long)(genrand_int32()>>1); +} + +/* generates a random number on [0,1]-real-interval */ +double genrand_real1(void) +{ + return genrand_int32()*(1.0/4294967295.0); + /* divided by 2^32-1 */ +} + +/* generates a random number on [0,1)-real-interval */ +double genrand_real2(void) +{ + return genrand_int32()*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on (0,1)-real-interval */ +double genrand_real3(void) +{ + return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on [0,1) with 53-bit resolution*/ +double genrand_res53(void) +{ + unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; + return(a*67108864.0+b)*(1.0/9007199254740992.0); +} |