Changeset 74360 in webkit


Ignore:
Timestamp:
Dec 20, 2010 1:16:14 PM (13 years ago)
Author:
barraclough@apple.com
Message:

Bug 26276 - Need a mechanism to determine stack extent

Reviewed by Oliver Hunt.

JavaScriptCore:

This patch adds a class 'StackBounds', to hold information about the machine stack.
The implementation of this class broadly adheres to the current implmentation of
stack limit checking, and as such does not solve the problem of determining stack
extent, but gives us a common place to do so.

Currently two mechanism are provided to determine the stack origin (the point the
stack is growing away from). currentThreadStackBase() in Collector provides a
more accurate determination of the stack origin, so use this to calculate
StackBounds::m_origin; WTFThreadData::approximatedStackStart is less accurate, and
as such can be removed. Cache the StackBounds on WTFThreadData such that they
need only be determined once per thread, and for non-API contexts cache this
information in JSGlobalData, to save a thread-specific access.

For the time being retain the estimate of stack size used by JSC's parser
(128 * sizeof(void*) * 1024), with a view to replacing this with something more
accurate in the near future.

  • parser/JSParser.cpp:

(JSC::JSParser::canRecurse):
(JSC::JSParser::JSParser):

Change to use StackBounds.

  • runtime/Collector.cpp:

(JSC::Heap::registerThread):
(JSC::Heap::markCurrentThreadConservativelyInternal):

Change to use StackBounds, cached on JSGlobalData.

  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::JSGlobalData):

  • runtime/JSGlobalData.h:

(JSC::JSGlobalData::stack):

Add a cached copy of StackBounds.

  • wtf/StackBounds.cpp: Copied from JavaScriptCore/runtime/Collector.cpp.

(WTF::estimateStackBound):
(WTF::StackBounds::initialize):
(WTF::getStackMax):

Copy code from Collector.cpp to determine stack origin.

  • wtf/StackBounds.h: Added.

(WTF::StackBounds::StackBounds):

No argument constructor; returns a null StackBounds.

(WTF::StackBounds::currentThreadStackBounds):

Returns a StackBounds object representing the stack limits
of the current thread.

(WTF::StackBounds::origin):

