[SCM] WebKit Debian packaging branch, debian/experimental, updated. debian/1.3.8-1-1049-g2e11a8e

ggaren at apple.com ggaren at apple.com
Fri Jan 21 15:12:06 UTC 2011


The following commit has been merged in the debian/experimental branch:
commit bde9609860dafb39601604ceca21c568bfa89897
Author: ggaren at apple.com <ggaren at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Sun Jan 9 03:04:42 2011 +0000

    2011-01-07  Geoffrey Garen  <ggaren at apple.com>
    
            Reviewed by Gavin Barraclough.
    
            Split machine stack marking functions into their own class (MachineStackMarker)
            https://bugs.webkit.org/show_bug.cgi?id=52088
    
            * API/APIShims.h:
            (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock): Moved registerThread()
            call behind an #ifdef because we shouldn't be registering threads at all
            if we don't support usage on multiple threads.
    
            * Android.mk:
            * CMakeLists.txt:
            * GNUmakefile.am:
            * JavaScriptCore.gypi:
            * JavaScriptCore.pro:
            * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
            * JavaScriptCore.xcodeproj/project.pbxproj: Updated projects.
    
            * runtime/Collector.cpp:
            (JSC::Heap::Heap):
            (JSC::Heap::destroy):
            (JSC::Heap::markRoots):
            * runtime/Collector.h:
            (JSC::Heap::machineStackMarker): Moved code to machineStackMarker.
    
            * runtime/JSGlobalData.h:
            (JSC::JSGlobalData::makeUsableFromMultipleThreads): Removed an unnecessary
            level of indirection, to make Heap less of a God class.
    
            * runtime/MachineStackMarker.h: Copied from Source/JavaScriptCore/runtime/Collector.h.
            * runtime/MachineStackMarker.cpp: Copied from Source/JavaScriptCore/runtime/Collector.cpp.
            (JSC::MachineStackMarker::MachineStackMarker):
            (JSC::MachineStackMarker::~MachineStackMarker):
            (JSC::MachineStackMarker::makeUsableFromMultipleThreads):
            (JSC::MachineStackMarker::registerThread):
            (JSC::MachineStackMarker::unregisterThread):
            (JSC::MachineStackMarker::markCurrentThreadConservativelyInternal):
            (JSC::MachineStackMarker::markCurrentThreadConservatively):
            (JSC::MachineStackMarker::markOtherThreadConservatively):
            (JSC::MachineStackMarker::markMachineStackConservatively): Moved code from Heap.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@75342 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/Source/JavaScriptCore/API/APIShims.h b/Source/JavaScriptCore/API/APIShims.h
index 0b49d70..26db2dc 100644
--- a/Source/JavaScriptCore/API/APIShims.h
+++ b/Source/JavaScriptCore/API/APIShims.h
@@ -39,8 +39,11 @@ protected:
         : m_globalData(globalData)
         , m_entryIdentifierTable(wtfThreadData().setCurrentIdentifierTable(globalData->identifierTable))
     {
+        UNUSED_PARAM(registerThread);
+#if ENABLE(JSC_MULTIPLE_THREADS)
         if (registerThread)
-            globalData->heap.registerThread();
+            globalData->heap.machineStackMarker().registerThread();
+#endif
         m_globalData->heap.activityCallback()->synchronize();
         m_globalData->timeoutChecker.start();
     }
diff --git a/Source/JavaScriptCore/Android.mk b/Source/JavaScriptCore/Android.mk
index 9cb26d5..490989a 100644
--- a/Source/JavaScriptCore/Android.mk
+++ b/Source/JavaScriptCore/Android.mk
@@ -125,6 +125,7 @@ LOCAL_SRC_FILES := \
 	runtime/JSWrapperObject.cpp \
 	runtime/LiteralParser.cpp \
 	runtime/Lookup.cpp \
+	runtime/MachineStackMarker.cpp \
 	runtime/MarkStack.cpp \
 	runtime/MarkStackPosix.cpp \
 	runtime/MathObject.cpp \
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index f8b4d1e..fd26d77 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -135,6 +135,7 @@ SET(JavaScriptCore_SOURCES
     runtime/JSZombie.cpp
     runtime/LiteralParser.cpp
     runtime/Lookup.cpp
+    runtime/MachineStackMarker.cpp
     runtime/MarkStack.cpp
     runtime/MathObject.cpp
     runtime/NativeErrorConstructor.cpp
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 54ac1e9..abb205c 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,46 @@
+2011-01-07  Geoffrey Garen  <ggaren at apple.com>
+
+        Reviewed by Gavin Barraclough.
+
+        Split machine stack marking functions into their own class (MachineStackMarker)
+        https://bugs.webkit.org/show_bug.cgi?id=52088
+
+        * API/APIShims.h:
+        (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock): Moved registerThread()
+        call behind an #ifdef because we shouldn't be registering threads at all
+        if we don't support usage on multiple threads.
+
+        * Android.mk:
+        * CMakeLists.txt:
+        * GNUmakefile.am:
+        * JavaScriptCore.gypi:
+        * JavaScriptCore.pro:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj: Updated projects.
+
+        * runtime/Collector.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::destroy):
+        (JSC::Heap::markRoots):
+        * runtime/Collector.h:
+        (JSC::Heap::machineStackMarker): Moved code to machineStackMarker.
+
+        * runtime/JSGlobalData.h:
+        (JSC::JSGlobalData::makeUsableFromMultipleThreads): Removed an unnecessary
+        level of indirection, to make Heap less of a God class.
+
+        * runtime/MachineStackMarker.h: Copied from Source/JavaScriptCore/runtime/Collector.h.
+        * runtime/MachineStackMarker.cpp: Copied from Source/JavaScriptCore/runtime/Collector.cpp.
+        (JSC::MachineStackMarker::MachineStackMarker):
+        (JSC::MachineStackMarker::~MachineStackMarker):
+        (JSC::MachineStackMarker::makeUsableFromMultipleThreads):
+        (JSC::MachineStackMarker::registerThread):
+        (JSC::MachineStackMarker::unregisterThread):
+        (JSC::MachineStackMarker::markCurrentThreadConservativelyInternal):
+        (JSC::MachineStackMarker::markCurrentThreadConservatively):
+        (JSC::MachineStackMarker::markOtherThreadConservatively):
+        (JSC::MachineStackMarker::markMachineStackConservatively): Moved code from Heap.
+
 2011-01-07  Gavin Barraclough  <barraclough at apple.com>
 
         Reviewed by Geoff Garen.
