Backed out changeset c3861ac69c78 (bug 1324810) for failing RegExp/RegExpExec-exec.js. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Wed, 21 Dec 2016 21:07:45 +0100
changeset 326967 3f3ea09dd51190713ed8023d3f7543ad5bf7fa90
parent 326966 b6fc4e878493f949125b6adae8a7b0ed1628d44f
child 326968 8303c228d2d9d5c0bb314e1ae1190c2a874f3849
push id31116
push userkwierso@gmail.com
push dateFri, 23 Dec 2016 02:37:16 +0000
treeherdermozilla-central@2785aaf276ba [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1324810
milestone53.0a1
backs outc3861ac69c78994cf478e07ce467880f881d7a45
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 changeset c3861ac69c78 (bug 1324810) for failing RegExp/RegExpExec-exec.js. r=backout
js/src/builtin/RegExp.cpp
js/src/builtin/RegExp.h
js/src/jit/CodeGenerator.cpp
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -1574,135 +1574,174 @@ js::GetFirstDollarIndexRaw(JSContext* cx
 
 bool
 js::RegExpPrototypeOptimizable(JSContext* cx, unsigned argc, Value* vp)
 {
     // This can only be called from self-hosted code.
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 1);
 
-    args.rval().setBoolean(RegExpPrototypeOptimizableRaw(cx, &args[0].toObject()));
+    uint8_t result = false;
+    if (!RegExpPrototypeOptimizableRaw(cx, &args[0].toObject(), &result))
+        return false;
+
+    args.rval().setBoolean(result);
     return true;
 }
 
 bool
-js::RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto)
+js::RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto, uint8_t* result)
 {
     JS::AutoCheckCannotGC nogc;
-    AutoAssertNoPendingException aanpe(cx);
-    if (!proto->isNative())
-        return false;
+    if (!proto->isNative()) {
+        *result = false;
+        return true;
+    }
 
     NativeObject* nproto = static_cast<NativeObject*>(proto);
 
     Shape* shape = cx->compartment()->regExps.getOptimizableRegExpPrototypeShape();
-    if (shape == nproto->lastProperty())
+    if (shape == nproto->lastProperty()) {
+        *result = true;
         return true;
+    }
 
     JSFunction* flagsGetter;
     if (!GetOwnGetterPure(cx, proto, NameToId(cx->names().flags), &flagsGetter))
         return false;
 
-    if (!flagsGetter)
-        return false;
+    if (!flagsGetter) {
+        *result = false;
+        return true;
+    }
 
-    if (!IsSelfHostedFunctionWithName(flagsGetter, cx->names().RegExpFlagsGetter))
-        return false;
+    if (!IsSelfHostedFunctionWithName(flagsGetter, cx->names().RegExpFlagsGetter)) {
+        *result = false;
+        return true;
+    }
 
     JSNative globalGetter;
     if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().global), &globalGetter))
         return false;
 
-    if (globalGetter != regexp_global)
-        return false;
+    if (globalGetter != regexp_global) {
+        *result = false;
+        return true;
+    }
 
     JSNative ignoreCaseGetter;
     if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().ignoreCase), &ignoreCaseGetter))
         return false;
 
-    if (ignoreCaseGetter != regexp_ignoreCase)
-        return false;
+    if (ignoreCaseGetter != regexp_ignoreCase) {
+        *result = false;
+        return true;
+    }
 
     JSNative multilineGetter;
     if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().multiline), &multilineGetter))
         return false;
 
-    if (multilineGetter != regexp_multiline)
-        return false;
+    if (multilineGetter != regexp_multiline) {
+        *result = false;
+        return true;
+    }
 
     JSNative stickyGetter;
     if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().sticky), &stickyGetter))
         return false;
 
-    if (stickyGetter != regexp_sticky)
-        return false;
+    if (stickyGetter != regexp_sticky) {
+        *result = false;
+        return true;
+    }
 
     JSNative unicodeGetter;
     if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().unicode), &unicodeGetter))
         return false;
 
-    if (unicodeGetter != regexp_unicode)
-        return false;
+    if (unicodeGetter != regexp_unicode) {
+        *result = false;
+        return true;
+    }
 
     // Check if @@match, @@search, and exec are own data properties,
     // those values should be tested in selfhosted JS.
     bool has = false;
     if (!HasOwnDataPropertyPure(cx, proto, SYMBOL_TO_JSID(cx->wellKnownSymbols().match), &has))
         return false;
-    if (!has)
-        return false;
+    if (!has) {
+        *result = false;
+        return true;
+    }
 
     if (!HasOwnDataPropertyPure(cx, proto, SYMBOL_TO_JSID(cx->wellKnownSymbols().search), &has))
         return false;
-    if (!has)
-        return false;
+    if (!has) {
+        *result = false;
+        return true;
+    }
 
     if (!HasOwnDataPropertyPure(cx, proto, NameToId(cx->names().exec), &has))
         return false;
-    if (!has)
-        return false;
+    if (!has) {
+        *result = false;
+        return true;
+    }
 
     cx->compartment()->regExps.setOptimizableRegExpPrototypeShape(nproto->lastProperty());
+    *result = true;
     return true;
 }
 
 bool
 js::RegExpInstanceOptimizable(JSContext* cx, unsigned argc, Value* vp)
 {
     // This can only be called from self-hosted code.
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 2);
 
