Bug 974350 part 1 - Rewrite CreateRegExpMatchResult to not use an AutoValueVector. r=h4writer
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 19 Feb 2014 17:37:17 +0100
changeset 169887 76618fcca7219afa71ef3fc58e70c6815c8ca131
parent 169886 abce7c294e389be130a5af01a1ad87349c2edb96
child 169888 6e3f7835fa623d2a083056889a9fe4d6ebaf09b7
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersh4writer
bugs974350
milestone30.0a1
Bug 974350 part 1 - Rewrite CreateRegExpMatchResult to not use an AutoValueVector. r=h4writer
js/src/builtin/RegExp.cpp
js/src/jsarray.cpp
js/src/jsarray.h
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -34,49 +34,45 @@ js::CreateRegExpMatchResult(JSContext *c
      *  index:          start index for the match
      */
     if (!input) {
         input = js_NewStringCopyN<CanGC>(cx, chars, length);
         if (!input)
             return false;
     }
 
-    size_t numPairs = matches.length();
-    JS_ASSERT(numPairs > 0);
-
-    AutoValueVector elements(cx);
-    if (!elements.reserve(numPairs))
-        return false;
-
-    /* Accumulate a Value for each pair, in a rooted vector. */
-    for (size_t i = 0; i < numPairs; ++i) {
-        const MatchPair &pair = matches[i];
-
-        if (pair.isUndefined()) {
-            JS_ASSERT(i != 0); /* Since we had a match, first pair must be present. */
-            elements.infallibleAppend(UndefinedHandleValue);
-        } else {
-            JSLinearString *str = js_NewDependentString(cx, input, pair.start, pair.length());
-            if (!str)
-                return false;
-            elements.infallibleAppend(StringValue(str));
-        }
-    }
-
     /* Get the templateObject that defines the shape and type of the output object */
     JSObject *templateObject = cx->compartment()->regExps.getOrCreateMatchResultTemplateObject(cx);
     if (!templateObject)
         return false;
 
-    /* Copy the rooted vector into the array object. */
-    RootedObject arr(cx, NewDenseCopiedArrayWithTemplate(cx, elements.length(), elements.begin(),
-                                                         templateObject));
+    size_t numPairs = matches.length();
+    JS_ASSERT(numPairs > 0);
+
+    RootedObject arr(cx, NewDenseAllocatedArrayWithTemplate(cx, numPairs, templateObject));
     if (!arr)
         return false;
 
+    /* Store a Value for each pair. */
+    for (size_t i = 0; i < numPairs; i++) {
+        const MatchPair &pair = matches[i];
+
+        if (pair.isUndefined()) {
+            JS_ASSERT(i != 0); /* Since we had a match, first pair must be present. */
+            arr->setDenseInitializedLength(i + 1);
+            arr->initDenseElement(i, UndefinedValue());
+        } else {
+            JSLinearString *str = js_NewDependentString(cx, input, pair.start, pair.length());
+            if (!str)
+                return false;
+            arr->setDenseInitializedLength(i + 1);
+            arr->initDenseElement(i, StringValue(str));
+        }
+    }
+
     /* Set the |index| property. (TemplateObject positions it in slot 0) */
     RootedValue index(cx, Int32Value(matches[0].start));
     arr->nativeSetSlot(0, index);
 
     /* Set the |input| property. (TemplateObject positions it in slot 1) */
     RootedValue inputVal(cx, StringValue(input));
     arr->nativeSetSlot(1, inputVal);
 
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -3272,18 +3272,17 @@ js::NewDenseCopiedArray(JSContext *cx, u
 
     if (values)
         arr->initDenseElements(0, values, length);
 
     return arr;
 }
 
 ArrayObject *
-js::NewDenseCopiedArrayWithTemplate(JSContext *cx, uint32_t length, const Value *values,
-                                    JSObject *templateObject)
+js::NewDenseAllocatedArrayWithTemplate(JSContext *cx, uint32_t length, JSObject *templateObject)
 {
     gc::AllocKind allocKind = GuessArrayGCKind(length);
     JS_ASSERT(CanBeFinalizedInBackground(allocKind, &ArrayObject::class_));
     allocKind = GetBackgroundAllocKind(allocKind);
 
     RootedTypeObject type(cx, templateObject->type());
     if (!type)
         return nullptr;
@@ -3295,19 +3294,16 @@ js::NewDenseCopiedArrayWithTemplate(JSCo
     gc::InitialHeap heap = GetInitialHeap(GenericObject, &ArrayObject::class_);
     Rooted<ArrayObject *> arr(cx, JSObject::createArray(cx, allocKind, heap, shape, type, length));
     if (!arr)
         return nullptr;
 
     if (!EnsureNewArrayElements(cx, arr, length))
         return nullptr;
 
-    arr->setDenseInitializedLength(length);
-    arr->initDenseElements(0, values, length);
-
     probes::CreateObject(cx, arr);
 
     return arr;
 }
 
 #ifdef DEBUG
 bool
 js_ArrayInfo(JSContext *cx, unsigned argc, Value *vp)
--- a/js/src/jsarray.h
+++ b/js/src/jsarray.h
@@ -65,23 +65,20 @@ NewDenseUnallocatedArray(ExclusiveContex
 extern ArrayObject *
 NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t elementOffset, JSObject *proto = nullptr);
 
 /* Create a dense array from the given array values, which must be rooted */
 extern ArrayObject *
 NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values, JSObject *proto = nullptr,
                     NewObjectKind newKind = GenericObject);
 
-/*
- * Create a dense array based on templateObject from the given array values,
- * which must be rooted.
- */
+/* Create a dense array based on templateObject with the given length. */
 extern ArrayObject *
-NewDenseCopiedArrayWithTemplate(JSContext *cx, uint32_t length, const Value *values,
-                                JSObject *templateObject);
+NewDenseAllocatedArrayWithTemplate(JSContext *cx, uint32_t length, JSObject *templateObject);
+
 /*
  * Determines whether a write to the given element on |obj| should fail because
  * |obj| is an Array with a non-writable length, and writing that element would
  * increase the length of the array.
  */
 extern bool
 WouldDefinePastNonwritableLength(ThreadSafeContext *cx,
                                  HandleObject obj, uint32_t index, bool strict,