Bug 1379980 - Clean up RegExp code a bit. r=jonco
☠☠ backed out by d63c9e7de4c5 ☠ ☠
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 11 Jul 2017 16:46:36 +0200
changeset 368347 32a13d3e29024cc846725deaddf52dd9eb5de13d
parent 368346 a247dfbbc96f9d5de997fca7ebe73ad8ea533211
child 368348 d63c9e7de4c54fd8e81c73cb2414e9125585e18e
push id32162
push usercbook@mozilla.com
push dateWed, 12 Jul 2017 09:07:26 +0000
treeherdermozilla-central@09a4282d1172 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1379980
milestone56.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 1379980 - Clean up RegExp code a bit. r=jonco
js/src/builtin/ReflectParse.cpp
js/src/builtin/RegExp.cpp
js/src/jit/BaselineCompiler.cpp
js/src/jit/CodeGenerator.cpp
js/src/jit/VMFunctions.h
js/src/vm/Interpreter.cpp
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpObject.h
--- a/js/src/builtin/ReflectParse.cpp
+++ b/js/src/builtin/ReflectParse.cpp
@@ -3267,17 +3267,17 @@ ASTSerializer::literal(ParseNode* pn, Mu
         val.setString(pn->pn_atom);
         break;
 
       case PNK_REGEXP:
       {
         RootedObject re1(cx, pn->as<RegExpLiteral>().objbox()->object);
         LOCAL_ASSERT(re1 && re1->is<RegExpObject>());
 
-        RootedObject re2(cx, CloneRegExpObject(cx, re1));
+        RootedObject re2(cx, CloneRegExpObject(cx, re1.as<RegExpObject>()));
         if (!re2)
             return false;
 
         val.setObject(*re2);
         break;
       }
 
       case PNK_NUMBER:
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -537,17 +537,17 @@ js::regexp_construct_raw_flags(JSContext
     RootedAtom sourceAtom(cx, AtomizeString(cx, args[0].toString()));
     if (!sourceAtom)
         return false;
 
     // Step 4.c.
     int32_t flags = int32_t(args[1].toNumber());
 
     // Step 7.
-    Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, GenericObject));
+    RegExpObject* regexp = RegExpAlloc(cx, GenericObject);
     if (!regexp)
         return false;
 
     // Step 8.
     regexp->initAndZeroLastIndex(sourceAtom, RegExpFlag(flags), cx);
     args.rval().setObject(*regexp);
     return true;
 }
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -1693,17 +1693,17 @@ BaselineCompiler::emit_JSOP_CALLSITEOBJ(
 
     if (!cx->compartment()->getTemplateLiteralObject(cx, raw, &cso))
         return false;
 
     frame.push(ObjectValue(*cso));
     return true;
 }
 
