Bug 1184945: Increase the default MatchResult size of a regexp, r=bhackett
authorHannes Verschore <hv1989@gmail.com>
Wed, 22 Jul 2015 10:09:35 +0200
changeset 254134 066e0b4423c9d2170f57f342a75fe30ad552d873
parent 254133 97a66defe146a7ebca16ac9b075c4026d30b6cf1
child 254135 245b24210e41d2f7197a78302431144a01cbd0a0
push id29090
push userryanvm@gmail.com
push dateWed, 22 Jul 2015 20:34:12 +0000
treeherdermozilla-central@8650fe82f1cd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs1184945
milestone42.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 1184945: Increase the default MatchResult size of a regexp, r=bhackett
js/src/jit/CodeGenerator.cpp
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpObject.h
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -1003,23 +1003,20 @@ static const VMFunction CloneRegExpObjec
 
 void
 CodeGenerator::visitRegExp(LRegExp* lir)
 {
     pushArg(ImmGCPtr(lir->mir()->source()));
     callVM(CloneRegExpObjectInfo, lir);
 }
 
-// The maximum number of pairs we can handle when executing RegExps inline.
-static const size_t RegExpMaxPairCount = 6;
-
 // Amount of space to reserve on the stack when executing RegExps inline.
 static const size_t RegExpReservedStack = sizeof(irregexp::InputOutputData)
                                         + sizeof(MatchPairs)
-                                        + RegExpMaxPairCount * sizeof(MatchPair);
+                                        + RegExpObject::MaxPairCount * sizeof(MatchPair);
 
 static size_t
 RegExpPairsVectorStartOffset(size_t inputOutputDataStartOffset)
 {
     return inputOutputDataStartOffset + sizeof(irregexp::InputOutputData) + sizeof(MatchPairs);
 }
 
 static Address
@@ -1088,17 +1085,17 @@ PrepareAndExecuteRegExp(JSContext* cx, M
 
     // Don't handle RegExps which read and write to lastIndex.
     masm.branchTest32(Assembler::NonZero, Address(temp1, RegExpShared::offsetOfFlags()),
                       Imm32(StickyFlag | GlobalFlag), failure);
 
     if (mode == RegExpShared::Normal) {
         // Don't handle RegExps with excessive parens.
         masm.load32(Address(temp1, RegExpShared::offsetOfParenCount()), temp2);
-        masm.branch32(Assembler::AboveOrEqual, temp2, Imm32(RegExpMaxPairCount), failure);
+        masm.branch32(Assembler::AboveOrEqual, temp2, Imm32(RegExpObject::MaxPairCount), failure);
 
         // Fill in the paren count in the MatchPairs on the stack.
         masm.add32(Imm32(1), temp2);
         masm.store32(temp2, pairCountAddress);
     }
 
     // Load the code pointer for the type of input string we have, and compute
     // the input start/end pointers in the InputOutputData.
@@ -1337,17 +1334,17 @@ JitCompartment::generateRegExpExecStub(J
     Register temp4 = regs.takeAny();
 
     ArrayObject* templateObject = cx->compartment()->regExps.getOrCreateMatchResultTemplateObject(cx);
     if (!templateObject)
         return nullptr;
 
     // The template object should have enough space for the maximum number of
     // pairs this stub can handle.
-    MOZ_ASSERT(ObjectElements::VALUES_PER_HEADER + RegExpMaxPairCount ==
+    MOZ_ASSERT(ObjectElements::VALUES_PER_HEADER + RegExpObject::MaxPairCount ==
                gc::GetGCKindSlots(templateObject->asTenured().getAllocKind()));
 
     MacroAssembler masm(cx);
 
     // The InputOutputData is placed above the return address on the stack.
     size_t inputOutputDataStartOffset = sizeof(void*);
 
     Label notFound, oolEntry;
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -820,17 +820,18 @@ RegExpCompartment::~RegExpCompartment()
 }
 
 ArrayObject*
 RegExpCompartment::createMatchResultTemplateObject(JSContext* cx)
 {
     MOZ_ASSERT(!matchResultTemplateObject_);
 
     /* Create template array object */
-    RootedArrayObject templateObject(cx, NewDenseUnallocatedArray(cx, 0, nullptr, TenuredObject));
+    RootedArrayObject templateObject(cx, NewDenseUnallocatedArray(cx, RegExpObject::MaxPairCount,
+                                     nullptr, TenuredObject));
     if (!templateObject)
         return matchResultTemplateObject_; // = nullptr
 
     // Create a new group for the template.
     Rooted<TaggedProto> proto(cx, templateObject->getTaggedProto());
     ObjectGroup* group = ObjectGroupCompartment::makeGroup(cx, templateObject->getClass(), proto);
     if (!group)
         return matchResultTemplateObject_; // = nullptr
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -355,16 +355,20 @@ class RegExpObject : public NativeObject
     static const unsigned STICKY_FLAG_SLOT         = 5;
 
   public:
     static const unsigned RESERVED_SLOTS = 6;
     static const unsigned PRIVATE_SLOT = 7;
 
     static const Class class_;
 
+    // The maximum number of pairs a MatchResult can have, without having to
+    // allocate a bigger MatchResult.
+    static const size_t MaxPairCount = 14;
+
     /*
      * Note: The regexp statics flags are OR'd into the provided flags,
      * so this function is really meant for object creation during code
      * execution, as opposed to during something like XDR.
      */
     static RegExpObject*
     create(ExclusiveContext* cx, RegExpStatics* res, const char16_t* chars, size_t length,
            RegExpFlag flags, frontend::TokenStream* ts, LifoAlloc& alloc);