2007-09-04 Maciej Stachowiak <mjs@apple.com>
+ Back out accidentally committed change.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * kjs/collector.cpp:
+ (KJS::Collector::registerThread):
+ * wtf/FastMalloc.cpp:
+ (WTF::fastMallocSetIsMultiThreaded):
+ (WTF::TCMalloc_ThreadCache::GetCache):
+ (WTF::TCMalloc_ThreadCache::GetCacheIfPresent):
+ (WTF::TCMalloc_ThreadCache::CreateCacheIfNecessary):
+ (WTF::do_malloc):
+ * wtf/FastMallocInternal.h: Added.
+
+2007-09-04 Maciej Stachowiak <mjs@apple.com>
+
Reviewed by Darin.
- Added Vector::appendRange(), which appends to a vector based on a given start and end iterator
65C647B4093EF8D60022C380 /* RefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C647B3093EF8D60022C380 /* RefPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
65C7A1740A8EAACB00FA37EA /* JSWrapperObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
65D6D87F09B5A32E0002E4D7 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 65D6D87E09B5A32E0002E4D7 /* Platform.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 65D7D19C08F10B5B0015ABD8 /* FastMallocInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 65D7D19B08F10B5B0015ABD8 /* FastMallocInternal.h */; };
65DFC93008EA173A00F7300B /* HashFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92A08EA173A00F7300B /* HashFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
65DFC93108EA173A00F7300B /* HashMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92B08EA173A00F7300B /* HashMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
65DFC93208EA173A00F7300B /* HashSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92C08EA173A00F7300B /* HashSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSWrapperObject.cpp; sourceTree = "<group>"; };
65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSWrapperObject.h; sourceTree = "<group>"; };
65D6D87E09B5A32E0002E4D7 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Platform.h; sourceTree = "<group>"; };
+ 65D7D19B08F10B5B0015ABD8 /* FastMallocInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = FastMallocInternal.h; sourceTree = "<group>"; tabWidth = 8; };
65DFC92A08EA173A00F7300B /* HashFunctions.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HashFunctions.h; sourceTree = "<group>"; tabWidth = 8; };
65DFC92B08EA173A00F7300B /* HashMap.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HashMap.h; sourceTree = "<group>"; tabWidth = 8; };
65DFC92C08EA173A00F7300B /* HashSet.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HashSet.h; sourceTree = "<group>"; tabWidth = 8; };
65E217B708E7EECC0023E5F6 /* Assertions.h */,
65E217B908E7EECC0023E5F6 /* FastMalloc.cpp */,
65E217BA08E7EECC0023E5F6 /* FastMalloc.h */,
+ 65D7D19B08F10B5B0015ABD8 /* FastMallocInternal.h */,
9302043A0B790750000C6115 /* FastMallocPCRE.cpp */,
935AF46909E9D9DB00ACD1D8 /* Forward.h */,
93B6A0DE0AA64DA40076DE27 /* GetPtr.h */,
65DFC93208EA173A00F7300B /* HashSet.h in Headers */,
65DFC93408EA173A00F7300B /* HashTable.h in Headers */,
65DFC93508EA173A00F7300B /* HashTraits.h in Headers */,
+ 65D7D19C08F10B5B0015ABD8 /* FastMallocInternal.h in Headers */,
65EA4C9C092AF9E20093D800 /* JSLock.h in Headers */,
65C647B4093EF8D60022C380 /* RefPtr.h in Headers */,
6580F796094070560082C219 /* PassRefPtr.h in Headers */,
#include <setjmp.h>
#include <stdlib.h>
#include <wtf/FastMalloc.h>
+#include <wtf/FastMallocInternal.h>
#include <wtf/HashCountedSet.h>
#include <wtf/UnusedParam.h>
pthread_once(®isteredThreadKeyOnce, initializeRegisteredThreadKey);
if (!pthread_getspecific(registeredThreadKey)) {
+ if (!onMainThread())
+ WTF::fastMallocSetIsMultiThreaded();
#if PLATFORM(DARWIN)
- if (onMainThread())
- CollectorHeapIntrospector::init(&heap);
+ else
+ CollectorHeapIntrospector::init(&heap);
#endif
Collector::Thread *thread = new Collector::Thread(pthread_self(), getCurrentPlatformThread());
return realloc(p, n);
}
+void fastMallocSetIsMultiThreaded()
+{
+}
+
} // namespace WTF
#if PLATFORM(DARWIN)
#endif
}
+#ifdef WTF_CHANGES
+bool isMultiThreaded;
+TCMalloc_ThreadCache *mainThreadCache;
+
+void fastMallocSetIsMultiThreaded()
+{
+ // We lock when writing mainThreadCache but not when reading it. It's OK if
+ // the main thread reads a stale, non-NULL value for mainThreadCache because
+ // mainThreadCache is the same as the main thread's thread-specific cache.
+ // Other threads can't read a stale, non-NULL value for mainThreadCache because
+ // clients must call this function before allocating on other threads, so they'll
+ // have synchronized before reading mainThreadCache.
+
+ // A similar principle applies to isMultiThreaded. It's OK for the main thread
+ // in GetCache() to read a stale, false value for isMultiThreaded because
+ // doing so will just cause it to make an unnecessary call to InitModule(),
+ // which will synchronize it.
+
+ // To save a branch in some cases, mainThreadCache is only set when
+ // isMultiThreaded is false.
+
+ {
+ SpinLockHolder lock(&pageheap_lock);
+ isMultiThreaded = true;
+ mainThreadCache = 0;
+ }
+
+ TCMalloc_ThreadCache::InitModule();
+}
+#endif
+
ALWAYS_INLINE TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCache() {
void* ptr = NULL;
+#ifndef WTF_CHANGES
if (!tsd_inited) {
InitModule();
} else {
ptr = pthread_getspecific(heap_key);
}
+#else
+ if (mainThreadCache) // fast path for single-threaded mode
+ return mainThreadCache;
+
+ if (isMultiThreaded) // fast path for multi-threaded mode -- heap_key already initialized
+ ptr = pthread_getspecific(heap_key);
+ else // slow path for possible first-time init
+ InitModule();
+#endif
if (ptr == NULL) ptr = CreateCacheIfNecessary();
return reinterpret_cast<TCMalloc_ThreadCache*>(ptr);
}
// because we may be in the thread destruction code and may have
// already cleaned up the cache for this thread.
inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCacheIfPresent() {
+ if (mainThreadCache)
+ return mainThreadCache;
if (!tsd_inited) return NULL;
return reinterpret_cast<TCMalloc_ThreadCache*>
(pthread_getspecific(heap_key));
thread_heaps = heap;
thread_heap_count++;
RecomputeThreadCacheSize();
+ if (!isMultiThreaded)
+ mainThreadCache = heap;
}
}
static ALWAYS_INLINE void* do_malloc(size_t size) {
#ifdef WTF_CHANGES
+ ASSERT(isMultiThreaded || pthread_main_np());
ASSERT(!isForbidden());
#endif
--- /dev/null
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 2005 Apple Computer, 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 WTF_FastMallocInternal_h
+#define WTF_FastMallocInternal_h
+
+namespace WTF {
+ // Clients must call this function before allocating memory on a secondary thread.
+ void fastMallocSetIsMultiThreaded();
+}
+
+#endif // WTF_FastMallocInternal_h