Backed out changesets fe340da3fb4c and 076426ec9ed6 (bug 1112537) for jit-test failures on OSX and Win8.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 20 Jan 2015 17:30:49 -0500
changeset 251885 c8b693e4b0de9477b0c33c9d852118de201ab48c
parent 251884 68fee019fc009389826888566a53dea570b6a53d
child 251886 92dcd34c8aa12103e0173645f09d6fa0dacfa9fd
child 251927 5002e9c06365c09ab2d32ae06f63047c38c8a960
push id4610
push userjlund@mozilla.com
push dateMon, 30 Mar 2015 18:32:55 +0000
treeherdermozilla-beta@4df54044d9ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1112537
milestone38.0a1
backs outfe340da3fb4cd9fc0c2c5fa97ea5ed94396ea3ff
076426ec9ed6b4eff880cf5367af77ca7a8d6701
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
Backed out changesets fe340da3fb4c and 076426ec9ed6 (bug 1112537) for jit-test failures on OSX and Win8.
js/src/jit-test/tests/ion/bug977966.js
js/src/jit/CodeGenerator.cpp
js/src/jit/MIR.cpp
js/src/jit/MIR.h
js/src/jsarray.cpp
js/src/jsstr.cpp
js/src/jsstr.h
--- a/js/src/jit-test/tests/ion/bug977966.js
+++ b/js/src/jit-test/tests/ion/bug977966.js
@@ -67,50 +67,16 @@ function myjoin(i, x) {
 
 function split_join_4(i) {
     var x = (i + "-" + i).split("-");
     var res = myjoin(i, x);
     assertEq(res, i + "->" + i);
     return i;
 }
 
-function split_join_5(i) {
-    var s = "abca";
-    assertEq(s.split("a").join("") + i, "bc" + i);
-}
-
-function split_join_two_byte_char(i) {
-    var s1 = "ab";
-    assertEq(s1.split("").join("\u03c0"), "a\u03c0b");
-    var s2 = i + "\u03c0" + i;
-    assertEq(s2.split("\u03c0").join("-"), i + "-" + i);
-}
-
-if (getBuildConfiguration()['asan']) {
-    function split_join_overflow() {}
-} else {
-    function split_join_overflow()
-    {
-        try {
-            var s = "  ";
-            for (var i = 1; i < 10; i++)
-                s = s.split("").join(s); // 2^(2^i)
-        } catch (exn) {
-            if (exn != "out of memory")
-                assertEq(exn instanceof InternalError, true);
-        };
-    }
-}
-
-function split_join_underflow(i)
-{
-    var s = "";
-    assertEq(s.split("").join("x" + i), "");
-}
-
 // Check that we do not consider the string argument of join as a replacement
 // pattern, as the string replace primitive is supposed to do.
 function split_join_pattern(i) {
     var s = i + "-" + i;
     assertEq(s.split("-").join("$`$&$'"), i + "$`$&$'" + i);
     assertEq(s.replace("-", "$`$&$'"), "" + i + i + "-" + i + i);
 }
 
@@ -133,17 +99,11 @@ function split_join_multiple(i) {
 for (var i = 0; i < 100; ++i) {
     join_check(i);
     split(i);
     join(i);
     split_join(i);
     split_join_2(i);
     split_join_3(i);
     split_join_4(i);
-    split_join_5(i);
     split_join_pattern(i);
     split_join_multiple(i);
-    split_join_two_byte_char(i);
-    split_join_underflow(i);
 }
-
-for (var i = 0; i < 5; i++)
-   split_join_overflow();
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -1629,17 +1629,16 @@ CodeGenerator::visitRegExpReplace(LRegEx
         pushArg(ImmGCPtr(lir->string()->toConstant()->toString()));
     else
         pushArg(ToRegister(lir->string()));
 
     callVM(RegExpReplaceInfo, lir);
 }
 
 typedef JSString *(*StringReplaceFn)(JSContext *, HandleString, HandleString, HandleString);
-static const VMFunction StringFlatReplaceInfo = FunctionInfo<StringReplaceFn>(js::str_flat_replace_string);
 static const VMFunction StringReplaceInfo = FunctionInfo<StringReplaceFn>(StringReplace);
 
 void
 CodeGenerator::visitStringReplace(LStringReplace *lir)
 {
     if (lir->replacement()->isConstant())
         pushArg(ImmGCPtr(lir->replacement()->toConstant()->toString()));
     else
@@ -1650,19 +1649,16 @@ CodeGenerator::visitStringReplace(LStrin
     else
         pushArg(ToRegister(lir->pattern()));
 
     if (lir->string()->isConstant())
         pushArg(ImmGCPtr(lir->string()->toConstant()->toString()));
     else
         pushArg(ToRegister(lir->string()));
 
-    if (lir->mir()->isFlatReplacement())
-        return callVM(StringFlatReplaceInfo, lir);
-
     callVM(StringReplaceInfo, lir);
 }
 
 typedef JSObject *(*LambdaFn)(JSContext *, HandleFunction, HandleObject);
 static const VMFunction LambdaInfo = FunctionInfo<LambdaFn>(js::Lambda);
 
 void
 CodeGenerator::visitLambdaForSingleton(LLambdaForSingleton *lir)
@@ -5900,16 +5896,17 @@ typedef JSObject *(*StringSplitFn)(JSCon
 static const VMFunction StringSplitInfo = FunctionInfo<StringSplitFn>(js::str_split_string);
 
 void
 CodeGenerator::visitStringSplit(LStringSplit *lir)
 {
     pushArg(ToRegister(lir->separator()));
     pushArg(ToRegister(lir->string()));
     pushArg(ImmGCPtr(lir->mir()->typeObject()));
+
     callVM(StringSplitInfo, lir);
 }
 
 void
 CodeGenerator::visitInitializedLength(LInitializedLength *lir)
 {
     Address initLength(ToRegister(lir->elements()), ObjectElements::offsetOfInitializedLength());
     masm.load32(initLength, ToRegister(lir->output()));
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -4071,42 +4071,42 @@ MTableSwitch::foldsTo(TempAllocator &all
     // the only successor.
     if (numSuccessors() == 1 || (op->type() != MIRType_Value && !IsNumberType(op->type())))
         return MGoto::New(alloc, getDefault());
 
     return this;
 }
 
 MDefinition *
-MArrayJoin::foldsTo(TempAllocator &alloc)
-{
+MArrayJoin::foldsTo(TempAllocator &alloc) {
+    // :TODO: Enable this optimization after fixing Bug 977966 test cases.
+    return this;
+
     MDefinition *arr = array();
 
     if (!arr->isStringSplit())
         return this;
 
-    setRecoveredOnBailout();
+    this->setRecoveredOnBailout();
     if (arr->hasLiveDefUses()) {
-        setNotRecoveredOnBailout();
+        this->setNotRecoveredOnBailout();
         return this;
     }
 
     // We're replacing foo.split(bar).join(baz) by
     // foo.replace(bar, baz).  MStringSplit could be recovered by
     // a bailout.  As we are removing its last use, and its result
     // could be captured by a resume point, this MStringSplit will
     // be executed on the bailout path.
     MDefinition *string = arr->toStringSplit()->string();
     MDefinition *pattern = arr->toStringSplit()->separator();
     MDefinition *replacement = sep();
 
     setNotRecoveredOnBailout();
-    MStringReplace *substr = MStringReplace::New(alloc, string, pattern, replacement);
-    substr->setFlatReplacement();
-    return substr;
+    return MStringReplace::New(alloc, string, pattern, replacement);
 }
 
 bool
 jit::ElementAccessIsDenseNative(types::CompilerConstraintList *constraints,
                                 MDefinition *obj, MDefinition *id)
 {
     if (obj->mightBeType(MIRType_String))
         return false;
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -6996,55 +6996,38 @@ class MRegExpReplace
     }
 };
 
 class MStringReplace
   : public MStrReplace< StringPolicy<1> >
 {
   private:
 
-    bool isFlatReplacement_;
-
     MStringReplace(MDefinition *string, MDefinition *pattern, MDefinition *replacement)
-      : MStrReplace< StringPolicy<1> >(string, pattern, replacement), isFlatReplacement_(false)
+      : MStrReplace< StringPolicy<1> >(string, pattern, replacement)
     {
     }
 
   public:
     INSTRUCTION_HEADER(StringReplace)
 
     static MStringReplace *New(TempAllocator &alloc, MDefinition *string, MDefinition *pattern, MDefinition *replacement) {
         return new(alloc) MStringReplace(string, pattern, replacement);
     }
 
-    void setFlatReplacement() {
-        MOZ_ASSERT(!isFlatReplacement_);
-        isFlatReplacement_ = true;
-    }
-
-    bool isFlatReplacement() const {
-        return isFlatReplacement_;
-    }
-
-    bool congruentTo(const MDefinition *ins) const MOZ_OVERRIDE {
-        if (!ins->isStringReplace())
-            return false;
-        if (isFlatReplacement_ != ins->toStringReplace()->isFlatReplacement_)
-            return false;
+    bool congruentTo(const MDefinition *ins) const MOZ_OVERRIDE {
         return congruentIfOperandsEqual(ins);
     }
 
     AliasSet getAliasSet() const MOZ_OVERRIDE {
         return AliasSet::None();
     }
 
     bool writeRecoverData(CompactBufferWriter &writer) const MOZ_OVERRIDE;
     bool canRecoverOnBailout() const MOZ_OVERRIDE {
-        if (isFlatReplacement_)
-            return false;
         if (pattern()->isRegExp())
             return !pattern()->toRegExp()->source()->global();
         return false;
     }
 };
 
 class MSubstr
   : public MTernaryInstruction,
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -2,17 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsarray.h"
 
 #include "mozilla/ArrayUtils.h"
-#include "mozilla/CheckedInt.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/MathAlgorithms.h"
 
 #include <algorithm>
 
 #include "jsapi.h"
 #include "jsatom.h"
@@ -44,17 +43,16 @@
 
 using namespace js;
 using namespace js::gc;
 using namespace js::types;
 
 using mozilla::Abs;
 using mozilla::ArrayLength;
 using mozilla::CeilingLog2;
-using mozilla::CheckedInt;
 using mozilla::DebugOnly;
 using mozilla::IsNaN;
 
 using JS::AutoCheckCannotGC;
 using JS::ToUint32;
 
 bool
 js::GetLengthProperty(JSContext *cx, HandleObject obj, uint32_t *lengthp)
@@ -1069,23 +1067,17 @@ js::ArrayJoin(JSContext *cx, HandleObjec
 
     StringBuffer sb(cx);
     if (sepstr->hasTwoByteChars() && !sb.ensureTwoByteChars())
         return nullptr;
 
     // The separator will be added |length - 1| times, reserve space for that
     // so that we don't have to unnecessarily grow the buffer.
     size_t seplen = sepstr->length();
-    CheckedInt<uint32_t> res = CheckedInt<uint32_t>(seplen) * (length - 1);
-    if (length > 0 && !res.isValid()) {
-        js_ReportAllocationOverflow(cx);
-        return nullptr;
-    }
-
-    if (length > 0 && !sb.reserve(res.value()))
+    if (length > 0 && !sb.reserve(seplen * (length - 1)))
         return nullptr;
 
     // Various optimized versions of steps 7-10.
     if (seplen == 0) {
         EmptySeparatorOp op;
         if (!ArrayJoinKernel<Locale>(cx, op, obj, length, sb))
             return nullptr;
     } else if (seplen == 1) {
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -3321,132 +3321,19 @@ StrReplaceString(JSContext *cx, ReplaceD
      */
     if (rdata.dollarIndex != UINT32_MAX)
         return BuildDollarReplacement(cx, rdata.str, rdata.repstr, rdata.dollarIndex, fm, rval);
     return BuildFlatReplacement(cx, rdata.str, rdata.repstr, fm, rval);
 }
 
 static const uint32_t ReplaceOptArg = 2;
 
-template <typename StrChar, typename RepChar>
-static bool
-StrFlatReplaceGlobal(JSContext *cx, JSLinearString *str, JSLinearString *pat, JSLinearString *rep,
-                     StringBuffer &sb)
-{
-    MOZ_ASSERT(str->length() > 0);
-
-    AutoCheckCannotGC nogc;
-    const StrChar *strChars = str->chars<StrChar>(nogc);
-    const RepChar *repChars = rep->chars<RepChar>(nogc);
-
-    // The pattern is empty, so we interleave the replacement string in-between
-    // each character.
-    if (!pat->length()) {
-        CheckedInt<uint32_t> strLength(str->length());
-        CheckedInt<uint32_t> repLength(rep->length());
-        CheckedInt<uint32_t> length = repLength * (strLength - 1) + strLength;
-        if (!length.isValid()) {
-            js_ReportAllocationOverflow(cx);
-            return false;
-        }
-
-        if (!sb.reserve(length.value()))
-            return false;
-
-        for (unsigned i = 0; i < str->length() - 1; ++i, ++strChars) {
-            sb.infallibleAppend(*strChars);
-            sb.infallibleAppend(repChars, rep->length());
-        }
-        sb.infallibleAppend(*strChars);
-        return true;
-    }
-
-    // If it's true, we are sure that the result's length is, at least, the same
-    // length as |str->length()|.
-    if (rep->length() >= pat->length()) {
-        if (!sb.reserve(str->length()))
-            return false;
-    }
-
-    uint32_t start = 0;
-    for (;;) {
-        int match = StringMatch(str, pat, start);
-        if (match < 0)
-            break;
-        if (!sb.append(strChars + start, match - start))
-            return false;
-        if (!sb.append(repChars, rep->length()))
-            return false;
-        start = match + pat->length();
-    }
-
-    if (!sb.append(strChars + start, str->length() - start))
-        return false;
-
-    return true;
-}
-
-// This is identical to "str.split(pattern).join(replacement)" except that we
-// do some deforestation optimization in Ion.
-JSString *
-js::str_flat_replace_string(JSContext *cx, HandleString string, HandleString pattern,
-                            HandleString replacement)
-{
-    MOZ_ASSERT(string);
-    MOZ_ASSERT(pattern);
-    MOZ_ASSERT(replacement);
-
-    if (!string->length())
-        return string;
-
-    RootedLinearString linearRepl(cx, replacement->ensureLinear(cx));
-    if (!linearRepl)
-        return nullptr;
-
-    RootedLinearString linearPat(cx, pattern->ensureLinear(cx));
-    if (!linearPat)
-        return nullptr;
-
-    RootedLinearString linearStr(cx, string->ensureLinear(cx));
-    if (!linearStr)
-        return nullptr;
-
-    StringBuffer sb(cx);
-    if (linearStr->hasTwoByteChars()) {
-        if (!sb.ensureTwoByteChars())
-            return nullptr;
-        if (linearRepl->hasTwoByteChars()) {
-            if (!StrFlatReplaceGlobal<char16_t, char16_t>(cx, linearStr, linearPat, linearRepl, sb))
-                return nullptr;
-        } else {
-            if (!StrFlatReplaceGlobal<char16_t, Latin1Char>(cx, linearStr, linearPat, linearRepl, sb))
-                return nullptr;
-        }
-    } else {
-        if (linearRepl->hasTwoByteChars()) {
-            if (!sb.ensureTwoByteChars())
-                return nullptr;
-            if (!StrFlatReplaceGlobal<Latin1Char, char16_t>(cx, linearStr, linearPat, linearRepl, sb))
-                return nullptr;
-        } else {
-            if (!StrFlatReplaceGlobal<Latin1Char, Latin1Char>(cx, linearStr, linearPat, linearRepl, sb))
-                return nullptr;
-        }
-    }
-
-    JSString *str = sb.finishString();
-    if (!str)
-        return nullptr;
-
-    return str;
-}
-
 bool
 js::str_replace_string_raw(JSContext *cx, HandleString string, HandleString pattern,
-                           HandleString replacement, MutableHandleValue rval)
+                          HandleString replacement, MutableHandleValue rval)
 {
     ReplaceData rdata(cx);
 
     rdata.str = string;
     JSLinearString *repl = replacement->ensureLinear(cx);
     if (!repl)
         return false;
     rdata.setReplacementString(repl);
--- a/js/src/jsstr.h
+++ b/js/src/jsstr.h
@@ -420,20 +420,16 @@ str_split_string(JSContext *cx, HandleTy
 
 bool
 str_resolve(JSContext *cx, HandleObject obj, HandleId id, bool *resolvedp);
 
 bool
 str_replace_regexp_raw(JSContext *cx, HandleString string, HandleObject regexp,
                        HandleString replacement, MutableHandleValue rval);
 
-JSString *
-str_flat_replace_string(JSContext *cx, HandleString string, HandleString pattern,
-                        HandleString replacement);
-
 bool
 str_replace_string_raw(JSContext *cx, HandleString string, HandleString pattern,
                        HandleString replacement, MutableHandleValue rval);
 
 } /* namespace js */
 
 extern bool
 js_String(JSContext *cx, unsigned argc, js::Value *vp);