Bug 1257164 - Check for interrupts in a few loops in JSON.stringify to eliminate feedback-less hangs. r=evilpie
authorJeff Walden <jwalden@mit.edu>
Wed, 13 Apr 2016 14:39:58 -0700
changeset 331027 1e6cb22a8971cb6ba21bd44afe084b9db22f5911
parent 331026 fe3aba52a965e4975aa9f1f416852cd3ac923846
child 331028 1cbabad59a633c1b555b1c6574e11bd12404c022
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersevilpie
bugs1257164
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1257164 - Check for interrupts in a few loops in JSON.stringify to eliminate feedback-less hangs. r=evilpie
js/src/json.cpp
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -367,16 +367,19 @@ JO(JSContext* cx, HandleObject obj, Stri
 
     /* My kingdom for not-quite-initialized-from-the-start references. */
     const AutoIdVector& propertyList = *props;
 
     /* Steps 8-10, 13. */
     bool wroteMember = false;
     RootedId id(cx);
     for (size_t i = 0, len = propertyList.length(); i < len; i++) {
+        if (!CheckForInterrupt(cx))
+            return false;
+
         /*
          * Steps 8a-8b.  Note that the call to Str is broken up into 1) getting
          * the property; 2) processing for toJSON, calling the replacer, and
          * handling boxed Number/String/Boolean objects; 3) filtering out
          * values which process to |undefined|, and 4) stringifying all values
          * which pass the filter.
          */
         id = propertyList[i];
@@ -454,16 +457,19 @@ JA(JSContext* cx, HandleObject obj, Stri
     if (length != 0) {
         /* Steps 4, 10b(i). */
         if (!WriteIndent(cx, scx, scx->depth))
             return false;
 
         /* Steps 7-10. */
         RootedValue outputValue(cx);
         for (uint32_t i = 0; i < length; i++) {
+            if (!CheckForInterrupt(cx))
+                return false;
+
             /*
              * Steps 8a-8c.  Again note how the call to the spec's Str method
              * is broken up into getting the property, running it past toJSON
              * and the replacer and maybe unboxing, and interpreting some
              * values as |null| in separate steps.
              */
 #ifdef DEBUG
             if (scx->maybeSafely) {
@@ -771,16 +777,19 @@ Walk(JSContext* cx, HandleObject holder,
             uint32_t length;
             if (!GetLengthProperty(cx, obj, &length))
                 return false;
 
             /* Step 2a(i), 2a(iii-iv). */
             RootedId id(cx);
             RootedValue newElement(cx);
             for (uint32_t i = 0; i < length; i++) {
+                if (!CheckForInterrupt(cx))
+                    return false;
+
                 if (!IndexToId(cx, i, &id))
                     return false;
 
                 /* Step 2a(iii)(1). */
                 if (!Walk(cx, obj, id, reviver, &newElement))
                     return false;
 
                 ObjectOpResult ignored;
@@ -801,16 +810,19 @@ Walk(JSContext* cx, HandleObject holder,
             AutoIdVector keys(cx);
             if (!GetPropertyKeys(cx, obj, JSITER_OWNONLY, &keys))
                 return false;
 
             /* Step 2b(ii). */
             RootedId id(cx);
             RootedValue newElement(cx);
             for (size_t i = 0, len = keys.length(); i < len; i++) {
+                if (!CheckForInterrupt(cx))
+                    return false;
+
                 /* Step 2b(ii)(1). */
                 id = keys[i];
                 if (!Walk(cx, obj, id, reviver, &newElement))
                     return false;
 
                 ObjectOpResult ignored;
                 if (newElement.isUndefined()) {
                     /* Step 2b(ii)(2). The spec deliberately ignores strict failure. */