diff --git a/Source/JavaScriptCore/GNUmakefile.am b/Source/JavaScriptCore/GNUmakefile.am
index 93f10ee..30e3f09 100644
--- a/Source/JavaScriptCore/GNUmakefile.am
+++ b/Source/JavaScriptCore/GNUmakefile.am
@@ -336,6 +336,8 @@ javascriptcore_sources += \
 	Source/JavaScriptCore/runtime/LiteralParser.h \
 	Source/JavaScriptCore/runtime/Lookup.cpp \
 	Source/JavaScriptCore/runtime/Lookup.h \
+	Source/JavaScriptCore/runtime/MachineStackMarker.cpp \
+	Source/JavaScriptCore/runtime/MachineStackMarker.h \
 	Source/JavaScriptCore/runtime/MarkStack.cpp \
 	Source/JavaScriptCore/runtime/MarkStack.h \
 	Source/JavaScriptCore/runtime/MathObject.cpp \
diff --git a/Source/JavaScriptCore/JavaScriptCore.gypi b/Source/JavaScriptCore/JavaScriptCore.gypi
index e60969e..4f4da73 100644
--- a/Source/JavaScriptCore/JavaScriptCore.gypi
+++ b/Source/JavaScriptCore/JavaScriptCore.gypi
@@ -276,6 +276,8 @@
             'runtime/LiteralParser.h',
             'runtime/Lookup.cpp',
             'runtime/Lookup.h',
+            'runtime/MachineStackMarker.cpp',
+            'runtime/MachineStackMarker.h',
             'runtime/MarkStack.cpp',
             'runtime/MarkStack.h',
             'runtime/MarkStackWin.cpp',
diff --git a/Source/JavaScriptCore/JavaScriptCore.pro b/Source/JavaScriptCore/JavaScriptCore.pro
index 86b1b9a..fa4ebfb 100644
--- a/Source/JavaScriptCore/JavaScriptCore.pro
+++ b/Source/JavaScriptCore/JavaScriptCore.pro
@@ -174,6 +174,7 @@ SOURCES += \
     runtime/JSWrapperObject.cpp \
     runtime/LiteralParser.cpp \
     runtime/Lookup.cpp \
+    runtime/MachineStackMarker.cpp \
     runtime/MarkStackPosix.cpp \
     runtime/MarkStackSymbian.cpp \
     runtime/MarkStackWin.cpp \
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
index 7284362..328363e 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
@@ -986,6 +986,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\runtime\MachineStackMarker.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\runtime\MachineStackMarker.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\runtime\MarkStack.cpp"
 				>
 			</File>
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 414f8b1..e08d0b7 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -163,6 +163,8 @@
 		14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14ABDF5E0A437FEF00ECCA01 /* JSCallbackObject.cpp */; };
 		14B3EF0512BC24DD00D29EFF /* PageBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 14B3EF0312BC24DD00D29EFF /* PageBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		14B3EF0612BC24DD00D29EFF /* PageBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14B3EF0412BC24DD00D29EFF /* PageBlock.cpp */; };
+		14B723B212D7DA46003BD5ED /* MachineStackMarker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14B7233F12D7D0DA003BD5ED /* MachineStackMarker.cpp */; };
+		14B723B812D7DA6F003BD5ED /* MachineStackMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 14B7234012D7D0DA003BD5ED /* MachineStackMarker.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		14B8EC720A5652090062BE54 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */; };
 		14BD59C50A3E8F9F00BAF59C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
 		14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */; };
@@ -725,6 +727,8 @@
 		14ABDF5E0A437FEF00ECCA01 /* JSCallbackObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCallbackObject.cpp; sourceTree = "<group>"; };
 		14B3EF0312BC24DD00D29EFF /* PageBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageBlock.h; sourceTree = "<group>"; };
 		14B3EF0412BC24DD00D29EFF /* PageBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageBlock.cpp; sourceTree = "<group>"; };
+		14B7233F12D7D0DA003BD5ED /* MachineStackMarker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MachineStackMarker.cpp; sourceTree = "<group>"; };
+		14B7234012D7D0DA003BD5ED /* MachineStackMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachineStackMarker.h; sourceTree = "<group>"; };
 		14B8ECA60A5653980062BE54 /* JavaScriptCore.exp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.exports; path = JavaScriptCore.exp; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
 		14BD59BF0A3E8F9000BAF59C /* testapi */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testapi; sourceTree = BUILT_PRODUCTS_DIR; };
 		14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSContextRef.cpp; sourceTree = "<group>"; };