Returns to stack origin (the point the stack is growing away
from; the highest extent of the stack on machines where the
stack grows downwards.

(WTF::StackBounds::recursionLimit):

Returns a limit value that is 'a comfortable distance from
the end of the stack'. Our concept of this is currently 1 page
away from the end, however the default value may be tuned in
the future, and clients may override passing a larger delta;
should only be called on StackBounds object representing the
stack of the thread this method is called on (checked by
checkConsistency).

(WTF::StackBounds::recursionCheck):

Checks whether we are currently 'a comfortable distance from
the end of the stack'. Our concept of this is currently 1 page
away from the end, however the default value may be tuned in
the future, and clients may override passing a larger delta
to apply when checking, if they wish to do so. This method
should only be called on StackBounds object representing the
stack of the thread this method is called on (checked by
checkConsistency).

(WTF::StackBounds::current):

Approximate current stack position. On machines where the stack
is growing downwards this is the lowest address that might need
conservative collection.

(WTF::StackBounds::isGrowingDownward):

True for all platforms other than WINCE, which has to check.

(WTF::StackBounds::checkConsistency):

This is called in methods that shoulds only be operating on a
valid set of bounds; as such we expect m_origin != m_bounds
(i.e. stack size != zero) - we're really testing that this
object is not null (the constructor initializes both fields
to zero). Also checks that current() is within the stack's
bounds.

  • wtf/WTFThreadData.cpp:

(WTF::WTFThreadData::WTFThreadData):

  • wtf/WTFThreadData.h:

(WTF::WTFThreadData::stack):

Add the StackBounds member variable.

JavaScriptGlue:

Add forwarding header for StackBounds.h.

  • ForwardingHeaders/wtf/StackBounds.h: Added.

WebCore:

Add forwarding header for StackBounds.h.

  • ForwardingHeaders/wtf/StackBounds.h: Added.
Location:
trunk
Files:
4 added
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/Android.mk

    r74357 r74360  
    166166        wtf/RandomNumber.cpp \
    167167        wtf/RefCountedLeakCounter.cpp \
     168    wtf/StackBounds.cpp \
    168169        wtf/TCSystemAlloc.cpp \
    169170        wtf/ThreadIdentifierDataPthreads.cpp \
  • trunk/JavaScriptCore/Android.v8.wtf.mk

    r70198 r74360  
    4343        wtf/RandomNumber.cpp \
    4444        wtf/RefCountedLeakCounter.cpp \
     45    wtf/StackBounds.cpp \
    4546        wtf/TCSystemAlloc.cpp \
    4647        wtf/ThreadIdentifierDataPthreads.cpp \
  • trunk/JavaScriptCore/ChangeLog

    r74357 r74360  
     12010-12-18  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        Bug 26276 - Need a mechanism to determine stack extent
     6
     7        This patch adds a class 'StackBounds', to hold information about the machine stack.
     8        The implementation of this class broadly adheres to the current implmentation of
     9        stack limit checking, and as such does not solve the problem of determining stack
     10        extent, but gives us a common place to do so.
     11
     12        Currently two mechanism are provided to determine the stack origin (the point the
     13        stack is growing away from). currentThreadStackBase() in Collector provides a
     14        more accurate determination of the stack origin, so use this to calculate
     15        StackBounds::m_origin; WTFThreadData::approximatedStackStart is less accurate, and
     16        as such can be removed.  Cache the StackBounds on WTFThreadData such that they
     17        need only be determined once per thread, and for non-API contexts cache this
     18        information in JSGlobalData, to save a thread-specific access.
     19
     20        For the time being retain the estimate of stack size used by JSC's parser
     21        (128 * sizeof(void*) * 1024), with a view to replacing this with something more
     22        accurate in the near future.
     23
     24        * parser/JSParser.cpp:
     25        (JSC::JSParser::canRecurse):
     26        (JSC::JSParser::JSParser):
     27            Change to use StackBounds.
     28        * runtime/Collector.cpp:
     29        (JSC::Heap::registerThread):
     30        (JSC::Heap::markCurrentThreadConservativelyInternal):
     31            Change to use StackBounds, cached on JSGlobalData.
     32        * runtime/JSGlobalData.cpp:
     33        (JSC::JSGlobalData::JSGlobalData):
     34        * runtime/JSGlobalData.h:
     35        (JSC::JSGlobalData::stack):
     36            Add a cached copy of StackBounds.
     37        * wtf/StackBounds.cpp: Copied from JavaScriptCore/runtime/Collector.cpp.
     38        (WTF::estimateStackBound):
     39        (WTF::StackBounds::initialize):
     40        (WTF::getStackMax):
     41            Copy code from Collector.cpp to determine stack origin.
     42        * wtf/StackBounds.h: Added.
     43        (WTF::StackBounds::StackBounds):
     44            No argument constructor; returns a null StackBounds.
     45        (WTF::StackBounds::currentThreadStackBounds):
     46            Returns a StackBounds object representing the stack limits
     47            of the current thread.
     48        (WTF::StackBounds::origin):
     49            Returns to stack origin (the point the stack is growing away
     50            from; the highest extent of the stack on machines where the
     51            stack grows downwards.
     52        (WTF::StackBounds::recursionLimit):
     53            Returns a limit value that is 'a comfortable distance from
     54            the end of the stack'. Our concept of this is currently 1 page
     55            away from the end, however the default value may be tuned in
     56            the future, and clients may override passing a larger delta;
     57            should only be called on StackBounds object representing the
     58            stack of the thread this method is called on (checked by
     59            checkConsistency).
     60        (WTF::StackBounds::recursionCheck):
     61            Checks whether we are currently 'a comfortable distance from
     62            the end of the stack'. Our concept of this is currently 1 page
     63            away from the end, however the default value may be tuned in
     64            the future, and clients may override passing a larger delta
     65            to apply when checking, if they wish to do so. This method
     66            should only be called on StackBounds object representing the
     67            stack of the thread this method is called on (checked by
     68            checkConsistency).
     69        (WTF::StackBounds::current):
     70            Approximate current stack position. On machines where the stack
     71            is growing downwards this is the lowest address that might need
     72            conservative collection.
     73        (WTF::StackBounds::isGrowingDownward):
     74            True for all platforms other than WINCE, which has to check.
     75        (WTF::StackBounds::checkConsistency):
     76            This is called in methods that shoulds only be operating on a
     77            valid set of bounds; as such we expect m_origin != m_bounds
     78            (i.e. stack size != zero) - we're really testing that this
     79            object is not null (the constructor initializes both fields
     80            to zero).  Also checks that current() is within the stack's
     81            bounds.
     82        * wtf/WTFThreadData.cpp:
     83        (WTF::WTFThreadData::WTFThreadData):
     84        * wtf/WTFThreadData.h:
     85        (WTF::WTFThreadData::stack):
     86            Add the StackBounds member variable.
     87
    1882010-12-17  Geoffrey Garen  <ggaren@apple.com>
    289
  • trunk/JavaScriptCore/GNUmakefile.am

    r74357 r74360  
    495495        JavaScriptCore/wtf/RetainPtr.h \
    496496        JavaScriptCore/wtf/SegmentedVector.h \
     497    JavaScriptCore/wtf/StackBounds.cpp \
     498    JavaScriptCore/wtf/StackBounds.h \
    497499        JavaScriptCore/wtf/StaticConstructors.h \
    498500        JavaScriptCore/wtf/StdLibExtras.h \
  • trunk/JavaScriptCore/JavaScriptCore.gypi

    r74357 r74360  
    425425            'wtf/SegmentedVector.h',
    426426            'wtf/SizeLimits.cpp',
     427            'wtf/StackBounds.cpp',
     428            'wtf/StackBounds.h',
    427429            'wtf/StaticConstructors.h',
    428430            'wtf/StdLibExtras.h',
  • trunk/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj

    r74357 r74360  
    778778                </File>
    779779                <File
     780                        RelativePath="..\..\wtf\StackBounds.cpp"
     781                        >
     782                </File>
     783                <File
     784                        RelativePath="..\..\wtf\StackBounds.h"
     785                        >
     786                </File>
     787                <File
    780788                        RelativePath="..\..\wtf\StaticConstructors.h"
    781789                        >
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r74357 r74360  
    253253                86D3B3C310159D7F002865E7 /* LinkBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B3C110159D7F002865E7 /* LinkBuffer.h */; };
    254254                86D3B3C410159D7F002865E7 /* RepatchBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B3C210159D7F002865E7 /* RepatchBuffer.h */; };
     255                86D87DAE12BCA7D1008E73A1 /* StackBounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86D87DA512BC4B14008E73A1 /* StackBounds.cpp */; };
     256                86D87DDB12BCAF94008E73A1 /* StackBounds.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D87DA612BC4B14008E73A1 /* StackBounds.h */; settings = {ATTRIBUTES = (Private, ); }; };
    255257                86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */; };
    256258                86E116B10FE75AC800B512BC /* CodeLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E116B00FE75AC800B512BC /* CodeLocation.h */; };
     
    870872                86D3B3C110159D7F002865E7 /* LinkBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkBuffer.h; sourceTree = "<group>"; };
    871873                86D3B3C210159D7F002865E7 /* RepatchBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RepatchBuffer.h; sourceTree = "<group>"; };
     874                86D87DA512BC4B14008E73A1 /* StackBounds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StackBounds.cpp; sourceTree = "<group>"; };
     875                86D87DA612BC4B14008E73A1 /* StackBounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackBounds.h; sourceTree = "<group>"; };
    872876                86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorFixedVMPool.cpp; sourceTree = "<group>"; };
    873877                86E116B00FE75AC800B512BC /* CodeLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeLocation.h; sourceTree = "<group>"; };
     
    15591563                                969A07290ED1CE6900F1F681 /* SegmentedVector.h */,
    15601564                                0BF28A2811A33DC300638F84 /* SizeLimits.cpp */,
     1565                                86D87DA512BC4B14008E73A1 /* StackBounds.cpp */,
     1566                                86D87DA612BC4B14008E73A1 /* StackBounds.h */,
    15611567                                868BFA5F117D048200B908B1 /* StaticConstructors.h */,
    15621568                                FE1B44790ECCD73B004F4DD1 /* StdLibExtras.h */,
     
    22962302                                BC18C4630E16F5CD00B34460 /* SourceProvider.h in Headers */,
    22972303                                A7386554118697B400540279 /* SpecializedThunkJIT.h in Headers */,
     2304                                86D87DDB12BCAF94008E73A1 /* StackBounds.h in Headers */,
    22982305                                868BFA60117D048200B908B1 /* StaticConstructors.h in Headers */,
    22992306                                FE1B447A0ECCD73B004F4DD1 /* StdLibExtras.h in Headers */,
     
    27982805                                0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */,
    27992806                                9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */,
     2807                                86D87DAE12BCA7D1008E73A1 /* StackBounds.cpp in Sources */,
    28002808                                14469DEB107EC7E700650446 /* StringConstructor.cpp in Sources */,
    28012809                                868BFA0E117CEFD100B908B1 /* StringImpl.cpp in Sources */,
  • trunk/JavaScriptCore/parser/JSParser.cpp

    r74299 r74360  
    6565
    6666COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
    67 
    68 // This matches v8
    69 static const ptrdiff_t kMaxParserStackUsage = 128 * sizeof(void*) * 1024;
    7067
    7168class JSParser {
     
    194191    bool canRecurse()
    195192    {
    196         char sample = 0;
    197         ASSERT(m_endAddress);
    198         return &sample > m_endAddress;
     193        return m_stack.recursionCheck();
    199194    }
    200195   
     
    206201    ParserArena m_arena;
    207202    Lexer* m_lexer;
    208     char* m_endAddress;
     203    StackBounds m_stack;
    209204    bool m_error;
    210205    JSGlobalData* m_globalData;
     
    492487JSParser::JSParser(Lexer* lexer, JSGlobalData* globalData, FunctionParameters* parameters, bool inStrictContext, bool isFunction, SourceProvider* provider)
    493488    : m_lexer(lexer)
    494     , m_endAddress(0)
     489    , m_stack(globalData->stack())
    495490    , m_error(false)
    496491    , m_globalData(globalData)
     
    506501    , m_lastIdentifier(0)
    507502{
    508     m_endAddress = wtfThreadData().approximatedStackStart() - kMaxParserStackUsage;
    509503    ScopeRef scope = pushScope();
    510504    if (isFunction)
  • trunk/JavaScriptCore/runtime/Collector.cpp

    r73623 r74360  
    390390}
    391391
    392 #if OS(WINCE)
    393 JS_EXPORTDATA void* g_stackBase = 0;
    394 
    395 inline bool isPageWritable(void* page)
    396 {
    397     MEMORY_BASIC_INFORMATION memoryInformation;
    398     DWORD result = VirtualQuery(page, &memoryInformation, sizeof(memoryInformation));
    399 
    400     // return false on error, including ptr outside memory
    401     if (result != sizeof(memoryInformation))
    402         return false;
    403 
    404     DWORD protect = memoryInformation.Protect & ~(PAGE_GUARD | PAGE_NOCACHE);
    405     return protect == PAGE_READWRITE
    406         || protect == PAGE_WRITECOPY
    407         || protect == PAGE_EXECUTE_READWRITE
    408         || protect == PAGE_EXECUTE_WRITECOPY;
    409 }
    410 
    411 static void* getStackBase(void* previousFrame)
    412 {
    413     // find the address of this stack frame by taking the address of a local variable
    414     bool isGrowingDownward;
    415     void* thisFrame = (void*)(&isGrowingDownward);
    416 
    417     isGrowingDownward = previousFrame < &thisFrame;
    418     static DWORD pageSize = 0;
    419     if (!pageSize) {
    420         SYSTEM_INFO systemInfo;
    421         GetSystemInfo(&systemInfo);
    422         pageSize = systemInfo.dwPageSize;
    423     }
    424 
    425     // scan all of memory starting from this frame, and return the last writeable page found
    426     register char* currentPage = (char*)((DWORD)thisFrame & ~(pageSize - 1));
    427     if (isGrowingDownward) {
    428         while (currentPage > 0) {
    429             // check for underflow
    430             if (currentPage >= (char*)pageSize)
    431                 currentPage -= pageSize;
    432             else
    433                 currentPage = 0;
    434             if (!isPageWritable(currentPage))
    435                 return currentPage + pageSize;
    436         }
    437         return 0;
    438     } else {
    439         while (true) {
    440             // guaranteed to complete because isPageWritable returns false at end of memory
    441             currentPage += pageSize;
    442             if (!isPageWritable(currentPage))
    443                 return currentPage;
    444         }
    445     }
    446 }
    447 #endif
    448 
    449 #if OS(QNX)
    450 static inline void *currentThreadStackBaseQNX()
    451 {
    452     static void* stackBase = 0;
    453     static size_t stackSize = 0;
    454     static pthread_t stackThread;
    455     pthread_t thread = pthread_self();
    456     if (stackBase == 0 || thread != stackThread) {
    457         struct _debug_thread_info threadInfo;
    458         memset(&threadInfo, 0, sizeof(threadInfo));
    459         threadInfo.tid = pthread_self();
    460         int fd = open("/proc/self", O_RDONLY);
    461         if (fd == -1) {
    462             LOG_ERROR("Unable to open /proc/self (errno: %d)", errno);
    463             return 0;
    464         }
    465         devctl(fd, DCMD_PROC_TIDSTATUS, &threadInfo, sizeof(threadInfo), 0);
    466         close(fd);
    467         stackBase = reinterpret_cast<void*>(threadInfo.stkbase);
    468         stackSize = threadInfo.stksize;
    469         ASSERT(stackBase);
    470         stackThread = thread;
    471     }
    472     return static_cast<char*>(stackBase) + stackSize;
    473 }
    474 #endif
    475 
    476 static inline void* currentThreadStackBase()
    477 {
    478 #if OS(DARWIN)
    479     pthread_t thread = pthread_self();
    480     return pthread_get_stackaddr_np(thread);
    481 #elif OS(WINDOWS) && CPU(X86) && COMPILER(MSVC)
    482     // offset 0x18 from the FS segment register gives a pointer to
    483     // the thread information block for the current thread
    484     NT_TIB* pTib;
    485     __asm {
    486         MOV EAX, FS:[18h]
    487         MOV pTib, EAX
    488     }
    489     return static_cast<void*>(pTib->StackBase);
    490 #elif OS(WINDOWS) && CPU(X86) && COMPILER(GCC)
    491     // offset 0x18 from the FS segment register gives a pointer to
    492     // the thread information block for the current thread
    493     NT_TIB* pTib;
    494     asm ( "movl %%fs:0x18, %0\n"
    495           : "=r" (pTib)
    496         );
    497     return static_cast<void*>(pTib->StackBase);
    498 #elif OS(WINDOWS) && CPU(X86_64)
    499     PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb());
    500     return reinterpret_cast<void*>(pTib->StackBase);
    501 #elif OS(QNX)
    502     AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
    503     MutexLocker locker(mutex);
    504     return currentThreadStackBaseQNX();
    505 #elif OS(SOLARIS)
    506     stack_t s;
    507     thr_stksegment(&s);
    508     return s.ss_sp;
    509 #elif OS(OPENBSD)
    510     pthread_t thread = pthread_self();
    511     stack_t stack;
    512     pthread_stackseg_np(thread, &stack);
    513     return stack.ss_sp;
    514 #elif OS(SYMBIAN)
    515     TThreadStackInfo info;
    516     RThread thread;
    517     thread.StackInfo(info);
    518     return (void*)info.iBase;
    519 #elif OS(HAIKU)
    520     thread_info threadInfo;
    521     get_thread_info(find_thread(NULL), &threadInfo);
    522     return threadInfo.stack_end;
    523 #elif OS(UNIX)
    524     AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
    525     MutexLocker locker(mutex);
    526     static void* stackBase = 0;
    527     static size_t stackSize = 0;
    528     static pthread_t stackThread;
    529     pthread_t thread = pthread_self();
    530     if (stackBase == 0 || thread != stackThread) {
    531         pthread_attr_t sattr;
    532         pthread_attr_init(&sattr);
    533 #if HAVE(PTHREAD_NP_H) || OS(NETBSD)
    534         // e.g. on FreeBSD 5.4, neundorf@kde.org
    535         pthread_attr_get_np(thread, &sattr);
    536 #else
    537         // FIXME: this function is non-portable; other POSIX systems may have different np alternatives
    538         pthread_getattr_np(thread, &sattr);
    539 #endif
    540         int rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize);
    541         (void)rc; // FIXME: Deal with error code somehow? Seems fatal.
    542         ASSERT(stackBase);
    543         pthread_attr_destroy(&sattr);
    544         stackThread = thread;
    545     }
    546     return static_cast<char*>(stackBase) + stackSize;
    547 #elif OS(WINCE)
    548     AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
    549     MutexLocker locker(mutex);
    550     if (g_stackBase)
    551         return g_stackBase;
    552     else {
    553         int dummy;
    554         return getStackBase(&dummy);
    555     }
    556 #else
    557 #error Need a way to get the stack base on this platform
    558 #endif
    559 }
    560 
    561392#if ENABLE(JSC_MULTIPLE_THREADS)
    562393
     
    588419
    589420    pthread_setspecific(m_currentThreadRegistrar, this);
    590     Heap::Thread* thread = new Heap::Thread(pthread_self(), getCurrentPlatformThread(), currentThreadStackBase());
     421    Heap::Thread* thread = new Heap::Thread(pthread_self(), getCurrentPlatformThread(), m_globalData->stack().origin());
    591422
    592423    MutexLocker lock(m_registeredThreadsMutex);
     
    655486void Heap::markConservatively(MarkStack& markStack, void* start, void* end)
    656487{
     488#if OS(WINCE)
    657489    if (start > end) {
    658490        void* tmp = start;
     
    660492        end = tmp;
    661493    }
     494#else
     495    ASSERT(start <= end);
     496#endif
    662497
    663498    ASSERT((static_cast<char*>(end) - static_cast<char*>(start)) < 0x1000000);
     
    693528void NEVER_INLINE Heap::markCurrentThreadConservativelyInternal(MarkStack& markStack)
    694529{
    695     void* dummy;
    696     void* stackPointer = &dummy;
    697     void* stackBase = currentThreadStackBase();
    698     markConservatively(markStack, stackPointer, stackBase);
     530    markConservatively(markStack, m_globalData->stack().current(), m_globalData->stack().origin());
    699531    markStack.drain();
    700532}
  • trunk/JavaScriptCore/runtime/JSGlobalData.cpp

    r72360 r74360  
    154154#endif
    155155{
     156    if (globalDataType == Default)
     157        m_stack = wtfThreadData().stack();
     158
    156159#if PLATFORM(MAC)
    157160    startProfilerServerIfNeeded();
  • trunk/JavaScriptCore/runtime/JSGlobalData.h

    r72489 r74360  
    4747#include <wtf/RefCounted.h>
    4848#include <wtf/ThreadSpecific.h>
     49#include <wtf/WTFThreadData.h>
    4950#if ENABLE(REGEXP_TRACING)
    5051#include <wtf/ListHashSet.h>
     
    179180        bool canUseJIT() { return m_canUseJIT; }
    180181#endif
     182
     183        const StackBounds& stack()
     184        {
     185            return (globalDataType == Default)
     186                ? m_stack
     187                : wtfThreadData().stack();
     188        }
     189
    181190        Lexer* lexer;
    182191        Parser* parser;
     
    251260        bool m_canUseJIT;
    252261#endif
     262        StackBounds m_stack;
    253263    };
    254264
  • trunk/JavaScriptCore/wtf/CMakeLists.txt

    r70201 r74360  
    1010    RandomNumber.cpp
    1111    RefCountedLeakCounter.cpp
     12    StackBounds.cpp
    1213    StringExtras.cpp
    1314    Threading.cpp
  • trunk/JavaScriptCore/wtf/WTFThreadData.cpp

    r66665 r74360  
    4343    , m_currentIdentifierTable(m_defaultIdentifierTable)
    4444#endif
     45    , m_stackBounds(StackBounds::currentThreadStackBounds())
    4546{
    46     char sample = 0;
    47     m_approximatedStackStart = &sample;
    4847}
    4948
  • trunk/JavaScriptCore/wtf/WTFThreadData.h

    r69458 r74360  
    3131#include <wtf/HashSet.h>
    3232#include <wtf/Noncopyable.h>
     33#include <wtf/StackBounds.h>
    3334#include <wtf/text/StringHash.h>
    3435
     
    114115#endif
    115116
    116     char* approximatedStackStart() const
     117    const StackBounds& stack() const
    117118    {
    118         return m_approximatedStackStart;
     119        return m_stackBounds;
    119120    }
    120121
     
    136137    friend class AtomicStringTable;
    137138
    138     char* m_approximatedStackStart;
     139    StackBounds m_stackBounds;
    139140};
    140141
  • trunk/JavaScriptCore/wtf/wtf.pri

    r74357 r74360  
    2020    wtf/RandomNumber.cpp \
    2121    wtf/RefCountedLeakCounter.cpp \
     22    wtf/StackBounds.cpp \
    2223    wtf/ThreadingNone.cpp \
    2324    wtf/Threading.cpp \
  • trunk/JavaScriptGlue/ChangeLog

    r74357 r74360  
     12010-12-18  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        Bug 26276 - Need a mechanism to determine stack extent
     6
     7        Add forwarding header for StackBounds.h.
     8
     9        * ForwardingHeaders/wtf/StackBounds.h: Added.
     10
    1112010-12-20  Geoffrey Garen  <ggaren@apple.com>
    212
  • trunk/WebCore/ChangeLog

    r74358 r74360  
     12010-12-18  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        Bug 26276 - Need a mechanism to determine stack extent
     6
     7        Add forwarding header for StackBounds.h.
     8
     9        * ForwardingHeaders/wtf/StackBounds.h: Added.
     10
    1112010-12-20  James Robinson  <jamesr@chromium.org>
    212
Note: See TracChangeset for help on using the changeset viewer.