-    args.rval().setBoolean(RegExpInstanceOptimizableRaw(cx, &args[0].toObject(),
-                                                        &args[1].toObject()));
+    uint8_t result = false;
+    if (!RegExpInstanceOptimizableRaw(cx, &args[0].toObject(), &args[1].toObject(), &result))
+        return false;
+
+    args.rval().setBoolean(result);
     return true;
 }
 
 bool
-js::RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto)
+js::RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto, uint8_t* result)
 {
     JS::AutoCheckCannotGC nogc;
-    AutoAssertNoPendingException aanpe(cx);
 
     RegExpObject* rx = &obj->as<RegExpObject>();
 
     Shape* shape = cx->compartment()->regExps.getOptimizableRegExpInstanceShape();
-    if (shape == rx->lastProperty())
+    if (shape == rx->lastProperty()) {
+        *result = true;
         return true;
+    }
 
-    if (!rx->hasStaticPrototype())
-        return false;
+    if (!rx->hasStaticPrototype()) {
+        *result = false;
+        return true;
+    }
 
-    if (rx->staticPrototype() != proto)
-        return false;
+    if (rx->staticPrototype() != proto) {
+        *result = false;
+        return true;
+    }
 
-    if (!RegExpObject::isInitialShape(rx))
-        return false;
+    if (!RegExpObject::isInitialShape(rx)) {
+        *result = false;
+        return true;
+    }
 
     cx->compartment()->regExps.setOptimizableRegExpInstanceShape(rx->lastProperty());
+    *result = true;
     return true;
 }
 
 /*
  * Pattern match the script to check if it is is indexing into a particular
  * object, e.g. 'function(a) { return b[a]; }'. Avoid calling the script in
  * such cases, which are used by javascript packers (particularly the popular
  * Dean Edwards packer) to efficiently encode large scripts. We only handle the
--- a/js/src/builtin/RegExp.h
+++ b/js/src/builtin/RegExp.h
@@ -108,23 +108,23 @@ IsRegExp(JSContext* cx, HandleValue valu
 
 extern MOZ_MUST_USE bool
 RegExpCreate(JSContext* cx, HandleValue pattern, HandleValue flags, MutableHandleValue rval);
 
 extern MOZ_MUST_USE bool
 RegExpPrototypeOptimizable(JSContext* cx, unsigned argc, Value* vp);
 
 extern MOZ_MUST_USE bool
-RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto);
+RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto, uint8_t* result);
 
 extern MOZ_MUST_USE bool
 RegExpInstanceOptimizable(JSContext* cx, unsigned argc, Value* vp);
 
 extern MOZ_MUST_USE bool
-RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto);
+RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto, uint8_t* result);
 
 extern MOZ_MUST_USE bool
 RegExpGetSubstitution(JSContext* cx, HandleLinearString matched, HandleLinearString string,
                       size_t position, HandleObject capturesObj, HandleLinearString replacement,
                       size_t firstDollarIndex, MutableHandleValue rval);
 
 extern MOZ_MUST_USE bool
 GetFirstDollarIndex(JSContext* cx, unsigned argc, Value* vp);
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -2117,25 +2117,33 @@ CodeGenerator::visitRegExpPrototypeOptim
 }
 
 void
 CodeGenerator::visitOutOfLineRegExpPrototypeOptimizable(OutOfLineRegExpPrototypeOptimizable* ool)
 {
     LRegExpPrototypeOptimizable* ins = ool->ins();
     Register object = ToRegister(ins->object());
     Register output = ToRegister(ins->output());
+    Register temp = ToRegister(ins->temp());
 
     saveVolatile(output);
 
+    masm.reserveStack(sizeof(void*));
+    masm.moveStackPtrTo(temp);
+
     masm.setupUnalignedABICall(output);
     masm.loadJSContext(output);
     masm.passABIArg(output);
     masm.passABIArg(object);
+    masm.passABIArg(temp);
     masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, RegExpPrototypeOptimizableRaw));
-    masm.storeCallResult(output);
+    masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel());
+
+    masm.load8ZeroExtend(Address(masm.getStackPointer(), 0), output);
+    masm.freeStack(sizeof(void*));
 
     restoreVolatile(output);
 
     masm.jump(ool->rejoin());
 }
 
 class OutOfLineRegExpInstanceOptimizable : public OutOfLineCodeBase<CodeGenerator>
 {
@@ -2179,26 +2187,34 @@ CodeGenerator::visitRegExpInstanceOptimi
 
 void
 CodeGenerator::visitOutOfLineRegExpInstanceOptimizable(OutOfLineRegExpInstanceOptimizable* ool)
 {
     LRegExpInstanceOptimizable* ins = ool->ins();
     Register object = ToRegister(ins->object());
     Register proto = ToRegister(ins->proto());
     Register output = ToRegister(ins->output());
+    Register temp = ToRegister(ins->temp());
 
     saveVolatile(output);
 
+    masm.reserveStack(sizeof(void*));
+    masm.moveStackPtrTo(temp);
+
     masm.setupUnalignedABICall(output);
     masm.loadJSContext(output);
     masm.passABIArg(output);
     masm.passABIArg(object);
     masm.passABIArg(proto);
+    masm.passABIArg(temp);
     masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, RegExpInstanceOptimizableRaw));
-    masm.storeCallResult(output);
+    masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel());
+
+    masm.load8ZeroExtend(Address(masm.getStackPointer(), 0), output);
+    masm.freeStack(sizeof(void*));
 
     restoreVolatile(output);
 
     masm.jump(ool->rejoin());
 }
 
 static void
 FindFirstDollarIndex(MacroAssembler& masm, Register str, Register len, Register chars,