[webkit-dev] Seeking help/guidance with ParserError::StackOverflow porting JavaScriptCore to Android

Eric Wing ewmailing at gmail.com
Fri Feb 21 18:05:14 PST 2014


Please bear with me. I'm trying to articulate a problem that another
developer run into. Both of us only know certain pieces of the problem
so I offered to post for both of us.

Quick background: I've been working with Appcelerator to port
JavaScriptCore to Android. The Appcelerator branch forked off of
Webkit I think in the July timeframe, shortly after WWDC. There are
plans to remerge with mainline, but this is down the road.

I currently have a working JavaScriptCore that runs on my 1st gen
Nexus 7 running 4.4. We wrote a test262 conformance app to check our
work, and it passes the 11,000+ tests with less than 20 failures.

I was contacted by the other developer (Shuan Zhao) who had found my
branch reproduced my build of JavaScriptCore for Android. However, on
their Android devices (Android 4.0.4, 4.1.2 and 4.3 (one HTC Desire
HD, one CoolPad and one Samsung Galaxy S4), JavaScriptCore fails to
successfully execute scripts when on the main thread. It appears that
ParserError::StackOverflow is triggered inside JavaScriptCore.

So our belief is that there is some problem related to the stack space
on these devices or these versions of Android.

We started in Source/WTF/wtf/StackBounds.cpp, we found:

void StackBounds::initialize()
{
    void* stackBase = 0;
    size_t stackSize = 0;

    pthread_t thread = pthread_self();
    pthread_attr_t sattr;
    pthread_attr_init(&sattr);
#if HAVE(PTHREAD_NP_H) || OS(NETBSD)
    // e.g. on FreeBSD 5.4, neundorf at kde.org
    pthread_attr_get_np(thread, &sattr);
#else
    // FIXME: this function is non-portable; other POSIX systems may
have different np alternatives
    pthread_getattr_np(thread, &sattr);
#endif
    int rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize);
    (void)rc; // FIXME: Deal with error code somehow? Seems fatal.
    ASSERT(stackBase);
    pthread_attr_destroy(&sattr);
    m_bound = stackBase;
    m_origin = static_cast<char*>(stackBase) + stackSize;
}


Shuan Zhao says "running on the main thread, the stack size is
131072(pthread_attr_getstack and pthread_attr_getstacksize function
returned the same result), which is 1M when running on a new thread. I
don't know why it is much smaller on the main thread. The stack size I
get from program running on my Mac OS is 512K which is also smaller
than 1M."

Additionally:
"I see the following code in JSCore. The value returned by
requiredCapacity is 128K when not in error handling mode which is as
much as the stack size I get on the main thread. I think this will
cause isSafeToRecurse to return false which will cause a stack
overflow exception. I don't know how to fix this."


class VMStackBounds {
public:
    VMStackBounds(VM& vm, const StackBounds& bounds)
        : m_vm(vm)
        , m_bounds(bounds)
    {
    }

    bool isSafeToRecurse() const { return
m_bounds.isSafeToRecurse(requiredCapacity()); }

private:
    inline size_t requiredCapacity() const
    {
        Interpreter* interpreter = m_vm.interpreter;

        // We have two separate stack limits, one for regular JS
execution, and one
        // for when we're handling errors. We need the error stack to be smaller
        // otherwise there would obviously not be any stack left to
execute JS in when
        // there's a stack overflow.
        //
        // These sizes were derived from the stack usage of a number
of sites when
        // layout occurs when we've already consumed most of the C stack.
        const size_t requiredStack = 128 * KB;
        const size_t errorModeRequiredStack = 64 * KB;

        size_t requiredCapacity = interpreter->isInErrorHandlingMode()
? errorModeRequiredStack : requiredStack;
        RELEASE_ASSERT(m_bounds.size() >= requiredCapacity);
        return requiredCapacity;
    }

    VM& m_vm;
    const StackBounds& m_bounds;
};

Finally: "I change the requiredStack variable to 64 * KB, and It works"

Shuan Zhao also noted the current mainline no longer has the
VMStackBounds class.


We really don't know what the correct fix is, so we hoped you could
give us some guidance on what we should try. (Note: We really don't
think it's safe for us to re-merge with mainline right now. There are
still too many unknowns for us.)

Thanks,
Eric

-- 
Beginning iPhone Games Development
http://playcontrol.net/iphonegamebook/


More information about the webkit-dev mailing list