Bug 883661 - Handle lazy functions when doing higher order fast invokes and in numeric comparator pattern matching, r=luke.
authorBrian Hackett <bhackett1024@gmail.com>
Mon, 17 Jun 2013 10:14:33 -0600
changeset 146795 849e6303ac21642973f3a2c43a68774e15777411
parent 146794 4319f2110d9015bfd655ddb690abd121d75b6481
child 146796 ccb80286042a2b2146ed362b466de468e1d58091
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs883661
milestone24.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 883661 - Handle lazy functions when doing higher order fast invokes and in numeric comparator pattern matching, r=luke.
js/src/jsarray.cpp
js/src/vm/Interpreter-inl.h
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -1497,40 +1497,44 @@ typedef bool (*ComparatorInt32)(const Va
 
 ComparatorInt32 SortComparatorInt32s[] = {
     NULL,
     ComparatorInt32LeftMinusRight,
     ComparatorInt32RightMinusLeft
 };
 
 enum ComparatorMatchResult {
-    Match_None = 0,
+    Match_Failure,
+    Match_None,
     Match_LeftMinusRight,
     Match_RightMinusLeft
 };
 
 /*
  * Specialize behavior for comparator functions with particular common bytecode
  * patterns: namely, |return x - y| and |return y - x|.
  */
 ComparatorMatchResult
-MatchNumericComparator(const Value &v)
+MatchNumericComparator(JSContext *cx, const Value &v)
 {
     if (!v.isObject())
         return Match_None;
 
     JSObject &obj = v.toObject();
     if (!obj.isFunction())
         return Match_None;
 
     JSFunction *fun = obj.toFunction();
-    if (!fun->hasScript())
+    if (!fun->isInterpreted())
         return Match_None;
 
-    JSScript *script = fun->nonLazyScript();
+    JSScript *script = fun->getOrCreateScript(cx);
+    if (!script)
+        return Match_Failure;
+
     jsbytecode *pc = script->code;
 
     uint16_t arg0, arg1;
     if (JSOp(*pc) != JSOP_GETARG)
         return Match_None;
     arg0 = GET_ARGNO(pc);
     pc += JSOP_GETARG_LENGTH;
 
@@ -1797,17 +1801,19 @@ js::array_sort(JSContext *cx, unsigned a
                                SortComparatorLexicographicInt32(cx))) {
                     return false;
                 }
             } else {
                 if (!SortLexicographically(cx, &vec, n))
                     return false;
             }
         } else {
-            ComparatorMatchResult comp = MatchNumericComparator(fval);
+            ComparatorMatchResult comp = MatchNumericComparator(cx, fval);
+            if (comp == Match_Failure)
+                return false;
 
             if (comp != Match_None) {
                 if (allInts) {
                     JS_ALWAYS_TRUE(vec.resize(n * 2));
                     if (!MergeSort(vec.begin(), n, vec.begin() + n, SortComparatorInt32s[comp]))
                         return false;
                 } else {
                     if (!SortNumerically(cx, &vec, n, comp))
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -1125,30 +1125,33 @@ class FastInvokeGuard
     {
         JS_ASSERT(!InParallelSection());
         initFunction(fval);
     }
 
     void initFunction(const Value &fval) {
         if (fval.isObject() && fval.toObject().isFunction()) {
             JSFunction *fun = fval.toObject().toFunction();
-            if (fun->hasScript()) {
+            if (fun->isInterpreted())
                 fun_ = fun;
-                script_ = fun->nonLazyScript();
-            }
         }
     }
 
     InvokeArgsGuard &args() {
         return args_;
     }
 
     bool invoke(JSContext *cx) {
 #ifdef JS_ION
         if (useIon_ && fun_) {
+            if (!script_) {
+                script_ = fun_->getOrCreateScript(cx);
+                if (!script_)
+                    return false;
+            }
             if (ictx_.empty())
                 ictx_.construct(cx, (js::ion::TempAllocator *)NULL);
             JS_ASSERT(fun_->nonLazyScript() == script_);
 
             ion::MethodStatus status = ion::CanEnterUsingFastInvoke(cx, script_, args_.length());
             if (status == ion::Method_Error)
                 return false;
             if (status == ion::Method_Compiled) {