-typedef JSObject* (*CloneRegExpObjectFn)(JSContext*, JSObject*);
+typedef JSObject* (*CloneRegExpObjectFn)(JSContext*, Handle<RegExpObject*>);
 static const VMFunction CloneRegExpObjectInfo =
     FunctionInfo<CloneRegExpObjectFn>(CloneRegExpObject, "CloneRegExpObject");
 
 bool
 BaselineCompiler::emit_JSOP_REGEXP()
 {
     RootedObject reObj(cx, script->getRegExp(pc));
 
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -1129,17 +1129,17 @@ CodeGenerator::visitValueToObjectOrNull(
     masm.branchTestNull(Assembler::NotEqual, input, ool->entry());
 
     masm.bind(&done);
     masm.unboxNonDouble(input, output);
 
     masm.bind(ool->rejoin());
 }
 
-typedef JSObject* (*CloneRegExpObjectFn)(JSContext*, JSObject*);
+typedef JSObject* (*CloneRegExpObjectFn)(JSContext*, Handle<RegExpObject*>);
 static const VMFunction CloneRegExpObjectInfo =
     FunctionInfo<CloneRegExpObjectFn>(CloneRegExpObject, "CloneRegExpObject");
 
 void
 CodeGenerator::visitRegExp(LRegExp* lir)
 {
     Register output = ToRegister(lir->output());
     Register temp = ToRegister(lir->temp());
--- a/js/src/jit/VMFunctions.h
+++ b/js/src/jit/VMFunctions.h
@@ -16,16 +16,17 @@
 #include "vm/Interpreter.h"
 
 namespace js {
 
 class NamedLambdaObject;
 class WithScope;
 class InlineTypedObject;
 class GeneratorObject;
+class RegExpObject;
 class TypedArrayObject;
 
 namespace jit {
 
 enum DataType {
     Type_Void,
     Type_Bool,
     Type_Int32,
@@ -334,16 +335,19 @@ template <> struct TypeToArgProperties<H
     static const uint32_t result = TypeToArgProperties<ArrayObject*>::result | VMFunction::ByRef;
 };
 template <> struct TypeToArgProperties<Handle<GeneratorObject*> > {
     static const uint32_t result = TypeToArgProperties<GeneratorObject*>::result | VMFunction::ByRef;
 };
 template <> struct TypeToArgProperties<Handle<PlainObject*> > {
     static const uint32_t result = TypeToArgProperties<PlainObject*>::result | VMFunction::ByRef;
 };
+template <> struct TypeToArgProperties<Handle<RegExpObject*> > {
+    static const uint32_t result = TypeToArgProperties<RegExpObject*>::result | VMFunction::ByRef;
+};
 template <> struct TypeToArgProperties<Handle<WithScope*> > {
     static const uint32_t result = TypeToArgProperties<WithScope*>::result | VMFunction::ByRef;
 };
 template <> struct TypeToArgProperties<Handle<LexicalScope*> > {
     static const uint32_t result = TypeToArgProperties<LexicalScope*>::result | VMFunction::ByRef;
 };
 template <> struct TypeToArgProperties<Handle<Scope*> > {
     static const uint32_t result = TypeToArgProperties<Scope*>::result | VMFunction::ByRef;
@@ -420,16 +424,19 @@ template <> struct TypeToRootType<Handle
     static const uint32_t result = VMFunction::RootObject;
 };
 template <> struct TypeToRootType<Handle<GeneratorObject*> > {
     static const uint32_t result = VMFunction::RootObject;
 };
 template <> struct TypeToRootType<Handle<PlainObject*> > {
     static const uint32_t result = VMFunction::RootObject;
 };
+template <> struct TypeToRootType<Handle<RegExpObject*> > {
+    static const uint32_t result = VMFunction::RootObject;
+};
 template <> struct TypeToRootType<Handle<LexicalScope*> > {
     static const uint32_t result = VMFunction::RootCell;
 };
 template <> struct TypeToRootType<Handle<WithScope*> > {
     static const uint32_t result = VMFunction::RootCell;
 };
 template <> struct TypeToRootType<Handle<Scope*> > {
     static const uint32_t result = VMFunction::RootCell;
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -3304,17 +3304,18 @@ CASE(JSOP_CALLSITEOBJ)
 END_CASE(JSOP_CALLSITEOBJ)
 
 CASE(JSOP_REGEXP)
 {
     /*
      * Push a regexp object cloned from the regexp literal object mapped by the
      * bytecode at pc.
      */
-    JSObject* obj = CloneRegExpObject(cx, script->getRegExp(REGS.pc));
+    ReservedRooted<JSObject*> re(&rootObject0, script->getRegExp(REGS.pc));
+    JSObject* obj = CloneRegExpObject(cx, re.as<RegExpObject>());
     if (!obj)
         goto error;
     PUSH_OBJECT(*obj);
 }
 END_CASE(JSOP_REGEXP)
 
 CASE(JSOP_ZERO)
     PUSH_INT32(0);
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -291,28 +291,28 @@ RegExpObject::assignInitialShape(JSConte
     JS_STATIC_ASSERT(LAST_INDEX_SLOT == 0);
 
     /* The lastIndex property alone is writable but non-configurable. */
     return NativeObject::addDataProperty(cx, self, cx->names().lastIndex, LAST_INDEX_SLOT,
                                          JSPROP_PERMANENT);
 }
 
 void
-RegExpObject::initIgnoringLastIndex(HandleAtom source, RegExpFlag flags)
+RegExpObject::initIgnoringLastIndex(JSAtom* source, RegExpFlag flags)
 {
     // If this is a re-initialization with an existing RegExpShared, 'flags'
     // may not match getShared()->flags, so forget the RegExpShared.
-    NativeObject::setPrivate(nullptr);
+    sharedRef() = nullptr;
 
     setSource(source);
     setFlags(flags);
 }
 
 void
-RegExpObject::initAndZeroLastIndex(HandleAtom source, RegExpFlag flags, JSContext* cx)
+RegExpObject::initAndZeroLastIndex(JSAtom* source, RegExpFlag flags, JSContext* cx)
 {
     initIgnoringLastIndex(source, flags);
     zeroLastIndex(cx);
 }
 
 static MOZ_ALWAYS_INLINE bool
 IsLineTerminator(const JS::Latin1Char c)
 {
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -43,19 +43,18 @@ struct MatchPair;
 class MatchPairs;
 class RegExpStatics;
 
 namespace frontend { class TokenStream; }
 
 extern RegExpObject*
 RegExpAlloc(JSContext* cx, NewObjectKind newKind, HandleObject proto = nullptr);
 
-// |regexp| is under-typed because this function's used in the JIT.
 extern JSObject*
-CloneRegExpObject(JSContext* cx, JSObject* regexp);
+CloneRegExpObject(JSContext* cx, Handle<RegExpObject*> regex);
 
 class RegExpObject : public NativeObject
 {
     static const unsigned LAST_INDEX_SLOT          = 0;
     static const unsigned SOURCE_SLOT              = 1;
     static const unsigned FLAGS_SLOT               = 2;
 
     static_assert(RegExpObject::FLAGS_SLOT == REGEXP_FLAGS_SLOT,
@@ -158,22 +157,22 @@ class RegExpObject : public NativeObject
     PreBarriered<RegExpShared*>& sharedRef() {
         auto& ref = NativeObject::privateRef(PRIVATE_SLOT);
         return reinterpret_cast<PreBarriered<RegExpShared*>&>(ref);
     }
 
     static void trace(JSTracer* trc, JSObject* obj);
     void trace(JSTracer* trc);
 
-    void initIgnoringLastIndex(HandleAtom source, RegExpFlag flags);
+    void initIgnoringLastIndex(JSAtom* source, RegExpFlag flags);
 
     // NOTE: This method is *only* safe to call on RegExps that haven't been
     //       exposed to script, because it requires that the "lastIndex"
     //       property be writable.
-    void initAndZeroLastIndex(HandleAtom source, RegExpFlag flags, JSContext* cx);
+    void initAndZeroLastIndex(JSAtom* source, RegExpFlag flags, JSContext* cx);
 
 #ifdef DEBUG
     static MOZ_MUST_USE bool dumpBytecode(JSContext* cx, Handle<RegExpObject*> regexp,
                                           bool match_only, HandleLinearString input);
 #endif
 
   private:
     /*