Bug 403878 - Replacing js_InternalCall with js_Invoke in Array.sort for arrays with scripted compator functions -- save alloc/free on each compare r=ibukanov, a=blocking1.9+
authorcrowder@fiverocks.com
Tue, 20 Nov 2007 10:07:13 -0800
changeset 8224 88b2a48fa4ca7e4d39a22692ebec902d3c60671b
parent 8223 6b1f67fccbd40dcd38128466389d1f7efe3846eb
child 8225 1143d2949ef6873e06043af687dd0bedea7da62e
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherderautoland@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersibukanov, blocking1.9
bugs403878
milestone1.9b2pre
Bug 403878 - Replacing js_InternalCall with js_Invoke in Array.sort for arrays with scripted compator functions -- save alloc/free on each compare r=ibukanov, a=blocking1.9+
js/src/jsarray.c
--- a/js/src/jsarray.c
+++ b/js/src/jsarray.c
@@ -989,16 +989,17 @@ js_MergeSort(void *src, size_t nel, size
 
     return JS_TRUE;
 }
 
 typedef struct CompareArgs {
     JSContext   *context;
     jsval       fval;
     jsval       *localroot;     /* need one local root, for sort_compare */
+    jsval       *elemroot;      /* stack needed for js_Invoke */
 } CompareArgs;
 
 static JSBool
 sort_compare(void *arg, const void *a, const void *b, int *result)
 {
     jsval av = *(const jsval *)a, bv = *(const jsval *)b;
     CompareArgs *ca = (CompareArgs *) arg;
     JSContext *cx = ca->context;
@@ -1032,26 +1033,29 @@ sort_compare(void *arg, const void *a, c
             astr = js_ValueToString(cx, av);
             *ca->localroot = STRING_TO_JSVAL(astr);
             if (astr && (bstr = js_ValueToString(cx, bv)))
                 *result = js_CompareStrings(astr, bstr);
             else
                 ok = JS_FALSE;
         }
     } else {
+        jsval *invokevp, *sp;
         jsdouble cmp;
-        jsval argv[2];
 
-        argv[0] = av;
-        argv[1] = bv;
-        ok = js_InternalCall(cx,
-                             OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fval)),
-                             fval, 2, argv, ca->localroot);
+        invokevp = ca->elemroot;
+        sp = invokevp;
+        *sp++ = ca->fval;
+        *sp++ = JSVAL_NULL;
+        *sp++ = av;
+        *sp++ = bv;
+
+        ok = js_Invoke(cx, 2, invokevp, JSINVOKE_INTERNAL);
         if (ok) {
-            ok = js_ValueToNumber(cx, *ca->localroot, &cmp);
+            ok = js_ValueToNumber(cx, *invokevp, &cmp);
 
             /* Clamp cmp to -1, 0, 1. */
             if (ok) {
                 if (JSDOUBLE_IS_NaN(cmp)) {
                     /*
                      * XXX report some kind of error here?  ECMA talks about
                      * 'consistent compare functions' that don't return NaN,
                      * but is silent about what the result should be.  So we
@@ -1216,23 +1220,31 @@ array_sort(JSContext *cx, uintN argc, js
     memset(mergesort_tmp, 0, newlen * sizeof(jsval));
     tvr.count = newlen * 2;
 
     /* Here len == 2 * (newlen + undefs + number_of_holes). */
     if (all_strings) {
         ok = js_MergeSort(vec, (size_t) newlen, sizeof(jsval),
                           sort_compare_strings, cx, mergesort_tmp);
     } else {
+        void *mark;
+
         ca.context = cx;
         ca.fval = fval;
         /* local GC root for temporary string */
         ca.localroot = &vec[tvr.count++];
         *ca.localroot = JSVAL_NULL;
+        ca.elemroot  = js_AllocStack(cx, 2 + 2, &mark);
+        if (!ca.elemroot) {
+            ok = JS_FALSE;
+            goto out;
+        }
         ok = js_MergeSort(vec, (size_t) newlen, sizeof(jsval),
                           sort_compare, &ca, mergesort_tmp);
+        js_FreeStack(cx, mark);
     }
     if (!ok)
         goto out;
 
     ok = InitArrayElements(cx, obj, 0, newlen, vec);
     if (!ok)
         goto out;