@@ -1667,8 +1671,6 @@
 		7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
 			isa = PBXGroup;
 			children = (
-				DDF7ABD211F60ED200108E36 /* GCActivityCallback.h */,
-				DDF7ABD311F60ED200108E36 /* GCActivityCallbackCF.cpp */,
 				BCF605110E203EF800B9A64D /* ArgList.cpp */,
 				BCF605120E203EF800B9A64D /* ArgList.h */,
 				BC257DE50E1F51C50016B6C9 /* Arguments.cpp */,
@@ -1722,6 +1724,8 @@
 				BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */,
 				F692A85C0255597D01FF60F7 /* FunctionPrototype.cpp */,
 				F692A85D0255597D01FF60F7 /* FunctionPrototype.h */,
+				DDF7ABD211F60ED200108E36 /* GCActivityCallback.h */,
+				DDF7ABD311F60ED200108E36 /* GCActivityCallbackCF.cpp */,
 				DDE82AD11209D955005C1756 /* GCHandle.cpp */,
 				DDE82AD21209D955005C1756 /* GCHandle.h */,
 				BC02E9B80E184545000F9297 /* GetterSetter.cpp */,
@@ -1785,6 +1789,8 @@
 				A7E2EA690FB460CF00601F06 /* LiteralParser.h */,
 				F692A8680255597D01FF60F7 /* Lookup.cpp */,
 				F692A8690255597D01FF60F7 /* Lookup.h */,
+				14B7233F12D7D0DA003BD5ED /* MachineStackMarker.cpp */,
+				14B7234012D7D0DA003BD5ED /* MachineStackMarker.h */,
 				A74B3498102A5F8E0032AB98 /* MarkStack.cpp */,
 				A779558F101A74D500114E55 /* MarkStack.h */,
 				A7C530E3102A3813005BC741 /* MarkStackPosix.cpp */,
@@ -1840,6 +1846,8 @@
 				7E2C6C980D31C6B6002D44E2 /* ScopeChainMark.h */,
 				93303FE80E6A72B500786E6A /* SmallStrings.cpp */,
 				93303FEA0E6A72C000786E6A /* SmallStrings.h */,
+				A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */,
+				A730B6101250068F009D25B1 /* StrictEvalActivation.h */,
 				BC18C3C00E16EE3300B34460 /* StringConstructor.cpp */,
 				BC18C3C10E16EE3300B34460 /* StringConstructor.h */,
 				BC18C3C20E16EE3300B34460 /* StringObject.cpp */,
@@ -1865,8 +1873,6 @@
 				14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */,
 				14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */,
 				1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */,
-				A730B6101250068F009D25B1 /* StrictEvalActivation.h */,
-				A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */,
 			);
 			path = runtime;
 			sourceTree = "<group>";
@@ -2214,6 +2220,7 @@
 				A7E2EA6B0FB460CF00601F06 /* LiteralParser.h in Headers */,
 				BC18C4360E16F5CD00B34460 /* Locker.h in Headers */,
 				BC18C4370E16F5CD00B34460 /* Lookup.h in Headers */,
+				14B723B812D7DA6F003BD5ED /* MachineStackMarker.h in Headers */,
 				86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */,
 				86D3B2C610156BDE002865E7 /* MacroAssemblerARM.h in Headers */,
 				86ADD1460FDDEA980006EEC2 /* MacroAssemblerARMv7.h in Headers */,
@@ -2765,6 +2772,7 @@
 				148F21B0107EC5410042EC2C /* Lexer.cpp in Sources */,
 				A7E2EA6C0FB460CF00601F06 /* LiteralParser.cpp in Sources */,
 				14469DDE107EC7E700650446 /* Lookup.cpp in Sources */,
+				14B723B212D7DA46003BD5ED /* MachineStackMarker.cpp in Sources */,
 				86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */,
 				06D358B30DAADAA4003B174E /* MainThread.cpp in Sources */,
 				06D358B40DAADAAA003B174E /* MainThreadMac.mm in Sources */,
@@ -2777,6 +2785,7 @@
 				14469DE1107EC7E700650446 /* NativeErrorPrototype.cpp in Sources */,
 				148F21B7107EC5470042EC2C /* Nodes.cpp in Sources */,
 				655EB29B10CE2581001A990E /* NodesCodegen.cpp in Sources */,
+				93854A9A12C93D3B00DAAF77 /* NullPtr.cpp in Sources */,
 				14469DE2107EC7E700650446 /* NumberConstructor.cpp in Sources */,
 				14469DE3107EC7E700650446 /* NumberObject.cpp in Sources */,
 				14469DE4107EC7E700650446 /* NumberPrototype.cpp in Sources */,
@@ -2810,10 +2819,10 @@
 				86EAC4970F93E8D1008EC948 /* RegexInterpreter.cpp in Sources */,
 				86EAC4990F93E8D1008EC948 /* RegexJIT.cpp in Sources */,
 				14280841107EC0930013E7B2 /* RegExp.cpp in Sources */,
+				868D81A212C428CE0093DC84 /* RegexPattern.cpp in Sources */,
 				A1712B3B11C7B212007A5315 /* RegExpCache.cpp in Sources */,
 				14280842107EC0930013E7B2 /* RegExpConstructor.cpp in Sources */,
 				14280843107EC0930013E7B2 /* RegExpObject.cpp in Sources */,
-				868D81A212C428CE0093DC84 /* RegexPattern.cpp in Sources */,
 				14280844107EC0930013E7B2 /* RegExpPrototype.cpp in Sources */,
 				1428083A107EC0750013E7B2 /* RegisterFile.cpp in Sources */,
 				86B99AB8117E391E00DF5A90 /* RopeImpl.cpp in Sources */,
@@ -2821,9 +2830,9 @@
 				14469DEA107EC7E700650446 /* ScopeChain.cpp in Sources */,
 				0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */,
 				9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */,
+				86D87DAE12BCA7D1008E73A1 /* StackBounds.cpp in Sources */,
 				A730B6131250068F009D25B1 /* StrictEvalActivation.cpp in Sources */,
 				86438FC41265503E00E0DFCA /* StringBuilder.cpp in Sources */,
-				86D87DAE12BCA7D1008E73A1 /* StackBounds.cpp in Sources */,
 				14469DEB107EC7E700650446 /* StringConstructor.cpp in Sources */,
 				868BFA0E117CEFD100B908B1 /* StringImpl.cpp in Sources */,
 				14469DEC107EC7E700650446 /* StringObject.cpp in Sources */,
@@ -2844,7 +2853,6 @@
 				E1EF79AA0CE97BA60088D500 /* UTF8.cpp in Sources */,
 				868BFA17117CF19900B908B1 /* WTFString.cpp in Sources */,
 				86D08D5311793613006E5ED0 /* WTFThreadData.cpp in Sources */,
