Merge inbound to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Sun, 29 Jul 2012 17:00:53 -0400
changeset 100835 36c30260e7fa1d043ac617d0d33c372513d6dc47
parent 100825 90828ac18dcf957d22a09de1e36e0424a331778e (current diff)
parent 100834 a231af50b731c5f17de997a570fe1c406943374e (diff)
child 100836 46ab93a2844b840a22ae24f5b54ae20f1869db3c
child 101298 bd91e48a4131574a95ff24e112d87f252dd58e1d
push id23195
push userryanvm@gmail.com
push dateSun, 29 Jul 2012 22:23:22 +0000
treeherdermozilla-central@36c30260e7fa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone17.0a1
first release with
nightly linux32
36c30260e7fa / 17.0a1 / 20120730030540 / files
nightly linux64
36c30260e7fa / 17.0a1 / 20120730030540 / files
nightly mac
36c30260e7fa / 17.0a1 / 20120730030540 / files
nightly win32
36c30260e7fa / 17.0a1 / 20120730030540 / files
nightly win64
36c30260e7fa / 17.0a1 / 20120730030540 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c.
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -202,16 +202,17 @@ var shell = {
   // xxx-button-release instead.
   filterHardwareKeys: function shell_filterHardwareKeys(evt) {
     var type;
     switch (evt.keyCode) {
       case evt.DOM_VK_HOME:         // Home button
         type = 'home-button';
         break;
       case evt.DOM_VK_SLEEP:        // Sleep button
+      case evt.DOM_VK_END:          // On desktop we don't have a sleep button
         type = 'sleep-button';
         break;
       case evt.DOM_VK_PAGE_UP:      // Volume up button
         type = 'volume-up-button';
         break;
       case evt.DOM_VK_PAGE_DOWN:    // Volume down button
         type = 'volume-down-button';
         break;
--- a/dom/file/ArchiveReader.h
+++ b/dom/file/ArchiveReader.h
@@ -10,24 +10,24 @@
 #include "nsIDOMArchiveReader.h"
 #include "nsIJSNativeInitializer.h"
 
 #include "FileCommon.h"
 
 #include "nsCOMArray.h"
 #include "nsIChannel.h"
 #include "nsIDOMFile.h"
-
+#include "mozilla/Attributes.h"
 
 BEGIN_FILE_NAMESPACE
 
 class ArchiveRequest;
 
-class ArchiveReader : public nsIDOMArchiveReader,
-                      public nsIJSNativeInitializer
+class ArchiveReader MOZ_FINAL : public nsIDOMArchiveReader,
+                                public nsIJSNativeInitializer
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_NSIDOMARCHIVEREADER
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ArchiveReader,
                                            nsIDOMArchiveReader)
--- a/dom/file/ArchiveZipFile.cpp
+++ b/dom/file/ArchiveZipFile.cpp
@@ -4,24 +4,25 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ArchiveZipFile.h"
 #include "ArchiveZipEvent.h"
 
 #include "nsIInputStream.h"
 #include "zlib.h"
+#include "mozilla/Attributes.h"
 
 USING_FILE_NAMESPACE
 
 #define ZIP_CHUNK 16384
 
 // a internat input stream object
 
-class ArchiveInputStream : public nsIInputStream
+class ArchiveInputStream MOZ_FINAL : public nsIInputStream
 {
 public:
   ArchiveInputStream(ArchiveReader* aReader,
                      nsString& aFilename,
                      PRUint32 aStart,
                      PRUint32 aLength,
                      ZipCentral& aCentral)
   : mArchiveReader(aReader),
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -298,16 +298,23 @@ class SourceSurface : public RefCounted<
 {
 public:
   virtual ~SourceSurface() {}
 
   virtual SurfaceType GetType() const = 0;
   virtual IntSize GetSize() const = 0;
   virtual SurfaceFormat GetFormat() const = 0;
 
+  /* This returns false if some event has made this source surface invalid for
+   * usage with current DrawTargets. For example in the case of Direct2D this
+   * could return false if we have switched devices since this surface was
+   * created.
+   */
+  virtual bool IsValid() const { return true; }
+
   /*
    * This function will get a DataSourceSurface for this surface, a
    * DataSourceSurface's data can be accessed directly.
    */
   virtual TemporaryRef<DataSourceSurface> GetDataSurface() = 0;
 };
 
 class DataSourceSurface : public SourceSurface
--- a/gfx/2d/SourceSurfaceD2D.cpp
+++ b/gfx/2d/SourceSurfaceD2D.cpp
@@ -29,16 +29,22 @@ SourceSurfaceD2D::GetSize() const
 }
 
 SurfaceFormat
 SourceSurfaceD2D::GetFormat() const
 {
   return mFormat;
 }
 
+bool
+SourceSurfaceD2D::IsValid() const
+{
+  return mDevice == Factory::GetDirect3D10Device();
+}
+
 TemporaryRef<DataSourceSurface>
 SourceSurfaceD2D::GetDataSurface()
 {
   return NULL;
 }
 
 bool
 SourceSurfaceD2D::InitFromData(unsigned char *aData,
@@ -63,16 +69,17 @@ SourceSurfaceD2D::InitFromData(unsigned 
   hr = aRT->CreateBitmap(D2DIntSize(aSize), aData, aStride, props, byRef(mBitmap));
 
   if (FAILED(hr)) {
     gfxWarning() << "Failed to create D2D Bitmap for data. Code: " << hr;
     return false;
   }
 
   DrawTargetD2D::mVRAMUsageSS += GetByteSize();
+  mDevice = Factory::GetDirect3D10Device();
 
   return true;
 }
 
 bool
 SourceSurfaceD2D::InitFromTexture(ID3D10Texture2D *aTexture,
                                   SurfaceFormat aFormat,
                                   ID2D1RenderTarget *aRT)
@@ -98,16 +105,17 @@ SourceSurfaceD2D::InitFromTexture(ID3D10
     D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(aFormat), AlphaMode(aFormat)));
   hr = aRT->CreateSharedBitmap(IID_IDXGISurface, surf, &props, byRef(mBitmap));
 
   if (FAILED(hr)) {
     gfxWarning() << "Failed to create SharedBitmap. Code: " << hr;
     return false;
   }
 
+  aTexture->GetDevice(byRef(mDevice));
   DrawTargetD2D::mVRAMUsageSS += GetByteSize();
 
   return true;
 }
 
 uint32_t
 SourceSurfaceD2D::GetByteSize() const
 {
--- a/gfx/2d/SourceSurfaceD2D.h
+++ b/gfx/2d/SourceSurfaceD2D.h
@@ -17,16 +17,18 @@ class SourceSurfaceD2D : public SourceSu
 {
 public:
   SourceSurfaceD2D();
   ~SourceSurfaceD2D();
 
   virtual SurfaceType GetType() const { return SURFACE_D2D1_BITMAP; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const;
+  virtual bool IsValid() const;
+
   virtual TemporaryRef<DataSourceSurface> GetDataSurface();
 
   ID2D1Bitmap *GetBitmap() { return mBitmap; }
 
   bool InitFromData(unsigned char *aData,
                     const IntSize &aSize,
                     int32_t aStride,
                     SurfaceFormat aFormat,
@@ -36,16 +38,18 @@ public:
                        ID2D1RenderTarget *aRT);
 
 private:
   friend class DrawTargetD2D;
 
   uint32_t GetByteSize() const;
 
   RefPtr<ID2D1Bitmap> mBitmap;
+  // We need to keep this pointer here to check surface validity.
+  RefPtr<ID3D10Device> mDevice;
   SurfaceFormat mFormat;
   IntSize mSize;
 };
 
 }
 }
 
 #endif /* MOZILLA_GFX_SOURCESURFACED2D_H_ */
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -498,17 +498,23 @@ void SourceSnapshotDetached(cairo_surfac
 }
 
 RefPtr<SourceSurface>
 gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurface)
 {
   void *userData = aSurface->GetData(&kSourceSurface);
 
   if (userData) {
-    return static_cast<SourceSurface*>(userData);
+    SourceSurface *surf = static_cast<SourceSurface*>(userData);
+
+    if (surf->IsValid()) {
+      return surf;
+    }
+    // We can just continue here as when setting new user data the destroy
+    // function will be called for the old user data.
   }
 
   SurfaceFormat format;
   if (aSurface->GetContentType() == gfxASurface::CONTENT_ALPHA) {
     format = FORMAT_A8;
   } else if (aSurface->GetContentType() == gfxASurface::CONTENT_COLOR) {
     format = FORMAT_B8G8R8X8;
   } else {
--- a/ipc/chromium/src/base/message_pump_qt.cc
+++ b/ipc/chromium/src/base/message_pump_qt.cc
@@ -75,17 +75,17 @@ MessagePumpQt::scheduleDelayedIfNeeded(c
     mTimer->stop();
   }
 
   TimeDelta later = delayed_work_time - Time::Now();
   // later.InMilliseconds() returns an int64, QTimer only accepts int's for start(),
   // std::min only works on exact same types.
   int laterMsecs = later.InMilliseconds() > std::numeric_limits<int>::max() ?
     std::numeric_limits<int>::max() : later.InMilliseconds();
-  mTimer->start(laterMsecs);
+  mTimer->start(laterMsecs > 0 ? laterMsecs : 0);
 }
 
 void
 MessagePumpQt::dispatchDelayed()
 {
   pump.HandleDispatch();
 }
 
--- a/js/public/Utility.h
+++ b/js/public/Utility.h
@@ -851,30 +851,17 @@ namespace js {
  */
 template<typename T>
 class MoveRef {
   public:
     typedef T Referent;
     explicit MoveRef(T &t) : pointer(&t) { }
     T &operator*()  const { return *pointer; }
     T *operator->() const { return  pointer; }
-#if defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(__clang__)
-    /*
-     * If MoveRef is used in a rvalue position (which is expected), we can
-     * end up in a situation where, without this ifdef, we would try to pass
-     * a T& to a move constructor, which fails. It is not clear if the compiler
-     * should instead use the copy constructor, but for now this lets us build
-     * with clang. See bug 689066 and llvm.org/pr11003 for the details.
-     * Note: We can probably remove MoveRef completely once we are comfortable
-     * using c++11.
-     */
-    operator T&& ()  const { return static_cast<T&&>(*pointer); }
-#else
     operator T& ()   const { return *pointer; }
-#endif
   private:
     T *pointer;
 };
 
 template<typename T>
 MoveRef<T> Move(T &t) { return MoveRef<T>(t); }
 
 template<typename T>
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -4859,17 +4859,17 @@ EmitFunc(JSContext *cx, BytecodeEmitter 
         CompileOptions options(cx);
         options.setPrincipals(parent->principals)
                .setOriginPrincipals(parent->originPrincipals)
                .setCompileAndGo(parent->compileAndGo)
                .setNoScriptRval(false)
                .setVersion(parent->getVersion());
         Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false, options,
                                                       parent->staticLevel + 1,
-                                                      bce->script->source,
+                                                      bce->script->scriptSource(),
                                                       funbox->bufStart, funbox->bufEnd));
         if (!script)
             return false;
 
         BytecodeEmitter bce2(bce, bce->parser, &sc, script, bce->callerFrame, bce->hasGlobalScope,
                              pn->pn_pos.begin.lineno);
         if (!bce2.init())
             return false;
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug777776.js
@@ -0,0 +1,5 @@
+gczeal(9, 2)
+for (a = 0; a < 4; ++a) {
+    b =
+    evaluate("/x/g");
+}
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -598,31 +598,31 @@ js::FunctionToString(JSContext *cx, Hand
         if (!out.append("function "))
             return NULL;
         if (fun->atom) {
             if (!out.append(fun->atom))
                 return NULL;
         }
     }
     bool haveSource = fun->isInterpreted();
-    if (haveSource && !fun->script()->source && !fun->script()->loadSource(cx, &haveSource))
+    if (haveSource && !fun->script()->scriptSource() && !fun->script()->loadSource(cx, &haveSource))
             return NULL;
     if (haveSource) {
         RootedScript script(cx, fun->script());
         RootedString src(cx, fun->script()->sourceData(cx));
         if (!src)
             return NULL;
         const jschar *chars = src->getChars(cx);
         if (!chars)
             return NULL;
         bool exprBody = fun->flags & JSFUN_EXPR_CLOSURE;
 
         // The source data for functions created by calling the Function
         // constructor is only the function's body.
-        bool funCon = script->sourceStart == 0 && script->source->argumentsNotIncluded();
+        bool funCon = script->sourceStart == 0 && script->scriptSource()->argumentsNotIncluded();
 
         // Functions created with the constructor should not be using the
         // expression body extension.
         JS_ASSERT_IF(funCon, !exprBody);
         JS_ASSERT_IF(!funCon, src->length() > 0 && chars[0] == '(');
 
         // If a function inherits strict mode by having scopes above it that
         // have "use strict", we insert "use strict" into the body of the
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -514,19 +514,19 @@ js::XDRScript(XDRState<mode> *xdr, Handl
             scriptBits |= (1 << ArgumentsHasVarBinding);
         if (script->analyzedArgsUsage() && script->needsArgsObj())
             scriptBits |= (1 << NeedsArgsObj);
         if (script->filename) {
             scriptBits |= (enclosingScript && enclosingScript->filename == script->filename)
                           ? (1 << ParentFilename)
                           : (1 << OwnFilename);
         }
-        if (script->source) {
+        if (script->scriptSource()) {
             scriptBits |= (1 << HaveSource);
-            if (!enclosingScript || enclosingScript->source != script->source)
+            if (!enclosingScript || enclosingScript->scriptSource() != script->scriptSource())
                 scriptBits |= (1 << OwnSource);
         }
         if (script->isGenerator)
             scriptBits |= (1 << IsGenerator);
         if (script->isGeneratorExp)
             scriptBits |= (1 << IsGeneratorExp);
 
         JS_ASSERT(!script->compileAndGo);
@@ -630,27 +630,29 @@ js::XDRScript(XDRState<mode> *xdr, Handl
         }
     } else if (scriptBits & (1 << ParentFilename)) {
         JS_ASSERT(enclosingScript);
         if (mode == XDR_DECODE)
             script->filename = enclosingScript->filename;
     }
 
     if (scriptBits & (1 << HaveSource)) {
+        ScriptSource *ss = script->scriptSource();
         if (scriptBits & (1 << OwnSource)) {
-            if (!ScriptSource::performXDR<mode>(xdr, &script->source))
+            if (!ScriptSource::performXDR<mode>(xdr, &ss))
                 return false;
         } else {
             JS_ASSERT(enclosingScript);
-            if (mode == XDR_DECODE)
-                script->source = enclosingScript->source;
+            ss = enclosingScript->scriptSource();
         }
+        if (mode == XDR_DECODE)
+            script->setScriptSource(cx, ss);
     } else if (mode == XDR_DECODE) {
-        script->source = NULL;
-        JS_ASSERT_IF(enclosingScript, !enclosingScript->source);
+        script->setScriptSource(cx, NULL);
+        JS_ASSERT_IF(enclosingScript, !enclosingScript->scriptSource());
     }
     if (!xdr->codeUint32(&script->sourceStart))
         return false;
     if (!xdr->codeUint32(&script->sourceEnd))
         return false;
 
     if (mode == XDR_DECODE) {
         script->lineno = lineno;
@@ -1066,45 +1068,56 @@ SourceCompressorThread::waitOnCompressio
     JS_ASSERT(tok->ss->ready());
     tok->ss = NULL;
     tok->chars = NULL;
     tok = NULL;
     PR_Unlock(lock);
 }
 #endif /* JS_THREADSAFE */
 
+void
+JSScript::setScriptSource(JSContext *cx, ScriptSource *ss)
+{
+#ifdef JSGC_INCREMENTAL
+    // During IGC, we need to barrier writing to scriptSource_.
+    if (ss && cx->runtime->gcIncrementalState != NO_INCREMENTAL && cx->runtime->gcIsFull)
+        ss->mark();
+#endif
+    scriptSource_ = ss;
+}
+
 bool
 JSScript::loadSource(JSContext *cx, bool *worked)
 {
-    JS_ASSERT(!source);
+    JS_ASSERT(!scriptSource_);
     *worked = false;
     if (!cx->runtime->sourceHook)
         return true;
     jschar *src = NULL;
     uint32_t length;
     if (!cx->runtime->sourceHook(cx, this, &src, &length))
         return false;
     if (!src)
         return true;
     ScriptSource *ss = ScriptSource::createFromSource(cx, src, length, false, NULL, true);
     if (!ss) {
         cx->free_(src);
         return false;
     }
-    source = ss;
+    setScriptSource(cx, ss);
     ss->attachToRuntime(cx->runtime);
     *worked = true;
     return true;
 }
 
 JSFixedString *
 JSScript::sourceData(JSContext *cx)
 {
-    JS_ASSERT(source);
-    return source->substring(cx, sourceStart, sourceEnd);
+    JS_ASSERT(scriptSource_);
+    return scriptSource_->substring(cx, sourceStart, sourceEnd);
 }
 
 JSFixedString *
 SourceDataCache::lookup(ScriptSource *ss)
 {
     if (!map_)
         return NULL;
     if (Map::Ptr p = map_->lookup(ss))
@@ -1194,26 +1207,16 @@ ScriptSource::createFromSource(JSContext
     ss->length_ = length;
     ss->compressedLength = 0;
     ss->marked = ss->onRuntime_ = false;
     ss->argumentsNotIncluded_ = argumentsNotIncluded;
 #ifdef DEBUG
     ss->ready_ = false;
 #endif
 
-#ifdef JSGC_INCREMENTAL
-    /*
-     * During the IGC we need to ensure that source is marked whenever it is
-     * accessed even if the name was already in the table. At this point old
-     * scripts pointing to the source may no longer be reachable.
-     */
-    if (cx->runtime->gcIncrementalState != NO_INCREMENTAL && cx->runtime->gcIsFull)
-        ss->marked = true;
-#endif
-
     JS_ASSERT_IF(ownSource, !tok);
 
 #ifdef JS_THREADSAFE
     if (tok && 0) {
         tok->ss = ss;
         tok->chars = src;
         cx->runtime->sourceCompressorThread.compress(tok);
     } else
@@ -1293,16 +1296,17 @@ ScriptSource::sizeOfIncludingThis(JSMall
     // data is a union, but both members are pointers to allocated memory, so
     // just using compressed will work.
     return mallocSizeOf(this) + mallocSizeOf(data.compressed);
 }
 
 void
 ScriptSource::sweep(JSRuntime *rt)
 {
+    JS_ASSERT(rt->gcIsFull);
     ScriptSource *next = rt->scriptSources, **prev = &rt->scriptSources;
     while (next) {
         ScriptSource *cur = next;
         next = cur->next;
         JS_ASSERT(cur->ready());
         JS_ASSERT(cur->onRuntime());
         if (cur->marked) {
             cur->marked = false;
@@ -1595,17 +1599,17 @@ JSScript::Create(JSContext *cx, HandleOb
     // stack if we nest functions more than a few hundred deep, so this will
     // never trigger.  Oh well.
     if (staticLevel > UINT16_MAX) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TOO_DEEP, js_function_str);
         return NULL;
     }
     script->staticLevel = uint16_t(staticLevel);
 
-    script->source = ss;
+    script->setScriptSource(cx, ss);
     script->sourceStart = bufStart;
     script->sourceEnd = bufEnd;
 
     return script;
 }
 
 static inline uint8_t *
 AllocScriptData(JSContext *cx, size_t size)
@@ -2259,17 +2263,17 @@ js::CloneScript(JSContext *cx, HandleObj
     CompileOptions options(cx);
     options.setPrincipals(cx->compartment->principals)
            .setOriginPrincipals(src->originPrincipals)
            .setCompileAndGo(src->compileAndGo)
            .setNoScriptRval(src->noScriptRval)
            .setVersion(src->getVersion());
     JSScript *dst = JSScript::Create(cx, enclosingScope, src->savedCallerFun,
                                      options, src->staticLevel,
-                                     src->source, src->sourceStart, src->sourceEnd);
+                                     src->scriptSource(), src->sourceStart, src->sourceEnd);
     if (!dst) {
         Foreground::free_(data);
         return NULL;
     }
 
     new (&dst->bindings) Bindings;
     dst->bindings.transfer(&bindings);
 
@@ -2592,18 +2596,18 @@ JSScript::markChildren(JSTracer *trc)
 
     if (enclosingScope_)
         MarkObject(trc, &enclosingScope_, "enclosing");
 
     if (IS_GC_MARKING_TRACER(trc)) {
         if (filename)
             MarkScriptFilename(trc->runtime, filename);
 
-        if (trc->runtime->gcIsFull && source && source->onRuntime())
-            source->mark();
+        if (trc->runtime->gcIsFull && scriptSource_)
+            scriptSource_->mark();
     }
 
     bindings.trace(trc);
 
 #ifdef JS_METHODJIT
     for (int constructing = 0; constructing <= 1; constructing++) {
         for (int barriers = 0; barriers <= 1; barriers++) {
             mjit::JITScript *jit = getJIT((bool) constructing, (bool) barriers);
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -432,19 +432,18 @@ struct JSScript : public js::gc::Cell
     js::HeapPtrAtom *atoms;     /* maps immediate index to literal struct */
 
     JSPrincipals    *principals;/* principals for this script */
     JSPrincipals    *originPrincipals; /* see jsapi.h 'originPrincipals' comment */
 
     /* Persistent type information retained across GCs. */
     js::types::TypeScript *types;
 
-    js::ScriptSource *source; /* source code */
-
   private:
+    js::ScriptSource *scriptSource_; /* source code */
 #ifdef JS_METHODJIT
     JITScriptSet *mJITInfo;
 #endif
     js::HeapPtrFunction function_;
     js::HeapPtrObject   enclosingScope_;
 
     // 32-bit fields.
 
@@ -616,16 +615,24 @@ struct JSScript : public js::gc::Cell
      */
     JSFunction *function() const { return function_; }
     void setFunction(JSFunction *fun);
 
     JSFixedString *sourceData(JSContext *cx);
 
     bool loadSource(JSContext *cx, bool *worked);
 
+    js::ScriptSource *scriptSource() {
+        return scriptSource_;
+    }
+
+    void setScriptSource(JSContext *cx, js::ScriptSource *ss);
+
+  public:
+
     /* Return whether this script was compiled for 'eval' */
     bool isForEval() { return isCachedEval || isActiveEval; }
 
 #ifdef DEBUG
     unsigned id();
 #else
     unsigned id() { return 0; }
 #endif
@@ -992,17 +999,17 @@ struct ScriptSource
   public:
     static ScriptSource *createFromSource(JSContext *cx,
                                           const jschar *src,
                                           uint32_t length,
                                           bool argumentsNotIncluded = false,
                                           SourceCompressionToken *tok = NULL,
                                           bool ownSource = false);
     void attachToRuntime(JSRuntime *rt);
-    void mark() { JS_ASSERT(ready_); JS_ASSERT(onRuntime_); marked = true; }
+    void mark() { marked = true; }
     void destroy(JSRuntime *rt);
     uint32_t length() const { return length_; }
     bool onRuntime() const { return onRuntime_; }
     bool argumentsNotIncluded() const { return argumentsNotIncluded_; }
 #ifdef DEBUG
     bool ready() const { return ready_; }
 #endif
     JSFixedString *substring(JSContext *cx, uint32_t start, uint32_t stop);
--- a/memory/mozjemalloc/jemalloc.c
+++ b/memory/mozjemalloc/jemalloc.c
@@ -1528,18 +1528,16 @@ wrtmessage(const char *p1, const char *p
 #define	_write	write
 #endif
 	_write(STDERR_FILENO, p1, (unsigned int) strlen(p1));
 	_write(STDERR_FILENO, p2, (unsigned int) strlen(p2));
 	_write(STDERR_FILENO, p3, (unsigned int) strlen(p3));
 	_write(STDERR_FILENO, p4, (unsigned int) strlen(p4));
 }
 
-#define _malloc_message malloc_message
-
 void	(*_malloc_message)(const char *p1, const char *p2, const char *p3,
 	    const char *p4) = wrtmessage;
 
 #ifdef MALLOC_DEBUG
 #  define assert(e) do {						\
 	if (!(e)) {							\
 		char line_buf[UMAX2S_BUFSIZE];				\
 		_malloc_message(__FILE__, ":", umax2s(__LINE__, 10,	\
--- a/testing/jetpack/jetpack-location.txt
+++ b/testing/jetpack/jetpack-location.txt
@@ -1,1 +1,1 @@
-http://hg.mozilla.org/projects/addon-sdk/archive/ff6864587606.tar.bz2
+http://hg.mozilla.org/projects/addon-sdk/archive/78041d0c5005.tar.bz2