Backed out changeset 37f1b9d6f522 (bug 1271650) for leaking debugger tests. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Tue, 05 Jul 2016 17:13:58 +0200
changeset 303711 a706323c0073b7cd72dc0c41a6601a91f15dea9b
parent 303710 a7a0676a43f2bb8b0693591ab75cd9cad36edbf1
child 303712 3f7577ec0b2c407e6be478ee21a727b06cad468e
push id79146
push userarchaeopteryx@coole-files.de
push dateTue, 05 Jul 2016 15:15:04 +0000
treeherdermozilla-inbound@a706323c0073 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1271650
milestone50.0a1
backs out37f1b9d6f52267752005e13968aafaee294dafa3
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 37f1b9d6f522 (bug 1271650) for leaking debugger tests. r=backout
js/src/vm/Debugger.cpp
js/src/vm/Debugger.h
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -71,35 +71,35 @@ static void DebuggerSource_trace(JSTrace
 enum {
     JSSLOT_DEBUGFRAME_OWNER,
     JSSLOT_DEBUGFRAME_ARGUMENTS,
     JSSLOT_DEBUGFRAME_ONSTEP_HANDLER,
     JSSLOT_DEBUGFRAME_ONPOP_HANDLER,
     JSSLOT_DEBUGFRAME_COUNT
 };
 
-const ClassOps DebuggerFrame::classOps_ = {
+static const ClassOps DebuggerFrame_classOps = {
     nullptr,    /* addProperty */
     nullptr,    /* delProperty */
     nullptr,    /* getProperty */
     nullptr,    /* setProperty */
     nullptr,    /* enumerate   */
     nullptr,    /* resolve     */
     nullptr,    /* mayResolve  */
     DebuggerFrame_finalize,
     nullptr,    /* call        */
     nullptr,    /* hasInstance */
     nullptr,    /* construct   */
     nullptr,    /* trace   */
 };
 
-const Class DebuggerFrame::class_ = {
+static const Class DebuggerFrame_class = {
     "Frame",
     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGFRAME_COUNT),
-    &DebuggerFrame::classOps_
+    &DebuggerFrame_classOps
 };
 
 enum {
     JSSLOT_DEBUGARGUMENTS_FRAME,
     JSSLOT_DEBUGARGUMENTS_COUNT
 };
 
 static const Class DebuggerArguments_class = {
@@ -687,17 +687,17 @@ Debugger::init(JSContext* cx)
 JS_STATIC_ASSERT(unsigned(JSSLOT_DEBUGFRAME_OWNER) == unsigned(JSSLOT_DEBUGSCRIPT_OWNER));
 JS_STATIC_ASSERT(unsigned(JSSLOT_DEBUGFRAME_OWNER) == unsigned(JSSLOT_DEBUGSOURCE_OWNER));
 JS_STATIC_ASSERT(unsigned(JSSLOT_DEBUGFRAME_OWNER) == unsigned(JSSLOT_DEBUGOBJECT_OWNER));
 JS_STATIC_ASSERT(unsigned(JSSLOT_DEBUGFRAME_OWNER) == unsigned(DebuggerEnvironment::OWNER_SLOT));
 
 /* static */ Debugger*
 Debugger::fromChildJSObject(JSObject* obj)
 {
-    MOZ_ASSERT(obj->getClass() == &DebuggerFrame::class_ ||
+    MOZ_ASSERT(obj->getClass() == &DebuggerFrame_class ||
                obj->getClass() == &DebuggerScript_class ||
                obj->getClass() == &DebuggerSource_class ||
                obj->getClass() == &DebuggerObject::class_ ||
                obj->getClass() == &DebuggerEnvironment::class_);
     JSObject* dbgobj = &obj->as<NativeObject>().getReservedSlot(JSSLOT_DEBUGOBJECT_OWNER).toObject();
     return fromJSObject(dbgobj);
 }
 
@@ -710,45 +710,55 @@ Debugger::hasMemory() const
 DebuggerMemory&
 Debugger::memory() const
 {
     MOZ_ASSERT(hasMemory());
     return object->getReservedSlot(JSSLOT_DEBUG_MEMORY_INSTANCE).toObject().as<DebuggerMemory>();
 }
 
 bool
-Debugger::getScriptFrameWithIter(JSContext* cx, AbstractFramePtr referent,
+Debugger::getScriptFrameWithIter(JSContext* cx, AbstractFramePtr frame,
                                  const ScriptFrameIter* maybeIter, MutableHandleValue vp)
 {
-    MOZ_ASSERT_IF(maybeIter, maybeIter->abstractFramePtr() == referent);
-    MOZ_ASSERT(!referent.script()->selfHosted());
-
-    if (!referent.script()->ensureHasAnalyzedArgsUsage(cx))
-        return false;
-
-    FrameMap::AddPtr p = frames.lookupForAdd(referent);
+    MOZ_ASSERT_IF(maybeIter, maybeIter->abstractFramePtr() == frame);
+    MOZ_ASSERT(!frame.script()->selfHosted());
+
+    if (!frame.script()->ensureHasAnalyzedArgsUsage(cx))
+        return false;
+
+    FrameMap::AddPtr p = frames.lookupForAdd(frame);
     if (!p) {
         /* Create and populate the Debugger.Frame object. */
         RootedObject proto(cx, &object->getReservedSlot(JSSLOT_DEBUG_FRAME_PROTO).toObject());
-        RootedNativeObject debugger(cx, object);
-
-        RootedNativeObject frame(cx, DebuggerFrame::create(cx, proto, referent, maybeIter,
-                                                           debugger));
-        if (!frame)
-            return false;
-
-        if (!ensureExecutionObservabilityOfFrame(cx, referent))
-            return false;
-
-        if (!frames.add(p, referent, frame)) {
+        RootedNativeObject frameobj(cx, NewNativeObjectWithGivenProto(cx, &DebuggerFrame_class,
+                                                                      proto));
+        if (!frameobj)
+            return false;
+
+        // Eagerly copy ScriptFrameIter data if we've already walked the
+        // stack.
+        if (maybeIter) {
+            AbstractFramePtr data = maybeIter->copyDataAsAbstractFramePtr();
+            if (!data)
+                return false;
+            frameobj->setPrivate(data.raw());
+        } else {
+            frameobj->setPrivate(frame.raw());
+        }
+
+        frameobj->setReservedSlot(JSSLOT_DEBUGFRAME_OWNER, ObjectValue(*object));
+
+        if (!ensureExecutionObservabilityOfFrame(cx, frame))
+            return false;
+
+        if (!frames.add(p, frame, frameobj)) {
             ReportOutOfMemory(cx);
             return false;
         }
     }
-
     vp.setObject(*p->value());
     return true;
 }
 
 /* static */ bool
 Debugger::hasLiveHook(GlobalObject* global, Hook which)
 {
     if (GlobalObject::DebuggerVector* debuggers = global->getDebuggers()) {
@@ -6999,51 +7009,16 @@ static const JSPropertySpec DebuggerSour
 
 static const JSFunctionSpec DebuggerSource_methods[] = {
     JS_FS_END
 };
 
 
 /*** Debugger.Frame ******************************************************************************/
 
-/* static */ NativeObject*
-DebuggerFrame::initClass(JSContext* cx, HandleObject dbgCtor, HandleObject obj)
-{
-    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
-    RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
-
-    return InitClass(cx, dbgCtor, objProto, &class_, construct, 0, properties_,
-                     methods_, nullptr, nullptr);
-}
-
-/* static */ DebuggerFrame*
-DebuggerFrame::create(JSContext* cx, HandleObject proto, AbstractFramePtr referent,
-                      const ScriptFrameIter* maybeIter, HandleNativeObject debugger)
-{
-  JSObject* obj = NewObjectWithGivenProto(cx, &DebuggerFrame::class_, proto, TenuredObject);
-  if (!obj)
-    return nullptr;
-
-  DebuggerFrame& frame = obj->as<DebuggerFrame>();
-
-  // Eagerly copy ScriptFrameIter data if we've already walked the stack.
-  if (maybeIter) {
-      AbstractFramePtr data = maybeIter->copyDataAsAbstractFramePtr();
-      if (!data)
-          return nullptr;
-      frame.setPrivate(data.raw());
-  } else {
-      frame.setPrivate(referent.raw());
-  }
-
-  frame.setReservedSlot(JSSLOT_DEBUGFRAME_OWNER, ObjectValue(*debugger));
-
-  return &frame;
-}
-
 static void
 UpdateFrameIterPc(FrameIter& iter)
 {
     if (iter.abstractFramePtr().isRematerializedFrame()) {
 #ifdef DEBUG
         // Rematerialized frames don't need their pc updated. The reason we
         // need to update pc is because we might get the same Debugger.Frame
         // object for multiple re-entries into debugger code from debuggee
@@ -7095,32 +7070,32 @@ DebuggerFrame_maybeDecrementFrameScriptS
 }
 
 static void
 DebuggerFrame_finalize(FreeOp* fop, JSObject* obj)
 {
     DebuggerFrame_freeScriptFrameIterData(fop, obj);
 }
 
-/* static */ DebuggerFrame*
-DebuggerFrame::checkThis(JSContext* cx, const CallArgs& args, const char* fnname, bool checkLive)
+static NativeObject*
+CheckThisFrame(JSContext* cx, const CallArgs& args, const char* fnname, bool checkLive)
 {
     JSObject* thisobj = NonNullObject(cx, args.thisv());
     if (!thisobj)
         return nullptr;
-    if (thisobj->getClass() != &DebuggerFrame::class_) {
+    if (thisobj->getClass() != &DebuggerFrame_class) {
         JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
                              "Debugger.Frame", fnname, thisobj->getClass()->name);
         return nullptr;
     }
 
-    DebuggerFrame* nthisobj = &thisobj->as<DebuggerFrame>();
+    NativeObject* nthisobj = &thisobj->as<NativeObject>();
 
     /*
-     * Forbid Debugger.Frame.prototype, which is of class DebuggerFrame::class_
+     * Forbid Debugger.Frame.prototype, which is of class DebuggerFrame_class
      * but isn't really a working Debugger.Frame object. The prototype object
      * is distinguished by having a nullptr private value. Also, forbid popped
      * frames.
      */
     if (!nthisobj->getPrivate()) {
         if (nthisobj->getReservedSlot(JSSLOT_DEBUGFRAME_OWNER).isUndefined()) {
             JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
                                  "Debugger.Frame", fnname, "prototype object");
@@ -7147,20 +7122,20 @@ DebuggerFrame::checkThis(JSContext* cx, 
  * by the AbstractFramePtr and cache its internal Data in the Debugger.Frame
  * object's private slot. Subsequent uses of the Debugger.Frame object will
  * always create a ScriptFrameIter from the cached Data.
  *
  * Methods that only need the AbstractFramePtr should use THIS_FRAME.
  * Methods that need a ScriptFrameIterator should use THIS_FRAME_ITER.
  */
 
-#define THIS_FRAME_THISOBJ(cx, argc, vp, fnname, args, thisobj)                       \
-    CallArgs args = CallArgsFromVp(argc, vp);                                         \
-    RootedNativeObject thisobj(cx, DebuggerFrame::checkThis(cx, args, fnname, true)); \
-    if (!thisobj)                                                                     \
+#define THIS_FRAME_THISOBJ(cx, argc, vp, fnname, args, thisobj)                \
+    CallArgs args = CallArgsFromVp(argc, vp);                                  \
+    RootedNativeObject thisobj(cx, CheckThisFrame(cx, args, fnname, true));    \
+    if (!thisobj)                                                              \
         return false
 
 #define THIS_FRAME(cx, argc, vp, fnname, args, thisobj, frame)                 \
     THIS_FRAME_THISOBJ(cx, argc, vp, fnname, args, thisobj);                   \
     AbstractFramePtr frame = AbstractFramePtr::FromRaw(thisobj->getPrivate()); \
     if (frame.isScriptFrameIterData()) {                                       \
         ScriptFrameIter iter(*(ScriptFrameIter::Data*)(frame.raw()));          \
         frame = iter.abstractFramePtr();                                       \
@@ -7478,17 +7453,17 @@ DebuggerFrame_getOffset(JSContext* cx, u
     args.rval().setNumber(double(offset));
     return true;
 }
 
 static bool
 DebuggerFrame_getLive(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    NativeObject* thisobj = DebuggerFrame::checkThis(cx, args, "get live", false);
+    NativeObject* thisobj = CheckThisFrame(cx, args, "get live", false);
     if (!thisobj)
         return false;
     bool hasFrame = !!thisobj->getPrivate();
     args.rval().setBoolean(hasFrame);
     return true;
 }
 
 static bool
@@ -7778,25 +7753,25 @@ DebuggerFrame_evalWithBindings(JSContext
 
     EvalOptions options;
     if (!ParseEvalOptions(cx, args.get(2), options))
         return false;
 
     return DebuggerGenericEval(cx, chars, bindings, options, args.rval(), dbg, nullptr, &iter);
 }
 
-/* static */ bool
-DebuggerFrame::construct(JSContext* cx, unsigned argc, Value* vp)
+static bool
+DebuggerFrame_construct(JSContext* cx, unsigned argc, Value* vp)
 {
     JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NO_CONSTRUCTOR,
                          "Debugger.Frame");
     return false;
 }
 
-const JSPropertySpec DebuggerFrame::properties_[] = {
+static const JSPropertySpec DebuggerFrame_properties[] = {
     JS_PSG("arguments", DebuggerFrame_getArguments, 0),
     JS_PSG("callee", DebuggerFrame_getCallee, 0),
     JS_PSG("constructing", DebuggerFrame_getConstructing, 0),
     JS_PSG("environment", DebuggerFrame_getEnvironment, 0),
     JS_PSG("generator", DebuggerFrame_getGenerator, 0),
     JS_PSG("live", DebuggerFrame_getLive, 0),
     JS_PSG("offset", DebuggerFrame_getOffset, 0),
     JS_PSG("older", DebuggerFrame_getOlder, 0),
@@ -7804,17 +7779,17 @@ const JSPropertySpec DebuggerFrame::prop
     JS_PSG("this", DebuggerFrame_getThis, 0),
     JS_PSG("type", DebuggerFrame_getType, 0),
     JS_PSG("implementation", DebuggerFrame_getImplementation, 0),
     JS_PSGS("onStep", DebuggerFrame_getOnStep, DebuggerFrame_setOnStep, 0),
     JS_PSGS("onPop", DebuggerFrame_getOnPop, DebuggerFrame_setOnPop, 0),
     JS_PS_END
 };
 
-const JSFunctionSpec DebuggerFrame::methods_[] = {
+static const JSFunctionSpec DebuggerFrame_methods[] = {
     JS_FN("eval", DebuggerFrame_eval, 1, 0),
     JS_FN("evalWithBindings", DebuggerFrame_evalWithBindings, 1, 0),
     JS_FS_END
 };
 
 
 /*** Debugger.Object *****************************************************************************/
 
@@ -10221,17 +10196,20 @@ JS_DefineDebuggerObject(JSContext* cx, H
         return false;
     debugProto = InitClass(cx, obj,
                            objProto, &Debugger::class_, Debugger::construct,
                            1, Debugger::properties, Debugger::methods, nullptr,
                            Debugger::static_methods, debugCtor.address());
     if (!debugProto)
         return false;
 
-    frameProto = DebuggerFrame::initClass(cx, debugCtor, obj);
+    frameProto = InitClass(cx, debugCtor, objProto, &DebuggerFrame_class,
+                           DebuggerFrame_construct, 0,
+                           DebuggerFrame_properties, DebuggerFrame_methods,
+                           nullptr, nullptr);
     if (!frameProto)
         return false;
 
     scriptProto = InitClass(cx, debugCtor, objProto, &DebuggerScript_class,
                             DebuggerScript_construct, 0,
                             DebuggerScript_properties, DebuggerScript_methods,
                             nullptr, nullptr);
     if (!scriptProto)
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -1125,36 +1125,16 @@ class DebuggerEnvironment : public Nativ
     static MOZ_MUST_USE bool optimizedOutGetter(JSContext* cx, unsigned argc, Value* vp);
 
     static MOZ_MUST_USE bool namesMethod(JSContext* cx, unsigned argc, Value* vp);
     static MOZ_MUST_USE bool findMethod(JSContext* cx, unsigned argc, Value* vp);
     static MOZ_MUST_USE bool getVariableMethod(JSContext* cx, unsigned argc, Value* vp);
     static MOZ_MUST_USE bool setVariableMethod(JSContext* cx, unsigned argc, Value* vp);
 };
 
-class DebuggerFrame : public NativeObject
-{
-  public:
-    static const Class class_;
-
-    static NativeObject* initClass(JSContext* cx, HandleObject dbgCtor, HandleObject objProto);
-    static DebuggerFrame* create(JSContext* cx, HandleObject proto, AbstractFramePtr referent,
-                                 const ScriptFrameIter* maybeIter, HandleNativeObject debugger);
-    static DebuggerFrame* checkThis(JSContext* cx, const CallArgs& args, const char* fnname,
-                                    bool checkLive);
-
-  private:
-    static const ClassOps classOps_;
-
-    static const JSPropertySpec properties_[];
-    static const JSFunctionSpec methods_[];
-
-    static MOZ_MUST_USE bool construct(JSContext* cx, unsigned argc, Value* vp);
-};
-
 class DebuggerObject : public NativeObject
 {
   public:
     static const Class class_;
 
     static NativeObject* initClass(JSContext* cx, HandleObject obj, HandleObject debugCtor);
     static DebuggerObject* create(JSContext* cx, HandleObject proto, HandleObject obj,
                                   HandleNativeObject debugger);