Commit 61fa808e authored by Matthew Gaudet's avatar Matthew Gaudet
Browse files

Bug 1604952 - Change ownership of RegExpCreationData by holding them on...

Bug 1604952 - Change ownership of RegExpCreationData by holding them on frontend::ParseInfo r=tcampbell

By doing this we guarantee RegExpCreationData are cleaned up, avoiding a possible leak where
dead code elimination removes a ParseNode without cleaning up the RegExpCreationData.

Differential Revision: https://phabricator.services.mozilla.com/D57904

--HG--
extra : moz-landing-system : lando
parent 45cf5b11
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3184,7 +3184,8 @@ bool ASTSerializer::literal(ParseNode* pn, MutableHandleValue dst) {
      break;

    case ParseNodeKind::RegExpExpr: {
      RootedObject re1(cx, pn->as<RegExpLiteral>().getOrCreate(cx));
      RootedObject re1(
          cx, pn->as<RegExpLiteral>().getOrCreate(cx, parser->getParseInfo()));
      LOCAL_ASSERT(re1 && re1->is<RegExpObject>());

      RootedObject re2(cx, CloneRegExpObject(cx, re1.as<RegExpObject>()));
+7 −3
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include "mozilla/PodOperations.h"    // PodZero
#include "mozilla/ReverseIterator.h"  // mozilla::Reversed

#include "frontend/ParseInfo.h"
#include "frontend/ParseNode.h"      // ObjectBox
#include "frontend/SharedContext.h"  // FunctionBox
#include "vm/BytecodeUtil.h"         // INDEX_LIMIT, StackUses, StackDefs
@@ -42,12 +43,14 @@ void GCThingList::finishInnerFunctions() {
  }
}

bool GCThingList::finish(JSContext* cx, mozilla::Span<JS::GCCellPtr> array) {
bool GCThingList::finish(JSContext* cx, ParseInfo& parseInfo,
                         mozilla::Span<JS::GCCellPtr> array) {
  MOZ_ASSERT(length() <= INDEX_LIMIT);
  MOZ_ASSERT(length() == array.size());

  struct Matcher {
    JSContext* cx;
    ParseInfo& parseInfo;
    uint32_t i;
    mozilla::Span<JS::GCCellPtr>& array;

@@ -65,7 +68,8 @@ bool GCThingList::finish(JSContext* cx, mozilla::Span<JS::GCCellPtr> array) {
      return true;
    }

    bool operator()(RegExpCreationData& data) {
    bool operator()(RegExpIndex& rindex) {
      RegExpCreationData& data = parseInfo.regExpData[rindex];
      RegExpObject* regexp = data.createRegExp(cx);
      if (!regexp) {
        return false;
@@ -85,7 +89,7 @@ bool GCThingList::finish(JSContext* cx, mozilla::Span<JS::GCCellPtr> array) {
  };

  for (uint32_t i = 0; i < length(); i++) {
    Matcher m{cx, i, array};
    Matcher m{cx, parseInfo, i, array};
    if (!vector[i].get().match(m)) {
      return false;
    }
+9 −7
Original line number Diff line number Diff line
@@ -22,8 +22,10 @@
#include "frontend/JumpList.h"         // JumpTarget
#include "frontend/NameCollections.h"  // AtomIndexMap, PooledMapPtr
#include "frontend/ObjLiteral.h"       // ObjLiteralCreationData
#include "frontend/ParseInfo.h"        // ParseInfo
#include "frontend/ParseNode.h"        // BigIntLiteral
#include "frontend/SourceNotes.h"      // jssrcnote
#include "frontend/Stencil.h"          // Stencils
#include "gc/Barrier.h"                // GCPtrObject, GCPtrScope, GCPtrValue
#include "gc/Rooting.h"                // JS::Rooted
#include "js/GCVariant.h"              // GCPolicy<mozilla::Variant>
@@ -47,7 +49,7 @@ class ObjectBox;

struct MOZ_STACK_CLASS GCThingList {
  using ListType = mozilla::Variant<JS::GCCellPtr, BigIntCreationData,
                                    ObjLiteralCreationData, RegExpCreationData>;
                                    ObjLiteralCreationData, RegExpIndex>;
  JS::RootedVector<ListType> vector;

  // Last emitted object.
@@ -78,8 +80,7 @@ struct MOZ_STACK_CLASS GCThingList {
  MOZ_MUST_USE bool append(RegExpLiteral* literal, uint32_t* index) {
    *index = vector.length();
    if (literal->isDeferred()) {
      return vector.append(
          mozilla::AsVariant(std::move(literal->creationData())));
      return vector.append(mozilla::AsVariant(literal->index()));
    }
    return vector.append(
        mozilla::AsVariant(JS::GCCellPtr(literal->objbox()->object())));
@@ -91,7 +92,8 @@ struct MOZ_STACK_CLASS GCThingList {
  MOZ_MUST_USE bool append(ObjectBox* obj, uint32_t* index);

  uint32_t length() const { return vector.length(); }
  MOZ_MUST_USE bool finish(JSContext* cx, mozilla::Span<JS::GCCellPtr> array);
  MOZ_MUST_USE bool finish(JSContext* cx, ParseInfo& parseInfo,
                           mozilla::Span<JS::GCCellPtr> array);
  void finishInnerFunctions();

  AbstractScope getScope(size_t index) const {
@@ -397,9 +399,9 @@ template <>
struct GCPolicy<js::frontend::BigIntCreationData>
    : JS::IgnoreGCPolicy<js::frontend::BigIntCreationData> {};

template <>
struct GCPolicy<js::frontend::RegExpCreationData>
    : JS::IgnoreGCPolicy<js::frontend::RegExpCreationData> {};
template <typename T>
struct GCPolicy<js::frontend::TypedIndex<T>>
    : JS::IgnoreGCPolicy<js::frontend::TypedIndex<T>> {};
}  // namespace JS

#endif /* frontend_BytecodeSection_h */
+3 −2
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@

#include "frontend/ParseNode.h"
#include "frontend/SharedContext.h"
#include "frontend/Stencil.h"
#include "vm/JSContext.h"

namespace js {
@@ -236,8 +237,8 @@ class FullParseHandler {
    return new_<RegExpLiteral>(objbox, pos);
  }

  RegExpLiteralType newRegExp(const TokenPos& pos) {
    return new_<RegExpLiteral>(pos);
  RegExpLiteralType newRegExp(RegExpIndex index, const TokenPos& pos) {
    return new_<RegExpLiteral>(index, pos);
  }

  ConditionalExpressionType newConditional(Node cond, Node thenExpr,
+6 −1
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@

#include "ds/LifoAlloc.h"
#include "frontend/FunctionTree.h"
#include "frontend/Stencil.h"
#include "frontend/UsedNameTracker.h"
#include "js/RealmOptions.h"
#include "js/Vector.h"
@@ -38,6 +39,9 @@ struct MOZ_RAII ParseInfo {
  LifoAllocScope& allocScope;
  FunctionTreeHolder treeHolder;
  Mode mode;
  // Hold onto the RegExpCreationData that are allocated during parse to
  // ensure correct destruction.
  Vector<RegExpCreationData> regExpData;

  ParseInfo(JSContext* cx, LifoAllocScope& alloc)
      : usedNames(cx),
@@ -45,7 +49,8 @@ struct MOZ_RAII ParseInfo {
        treeHolder(cx),
        mode(cx->realm()->behaviors().deferredParserAlloc()
                 ? ParseInfo::Mode::Deferred
                 : ParseInfo::Mode::Eager) {}
                 : ParseInfo::Mode::Eager),
        regExpData(cx) {}

  // To avoid any misuses, make sure this is neither copyable,
  // movable or assignable.
Loading