-				93854A9A12C93D3B00DAAF77 /* NullPtr.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/Source/JavaScriptCore/runtime/Collector.cpp b/Source/JavaScriptCore/runtime/Collector.cpp
index 38845ce..e72938a 100644
--- a/Source/JavaScriptCore/runtime/Collector.cpp
+++ b/Source/JavaScriptCore/runtime/Collector.cpp
@@ -47,50 +47,6 @@
 #include <wtf/UnusedParam.h>
 #include <wtf/VMTags.h>
 
-#if OS(DARWIN)
-
-#include <mach/mach_init.h>
-#include <mach/mach_port.h>
-#include <mach/task.h>
-#include <mach/thread_act.h>
-#include <mach/vm_map.h>
-
-#elif OS(WINDOWS)
-
-#include <windows.h>
-#include <malloc.h>
-
-#elif OS(HAIKU)
-
-#include <OS.h>
-
-#elif OS(UNIX)
-
-#include <stdlib.h>
-#if !OS(HAIKU)
-#include <sys/mman.h>
-#endif
-#include <unistd.h>
-
-#if OS(SOLARIS)
-#include <thread.h>
-#else
-#include <pthread.h>
-#endif
-
-#if HAVE(PTHREAD_NP_H)
-#include <pthread_np.h>
-#endif
-
-#if OS(QNX)
-#include <fcntl.h>
-#include <sys/procfs.h>
-#include <stdio.h>
-#include <errno.h>
-#endif
-
-#endif
-
 #define COLLECT_ON_EVERY_ALLOCATION 0
 
 using std::max;
@@ -106,38 +62,10 @@ const size_t ALLOCATIONS_PER_COLLECTION = 3600;
 // a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
 #define MIN_ARRAY_SIZE (static_cast<size_t>(14))
 
-#if ENABLE(JSC_MULTIPLE_THREADS)
-
-#if OS(DARWIN)
-typedef mach_port_t PlatformThread;
-#elif OS(WINDOWS)
-typedef HANDLE PlatformThread;
-#endif
-
-class Heap::Thread {
-public:
-    Thread(pthread_t pthread, const PlatformThread& platThread, void* base) 
-        : posixThread(pthread)
-        , platformThread(platThread)
-        , stackBase(base)
-    {
-    }
-
-    Thread* next;
-    pthread_t posixThread;
-    PlatformThread platformThread;
-    void* stackBase;
-};
-
-#endif
-
 Heap::Heap(JSGlobalData* globalData)
     : m_markListSet(0)
-#if ENABLE(JSC_MULTIPLE_THREADS)
-    , m_registeredThreads(0)
-    , m_currentThreadRegistrar(0)
-#endif
     , m_globalData(globalData)
+    , m_machineStackMarker(this)
 {
     ASSERT(globalData);
     memset(&m_heap, 0, sizeof(CollectorHeap));
@@ -171,19 +99,6 @@ void Heap::destroy()
 
     freeBlocks();
 
-#if ENABLE(JSC_MULTIPLE_THREADS)
-    if (m_currentThreadRegistrar) {
-        int error = pthread_key_delete(m_currentThreadRegistrar);
-        ASSERT_UNUSED(error, !error);
-    }
-
-    MutexLocker registeredThreadsLock(m_registeredThreadsMutex);
-    for (Heap::Thread* t = m_registeredThreads; t;) {
-        Heap::Thread* next = t->next;
-        delete t;
-        t = next;
-    }
-#endif
     m_globalData = 0;
 }
 
@@ -385,82 +300,6 @@ void Heap::shrinkBlocks(size_t neededBlocks)
         m_heap.collectorBlock(i)->marked.set(HeapConstants::cellsPerBlock - 1);
 }
 
-#if ENABLE(JSC_MULTIPLE_THREADS)
-
-static inline PlatformThread getCurrentPlatformThread()
-{
-#if OS(DARWIN)
-    return pthread_mach_thread_np(pthread_self());
-#elif OS(WINDOWS)
-    return pthread_getw32threadhandle_np(pthread_self());
-#endif
-}
-
-void Heap::makeUsableFromMultipleThreads()
-{
-    if (m_currentThreadRegistrar)
-        return;
-
-    int error = pthread_key_create(&m_currentThreadRegistrar, unregisterThread);
-    if (error)
-        CRASH();
-}
-
-void Heap::registerThread()
-{
-    ASSERT(!m_globalData->exclusiveThread || m_globalData->exclusiveThread == currentThread());
-
-    if (!m_currentThreadRegistrar || pthread_getspecific(m_currentThreadRegistrar))
-        return;
-
-    pthread_setspecific(m_currentThreadRegistrar, this);
-    Heap::Thread* thread = new Heap::Thread(pthread_self(), getCurrentPlatformThread(), m_globalData->stack().origin());
-
-    MutexLocker lock(m_registeredThreadsMutex);
-
-    thread->next = m_registeredThreads;
-    m_registeredThreads = thread;
-}
-
-void Heap::unregisterThread(void* p)
-{
-    if (p)
-        static_cast<Heap*>(p)->unregisterThread();
-}
-
-void Heap::unregisterThread()
-{
-    pthread_t currentPosixThread = pthread_self();
-
-    MutexLocker lock(m_registeredThreadsMutex);
-
-    if (pthread_equal(currentPosixThread, m_registeredThreads->posixThread)) {
-        Thread* t = m_registeredThreads;
-        m_registeredThreads = m_registeredThreads->next;
-        delete t;
-    } else {
-        Heap::Thread* last = m_registeredThreads;
-        Heap::Thread* t;
-        for (t = m_registeredThreads->next; t; t = t->next) {
-            if (pthread_equal(t->posixThread, currentPosixThread)) {
-                last->next = t->next;
-                break;
-            }
-            last = t;
-        }
-        ASSERT(t); // If t is NULL, we never found ourselves in the list.
-        delete t;
-    }
-}
-
-#else // ENABLE(JSC_MULTIPLE_THREADS)
-
-void Heap::registerThread()
-{
-}
-
-#endif
-
 inline bool isPointerAligned(void* p)
 {
     return (((intptr_t)(p) & (sizeof(char*) - 1)) == 0);
@@ -521,212 +360,6 @@ void Heap::markConservatively(MarkStack& markStack, void* start, void* end)
     }
 }
 
-void NEVER_INLINE Heap::markCurrentThreadConservativelyInternal(MarkStack& markStack)
-{
-    markConservatively(markStack, m_globalData->stack().current(), m_globalData->stack().origin());
-    markStack.drain();
-}
-
-#if COMPILER(GCC)
-#define REGISTER_BUFFER_ALIGNMENT __attribute__ ((aligned (sizeof(void*))))
-#else
-#define REGISTER_BUFFER_ALIGNMENT
-#endif
-
-void Heap::markCurrentThreadConservatively(MarkStack& markStack)
-{
-    // setjmp forces volatile registers onto the stack
-    jmp_buf registers REGISTER_BUFFER_ALIGNMENT;
-#if COMPILER(MSVC)
-#pragma warning(push)
-#pragma warning(disable: 4611)
-#endif
-    setjmp(registers);
-#if COMPILER(MSVC)
-#pragma warning(pop)
-#endif
-
-    markCurrentThreadConservativelyInternal(markStack);
-}
-
-#if ENABLE(JSC_MULTIPLE_THREADS)
-
-static inline void suspendThread(const PlatformThread& platformThread)
-{
-#if OS(DARWIN)
-    thread_suspend(platformThread);
-#elif OS(WINDOWS)
-    SuspendThread(platformThread);
-#else
-#error Need a way to suspend threads on this platform
-#endif
-}
-
-static inline void resumeThread(const PlatformThread& platformThread)
-{
-#if OS(DARWIN)
-    thread_resume(platformThread);
-#elif OS(WINDOWS)
-    ResumeThread(platformThread);
-#else
-#error Need a way to resume threads on this platform
-#endif
-}
-
-typedef unsigned long usword_t; // word size, assumed to be either 32 or 64 bit
-
-#if OS(DARWIN)
-
-#if CPU(X86)
-typedef i386_thread_state_t PlatformThreadRegisters;
-#elif CPU(X86_64)
-typedef x86_thread_state64_t PlatformThreadRegisters;
-#elif CPU(PPC)
-typedef ppc_thread_state_t PlatformThreadRegisters;
-#elif CPU(PPC64)
-typedef ppc_thread_state64_t PlatformThreadRegisters;
-#elif CPU(ARM)
-typedef arm_thread_state_t PlatformThreadRegisters;
-#else
-#error Unknown Architecture
-#endif
-
-#elif OS(WINDOWS) && CPU(X86)
-typedef CONTEXT PlatformThreadRegisters;
-#else
-#error Need a thread register struct for this platform
-#endif
-
-static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs)
-{
-#if OS(DARWIN)
-
-#if CPU(X86)
-    unsigned user_count = sizeof(regs)/sizeof(int);
-    thread_state_flavor_t flavor = i386_THREAD_STATE;
-#elif CPU(X86_64)
-    unsigned user_count = x86_THREAD_STATE64_COUNT;
-    thread_state_flavor_t flavor = x86_THREAD_STATE64;
-#elif CPU(PPC) 
-    unsigned user_count = PPC_THREAD_STATE_COUNT;
-    thread_state_flavor_t flavor = PPC_THREAD_STATE;
-#elif CPU(PPC64)
-    unsigned user_count = PPC_THREAD_STATE64_COUNT;
-    thread_state_flavor_t flavor = PPC_THREAD_STATE64;
-#elif CPU(ARM)
-    unsigned user_count = ARM_THREAD_STATE_COUNT;
-    thread_state_flavor_t flavor = ARM_THREAD_STATE;
-#else
-#error Unknown Architecture
-#endif
-
-    kern_return_t result = thread_get_state(platformThread, flavor, (thread_state_t)&regs, &user_count);
-    if (result != KERN_SUCCESS) {
-        WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 
-                            "JavaScript garbage collection failed because thread_get_state returned an error (%d). This is probably the result of running inside Rosetta, which is not supported.", result);
-        CRASH();
-    }
-    return user_count * sizeof(usword_t);
-// end OS(DARWIN)
-
-#elif OS(WINDOWS) && CPU(X86)
-    regs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL | CONTEXT_SEGMENTS;
-    GetThreadContext(platformThread, &regs);
-    return sizeof(CONTEXT);
-#else
-#error Need a way to get thread registers on this platform
-#endif
-}
-
-static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs)
-{
-#if OS(DARWIN)
-
-#if __DARWIN_UNIX03
-
-#if CPU(X86)
-    return reinterpret_cast<void*>(regs.__esp);
-#elif CPU(X86_64)
-    return reinterpret_cast<void*>(regs.__rsp);
-#elif CPU(PPC) || CPU(PPC64)
-    return reinterpret_cast<void*>(regs.__r1);
-#elif CPU(ARM)
-    return reinterpret_cast<void*>(regs.__sp);
-#else
-#error Unknown Architecture
-#endif
-
-#else // !__DARWIN_UNIX03
-
-#if CPU(X86)
-    return reinterpret_cast<void*>(regs.esp);
-#elif CPU(X86_64)
-    return reinterpret_cast<void*>(regs.rsp);
-#elif CPU(PPC) || CPU(PPC64)
-    return reinterpret_cast<void*>(regs.r1);
-#else
-#error Unknown Architecture
-#endif
-
-#endif // __DARWIN_UNIX03
-
-// end OS(DARWIN)
-#elif CPU(X86) && OS(WINDOWS)
-    return reinterpret_cast<void*>((uintptr_t) regs.Esp);
-#else
-#error Need a way to get the stack pointer for another thread on this platform
-#endif
-}
-
-void Heap::markOtherThreadConservatively(MarkStack& markStack, Thread* thread)
-{
-    suspendThread(thread->platformThread);
-
-    PlatformThreadRegisters regs;
-    size_t regSize = getPlatformThreadRegisters(thread->platformThread, regs);
-
-    // mark the thread's registers
-    markConservatively(markStack, static_cast<void*>(&regs), static_cast<void*>(reinterpret_cast<char*>(&regs) + regSize));
-    markStack.drain();
-
-    void* stackPointer = otherThreadStackPointer(regs);
-    markConservatively(markStack, stackPointer, thread->stackBase);
-    markStack.drain();
-
-    resumeThread(thread->platformThread);
-}
-
-#endif
-
-void Heap::markStackObjectsConservatively(MarkStack& markStack)
-{
-    markCurrentThreadConservatively(markStack);
-
-#if ENABLE(JSC_MULTIPLE_THREADS)
-
-    if (m_currentThreadRegistrar) {
-
-        MutexLocker lock(m_registeredThreadsMutex);
-
-#ifndef NDEBUG
-        // Forbid malloc during the mark phase. Marking a thread suspends it, so 
-        // a malloc inside markChildren() would risk a deadlock with a thread that had been 
-        // suspended while holding the malloc lock.
-        fastMallocForbid();
-#endif
-        // It is safe to access the registeredThreads list, because we earlier asserted that locks are being held,
-        // and since this is a shared heap, they are real locks.
-        for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
-            if (!pthread_equal(thread->posixThread, pthread_self()))
-                markOtherThreadConservatively(markStack, thread);
-        }
-#ifndef NDEBUG
-        fastMallocAllow();
-#endif
-    }
-#endif
-}
-
 void Heap::updateWeakGCHandles()
 {
     for (unsigned i = 0; i < m_weakGCHandlePools.size(); ++i)
@@ -897,7 +530,7 @@ void Heap::markRoots()
     clearMarkBits();
 
     // Mark stack roots.
-    markStackObjectsConservatively(markStack);
+    m_machineStackMarker.markMachineStackConservatively(markStack);
     m_globalData->interpreter->registerFile().markCallFrames(markStack, this);
 
     // Mark explicitly registered roots.
diff --git a/Source/JavaScriptCore/runtime/Collector.h b/Source/JavaScriptCore/runtime/Collector.h
index a4e2fe1..349fc4c 100644
--- a/Source/JavaScriptCore/runtime/Collector.h
+++ b/Source/JavaScriptCore/runtime/Collector.h
@@ -24,6 +24,7 @@
 
 #include "GCHandle.h"
 #include "JSValue.h"
+#include "MachineStackMarker.h"
 #include <stddef.h>
 #include <string.h>
 #include <wtf/Bitmap.h>
@@ -36,11 +37,6 @@
 #include <wtf/PageAllocationAligned.h>
 #include <wtf/PassOwnPtr.h>
 #include <wtf/StdLibExtras.h>
-#include <wtf/Threading.h>
-
-#if ENABLE(JSC_MULTIPLE_THREADS)
-#include <pthread.h>
-#endif
 
 #define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) <= CELL_SIZE, class_fits_in_cell)
 
@@ -87,8 +83,6 @@ namespace JSC {
 
     class Heap : public Noncopyable {
     public:
-        class Thread;
-
         void destroy();
 
         void* allocateNumber(size_t);
@@ -127,8 +121,6 @@ namespace JSC {
         HashCountedSet<const char*>* protectedObjectTypeCounts();
         HashCountedSet<const char*>* objectTypeCounts();
 
-        void registerThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
-
         static bool isCellMarked(const JSCell*);
         static bool checkMarkCell(const JSCell*);
         static void markCell(JSCell*);
@@ -148,6 +140,8 @@ namespace JSC {
         LiveObjectIterator primaryHeapBegin();
         LiveObjectIterator primaryHeapEnd();
 
+        MachineStackMarker& machineStackMarker() { return m_machineStackMarker; }
+
     private:
         void reset();
         void sweep();
@@ -175,10 +169,6 @@ namespace JSC {
         void markRoots();
         void markProtectedObjects(MarkStack&);
         void markTempSortVectors(MarkStack&);
-        void markCurrentThreadConservatively(MarkStack&);
-        void markCurrentThreadConservativelyInternal(MarkStack&);
-        void markOtherThreadConservatively(MarkStack&, Thread*);
-        void markStackObjectsConservatively(MarkStack&);
 
         void updateWeakGCHandles();
         WeakGCHandlePool* weakGCHandlePool(size_t index);
@@ -195,18 +185,9 @@ namespace JSC {
 
         OwnPtr<GCActivityCallback> m_activityCallback;
 
-#if ENABLE(JSC_MULTIPLE_THREADS)
-        void makeUsableFromMultipleThreads();
-
-        static void unregisterThread(void*);
-        void unregisterThread();
-
-        Mutex m_registeredThreadsMutex;
-        Thread* m_registeredThreads;
-        pthread_key_t m_currentThreadRegistrar;
-#endif
-
         JSGlobalData* m_globalData;
+        
+        MachineStackMarker m_machineStackMarker;
     };
 
     // tunable parameters
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h
index 699f975..b4a6440 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.h
@@ -128,7 +128,7 @@ namespace JSC {
 
 #if ENABLE(JSC_MULTIPLE_THREADS)
         // Will start tracking threads that use the heap, which is resource-heavy.
-        void makeUsableFromMultipleThreads() { heap.makeUsableFromMultipleThreads(); }
+        void makeUsableFromMultipleThreads() { heap.machineStackMarker().makeUsableFromMultipleThreads(); }
 #endif
 
         GlobalDataType globalDataType;
diff --git a/Source/JavaScriptCore/runtime/MachineStackMarker.cpp b/Source/JavaScriptCore/runtime/MachineStackMarker.cpp
new file mode 100644
index 0000000..22c2a87
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/MachineStackMarker.cpp
@@ -0,0 +1,403 @@
+/*
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Eric Seidel <eric at webkit.org>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include "config.h"
+#include "MachineStackMarker.h"
+
+#include "Collector.h"
+#include "JSArray.h"
+#include "JSGlobalData.h"
+#include <setjmp.h>
+#include <stdlib.h>
+
+#if OS(DARWIN)
+
+#include <mach/mach_init.h>
+#include <mach/mach_port.h>
+#include <mach/task.h>
+#include <mach/thread_act.h>
+#include <mach/vm_map.h>
+
+#elif OS(WINDOWS)
+
+#include <windows.h>
+#include <malloc.h>
+
+#elif OS(HAIKU)
+
+#include <OS.h>
+
+#elif OS(UNIX)
+
+#include <stdlib.h>
+#if !OS(HAIKU)
+#include <sys/mman.h>
+#endif
+#include <unistd.h>
+
+#if OS(SOLARIS)
+#include <thread.h>
+#else
+#include <pthread.h>
+#endif
+
+#if HAVE(PTHREAD_NP_H)
+#include <pthread_np.h>
+#endif
+
+#if OS(QNX)
+#include <fcntl.h>
+#include <sys/procfs.h>
+#include <stdio.h>
+#include <errno.h>
+#endif
+
+#endif
+
+namespace JSC {
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+
+#if OS(DARWIN)
+typedef mach_port_t PlatformThread;
+#elif OS(WINDOWS)
+typedef HANDLE PlatformThread;
+#endif
+
+class MachineStackMarker::Thread {
+public:
+    Thread(pthread_t pthread, const PlatformThread& platThread, void* base) 
+        : posixThread(pthread)
+        , platformThread(platThread)
+        , stackBase(base)
+    {
+    }
+
+    Thread* next;
+    pthread_t posixThread;
+    PlatformThread platformThread;
+    void* stackBase;
+};
+
+#endif
+
+MachineStackMarker::MachineStackMarker(Heap* heap)
+    : m_heap(heap)
+#if ENABLE(JSC_MULTIPLE_THREADS)
+    , m_registeredThreads(0)
+    , m_currentThreadRegistrar(0)
+#endif
+{
+}
+
+MachineStackMarker::~MachineStackMarker()
+{
+#if ENABLE(JSC_MULTIPLE_THREADS)
+    if (m_currentThreadRegistrar) {
+        int error = pthread_key_delete(m_currentThreadRegistrar);
+        ASSERT_UNUSED(error, !error);
+    }
+
+    MutexLocker registeredThreadsLock(m_registeredThreadsMutex);
+    for (Thread* t = m_registeredThreads; t;) {
+        Thread* next = t->next;
+        delete t;
+        t = next;
+    }
+#endif
+}
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+
+static inline PlatformThread getCurrentPlatformThread()
+{
+#if OS(DARWIN)
+    return pthread_mach_thread_np(pthread_self());
+#elif OS(WINDOWS)
+    return pthread_getw32threadhandle_np(pthread_self());
+#endif
+}
+
+void MachineStackMarker::makeUsableFromMultipleThreads()
+{
+    if (m_currentThreadRegistrar)
+        return;
+
+    int error = pthread_key_create(&m_currentThreadRegistrar, unregisterThread);
+    if (error)
+        CRASH();
+}
+
+void MachineStackMarker::registerThread()
+{
+    ASSERT(!m_heap->globalData()->exclusiveThread || m_heap->globalData()->exclusiveThread == currentThread());
+
+    if (!m_currentThreadRegistrar || pthread_getspecific(m_currentThreadRegistrar))
+        return;
+
+    pthread_setspecific(m_currentThreadRegistrar, this);
+    Thread* thread = new Thread(pthread_self(), getCurrentPlatformThread(), m_heap->globalData()->stack().origin());
+
+    MutexLocker lock(m_registeredThreadsMutex);
+
+    thread->next = m_registeredThreads;
+    m_registeredThreads = thread;
+}
+
+void MachineStackMarker::unregisterThread(void* p)
+{
+    if (p)
+        static_cast<MachineStackMarker*>(p)->unregisterThread();
+}
+
+void MachineStackMarker::unregisterThread()
+{
+    pthread_t currentPosixThread = pthread_self();
+
+    MutexLocker lock(m_registeredThreadsMutex);
+
+    if (pthread_equal(currentPosixThread, m_registeredThreads->posixThread)) {
+        Thread* t = m_registeredThreads;
+        m_registeredThreads = m_registeredThreads->next;
+        delete t;
+    } else {
+        Thread* last = m_registeredThreads;
+        Thread* t;
+        for (t = m_registeredThreads->next; t; t = t->next) {
+            if (pthread_equal(t->posixThread, currentPosixThread)) {
+                last->next = t->next;
+                break;
+            }
+            last = t;
+        }
+        ASSERT(t); // If t is NULL, we never found ourselves in the list.
+        delete t;
+    }
+}
+
+#endif
+
+void NEVER_INLINE MachineStackMarker::markCurrentThreadConservativelyInternal(MarkStack& markStack)
+{
+    m_heap->markConservatively(markStack, m_heap->globalData()->stack().current(), m_heap->globalData()->stack().origin());
+    markStack.drain();
+}
+
+#if COMPILER(GCC)
+#define REGISTER_BUFFER_ALIGNMENT __attribute__ ((aligned (sizeof(void*))))
+#else
+#define REGISTER_BUFFER_ALIGNMENT
+#endif
+
+void MachineStackMarker::markCurrentThreadConservatively(MarkStack& markStack)
+{
+    // setjmp forces volatile registers onto the stack
+    jmp_buf registers REGISTER_BUFFER_ALIGNMENT;
+#if COMPILER(MSVC)
+#pragma warning(push)
+#pragma warning(disable: 4611)
+#endif
+    setjmp(registers);
+#if COMPILER(MSVC)
+#pragma warning(pop)
+#endif
+
+    markCurrentThreadConservativelyInternal(markStack);
+}
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+
+static inline void suspendThread(const PlatformThread& platformThread)
+{
+#if OS(DARWIN)
+    thread_suspend(platformThread);
+#elif OS(WINDOWS)
+    SuspendThread(platformThread);
+#else
+#error Need a way to suspend threads on this platform
+#endif
+}
+
+static inline void resumeThread(const PlatformThread& platformThread)
+{
+#if OS(DARWIN)
+    thread_resume(platformThread);
+#elif OS(WINDOWS)
+    ResumeThread(platformThread);
+#else
+#error Need a way to resume threads on this platform
+#endif
+}
+
+typedef unsigned long usword_t; // word size, assumed to be either 32 or 64 bit
+
+#if OS(DARWIN)
+
+#if CPU(X86)
+typedef i386_thread_state_t PlatformThreadRegisters;
+#elif CPU(X86_64)
+typedef x86_thread_state64_t PlatformThreadRegisters;
+#elif CPU(PPC)
+typedef ppc_thread_state_t PlatformThreadRegisters;
+#elif CPU(PPC64)
+typedef ppc_thread_state64_t PlatformThreadRegisters;
+#elif CPU(ARM)
+typedef arm_thread_state_t PlatformThreadRegisters;
+#else
+#error Unknown Architecture
+#endif
+
+#elif OS(WINDOWS) && CPU(X86)
+typedef CONTEXT PlatformThreadRegisters;
+#else
+#error Need a thread register struct for this platform
+#endif
+
+static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs)
+{
+#if OS(DARWIN)
+
+#if CPU(X86)
+    unsigned user_count = sizeof(regs)/sizeof(int);
+    thread_state_flavor_t flavor = i386_THREAD_STATE;
+#elif CPU(X86_64)
+    unsigned user_count = x86_THREAD_STATE64_COUNT;
+    thread_state_flavor_t flavor = x86_THREAD_STATE64;
+#elif CPU(PPC) 
+    unsigned user_count = PPC_THREAD_STATE_COUNT;
+    thread_state_flavor_t flavor = PPC_THREAD_STATE;
+#elif CPU(PPC64)
+    unsigned user_count = PPC_THREAD_STATE64_COUNT;
+    thread_state_flavor_t flavor = PPC_THREAD_STATE64;
+#elif CPU(ARM)
+    unsigned user_count = ARM_THREAD_STATE_COUNT;
+    thread_state_flavor_t flavor = ARM_THREAD_STATE;
+#else
+#error Unknown Architecture
+#endif
+
+    kern_return_t result = thread_get_state(platformThread, flavor, (thread_state_t)&regs, &user_count);
+    if (result != KERN_SUCCESS) {
+        WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 
+                            "JavaScript garbage collection failed because thread_get_state returned an error (%d). This is probably the result of running inside Rosetta, which is not supported.", result);
+        CRASH();
+    }
+    return user_count * sizeof(usword_t);
+// end OS(DARWIN)
+
+#elif OS(WINDOWS) && CPU(X86)
+    regs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL | CONTEXT_SEGMENTS;
+    GetThreadContext(platformThread, &regs);
+    return sizeof(CONTEXT);
+#else
+#error Need a way to get thread registers on this platform
+#endif
+}
+
+static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs)
+{
+#if OS(DARWIN)
+
+#if __DARWIN_UNIX03
+
+#if CPU(X86)
+    return reinterpret_cast<void*>(regs.__esp);
+#elif CPU(X86_64)
+    return reinterpret_cast<void*>(regs.__rsp);
+#elif CPU(PPC) || CPU(PPC64)
+    return reinterpret_cast<void*>(regs.__r1);
+#elif CPU(ARM)
+    return reinterpret_cast<void*>(regs.__sp);
+#else
+#error Unknown Architecture
+#endif
+
+#else // !__DARWIN_UNIX03
+
+#if CPU(X86)
+    return reinterpret_cast<void*>(regs.esp);
+#elif CPU(X86_64)
+    return reinterpret_cast<void*>(regs.rsp);
+#elif CPU(PPC) || CPU(PPC64)
+    return reinterpret_cast<void*>(regs.r1);
+#else
+#error Unknown Architecture
+#endif
+
+#endif // __DARWIN_UNIX03
+
+// end OS(DARWIN)
+#elif CPU(X86) && OS(WINDOWS)
+    return reinterpret_cast<void*>((uintptr_t) regs.Esp);
+#else
+#error Need a way to get the stack pointer for another thread on this platform
+#endif
+}
+
+void MachineStackMarker::markOtherThreadConservatively(MarkStack& markStack, Thread* thread)
+{
+    suspendThread(thread->platformThread);
+
+    PlatformThreadRegisters regs;
+    size_t regSize = getPlatformThreadRegisters(thread->platformThread, regs);
+
+    // mark the thread's registers
+    m_heap->markConservatively(markStack, static_cast<void*>(&regs), static_cast<void*>(reinterpret_cast<char*>(&regs) + regSize));
+    markStack.drain();
+
+    void* stackPointer = otherThreadStackPointer(regs);
+    m_heap->markConservatively(markStack, stackPointer, thread->stackBase);
+    markStack.drain();
+
+    resumeThread(thread->platformThread);
+}
+
+#endif
+
+void MachineStackMarker::markMachineStackConservatively(MarkStack& markStack)
+{
+    markCurrentThreadConservatively(markStack);
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+
+    if (m_currentThreadRegistrar) {
+
+        MutexLocker lock(m_registeredThreadsMutex);
+
+#ifndef NDEBUG
+        // Forbid malloc during the mark phase. Marking a thread suspends it, so 
+        // a malloc inside markChildren() would risk a deadlock with a thread that had been 
+        // suspended while holding the malloc lock.
+        fastMallocForbid();
+#endif
+        // It is safe to access the registeredThreads list, because we earlier asserted that locks are being held,
+        // and since this is a shared heap, they are real locks.
+        for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
+            if (!pthread_equal(thread->posixThread, pthread_self()))
+                markOtherThreadConservatively(markStack, thread);
+        }
+#ifndef NDEBUG
+        fastMallocAllow();
+#endif
+    }
+#endif
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/MachineStackMarker.h b/Source/JavaScriptCore/runtime/MachineStackMarker.h
new file mode 100644
index 0000000..e80fe05
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/MachineStackMarker.h
@@ -0,0 +1,73 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten at kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk at post.com)
+ *  Copyright (C) 2003, 2004, 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 Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef MachineStackMarker_h
+#define MachineStackMarker_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/ThreadingPrimitives.h>
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+#include <pthread.h>
+#endif
+
+namespace JSC {
+
+    class Heap;
+    class MarkStack;
+
+    class MachineStackMarker : public Noncopyable {
+    public:
+        MachineStackMarker(Heap*);
+        ~MachineStackMarker();
+
+        void markMachineStackConservatively(MarkStack&);
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+        void makeUsableFromMultipleThreads();
+        void registerThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
+#endif
+
+    private:
+        void markCurrentThreadConservatively(MarkStack&);
+        void markCurrentThreadConservativelyInternal(MarkStack&);
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+        class Thread;
+
+        static void unregisterThread(void*);
+
+        void unregisterThread();
+        void markOtherThreadConservatively(MarkStack&, Thread*);
+#endif
+
+        Heap* m_heap;
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+        Mutex m_registeredThreadsMutex;
+        Thread* m_registeredThreads;
+        pthread_key_t m_currentThreadRegistrar;
+#endif
+    };
+
+} // namespace JSC
+
+#endif // MachineStackMarker_h

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list