Bug 609103 - jsapi-tests/testThreads.cpp should call JS_SetNativeStackQuota to avoid stack overflow. rs=gwagner.
authorJason Orendorff <jorendorff@mozilla.com>
Wed, 17 Nov 2010 17:13:15 -0600
changeset 58038 30c864b404833da3c08199a7f703c87a7b4dadd7
parent 57837 08794e076dedf23252ac6c7f03c2cd1f5a896d0f
child 58039 d446894bc3a61fb381f6d6d5e9c4ba4605fa3a16
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersgwagner
bugs609103
milestone2.0b8pre
Bug 609103 - jsapi-tests/testThreads.cpp should call JS_SetNativeStackQuota to avoid stack overflow. rs=gwagner.
js/src/jsapi-tests/testThreads.cpp
--- a/js/src/jsapi-tests/testThreads.cpp
+++ b/js/src/jsapi-tests/testThreads.cpp
@@ -46,16 +46,19 @@ BEGIN_TEST(testThreads_bug561444)
             d->ok = ac.enter(cx, d->obj) &&
                     JS_EvaluateScript(cx, d->obj, d->code, strlen(d->code), __FILE__, __LINE__,
                                       &v);
         }
         JS_DestroyContext(cx);
     }
 END_TEST(testThreads_bug561444)
 
+const PRUint32 NATIVE_STACK_SIZE = 64 * 1024;
+const PRUint32 NATIVE_STACK_HEADROOM = 8 * 1024;
+
 template <class T>
 class Repeat {
     size_t n;
     const T &t;
 
   public:
     Repeat(size_t n, const T &t) : n(n), t(t) {}
 
@@ -91,17 +94,17 @@ class Parallel {
 
         PRThread **thread = new PRThread *[n];
 	if (!thread)
 	    return false;
 
         size_t i;
         for (i = 0; i < n; i++) {
             thread[i] = PR_CreateThread(PR_USER_THREAD, threadMain, &p, PR_PRIORITY_NORMAL,
-                                        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+                                        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, NATIVE_STACK_SIZE);
             if (thread[i] == NULL) {
                 p.ok = false;
                 break;
             }
         }
         while (i--)
             PR_JoinThread(thread[i]);
 
@@ -120,16 +123,17 @@ class eval {
   public:
     eval(JSRuntime *rt, const char *code) : rt(rt), code(code) {}
 
     bool operator()() const {
         JSContext *cx = JS_NewContext(rt, 8192);
 	if (!cx)
 	    return false;
 
+        JS_SetNativeStackQuota(cx, NATIVE_STACK_SIZE - NATIVE_STACK_HEADROOM);
         bool ok = false;
 	{
 	    JSAutoRequest ar(cx);
 	    JSObject *global =
 		JS_NewCompartmentAndGlobalObject(cx, JSAPITest::basicGlobalClass(), NULL);
 	    if (global) {
 		JS_SetGlobalObject(cx, global);
 		jsval rval;
@@ -147,9 +151,24 @@ BEGIN_TEST(testThreads_bug604782)
     jsrefcount rc = JS_SuspendRequest(cx);
     bool ok = repeat(20, parallel(3, eval(rt, "for(i=0;i<1000;i++);")))();
     JS_ResumeRequest(cx, rc);
     CHECK(ok);
     return true;
 }
 END_TEST(testThreads_bug604782)
 
+BEGIN_TEST(testThreads_bug609103)
+{
+    const char *code = 
+        "var x = {};\n"
+        "for (var i = 0; i < 10000; i++)\n"
+        "    x = {next: x};\n";
+
+    jsrefcount rc = JS_SuspendRequest(cx);
+    bool ok = parallel(2, eval(rt, code))();
+    JS_ResumeRequest(cx, rc);
+    CHECK(ok);
+    return true;
+}
+END_TEST(testThreads_bug609103)
+
 #endif