~ruther/guix-local

29f381bac72d207e8bf0a2c73c82d7a77b45b597 — Clément Lassieur 9 years ago a7e5944
gnu: Add mozjs-38 (Mozilla SpiderMonkey 38).

* gnu/packages/gnuzilla.scm (mozjs-38): New variable.
* gnu/packages/patches/mozjs38-pkg-config-version.patch,
gnu/packages/patches/mozjs38-shell-version.patch,
gnu/packages/patches/mozjs38-tracelogger.patch,
gnu/packages/patches/mozjs38-version-detection.patch: New files.
* gnu/local.mk (dist_patch_DATA): Add them.

Co-authored-by: ng0 <ng0@no-reply.pragmatique.xyz>
M gnu/local.mk => gnu/local.mk +4 -0
@@ 811,6 811,10 @@ dist_patch_DATA =						\
  %D%/packages/patches/module-init-tools-moduledir.patch	\
  %D%/packages/patches/mozjs17-aarch64-support.patch		\
  %D%/packages/patches/mozjs24-aarch64-support.patch		\
  %D%/packages/patches/mozjs38-pkg-config-version.patch		\
  %D%/packages/patches/mozjs38-shell-version.patch		\
  %D%/packages/patches/mozjs38-tracelogger.patch		\
  %D%/packages/patches/mozjs38-version-detection.patch		\
  %D%/packages/patches/multiqc-fix-git-subprocess-error.patch	\
  %D%/packages/patches/mumps-build-parallelism.patch		\
  %D%/packages/patches/mupdf-build-with-openjpeg-2.1.patch	\

M gnu/packages/gnuzilla.scm => gnu/packages/gnuzilla.scm +89 -1
@@ 6,6 6,7 @@
;;; Copyright © 2016, 2017 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2016 Alex Griffin <a@ajgrf.com>
;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
;;; Copyright © 2017 ng0 <ng0@no-reply.pragmatique.xyz>
;;;
;;; This file is part of GNU Guix.
;;;


@@ 57,7 58,8 @@
  #:use-module (gnu packages icu4c)
  #:use-module (gnu packages video)
  #:use-module (gnu packages xdisorg)
  #:use-module (gnu packages zip))
  #:use-module (gnu packages zip)
  #:use-module (gnu packages readline))

(define-public mozjs
  (package


@@ 159,6 161,92 @@ in C/C++.")
     `(("libffi" ,libffi)
       ("zlib" ,zlib)))))

(define-public mozjs-38
  (package
    (inherit mozjs)
    (name "mozjs")
    (version "38.2.1.rc0")
    (source (origin
              (method url-fetch)
              (uri (string-append
                    "https://people.mozilla.org/~sstangl/"
                    name "-" version ".tar.bz2"))
              (sha256
               (base32
                "0p4bmbpgkfsj54xschcny0a118jdrdgg0q29rwxigg3lh5slr681"))
              (patches
               (search-patches
                ;; See https://bugzilla.mozilla.org/show_bug.cgi?id=1269317 for
                ;; GCC 6 compatibility.

                "mozjs38-version-detection.patch" ; for 0ad
                "mozjs38-tracelogger.patch"

                ;; See https://bugzilla.mozilla.org/show_bug.cgi?id=1339931.
                "mozjs38-pkg-config-version.patch"
                "mozjs38-shell-version.patch"))
              (modules '((guix build utils)))
              (snippet
               '(begin
                  ;; Fix incompatibility with sed 4.4.
                  (substitute* "js/src/configure"
                    (("\\^\\[:space:\\]") "^[[:space:]]"))

                  ;; The headers are symlinks to files that are in /tmp, so they
                  ;; end up broken.  Copy them instead.
                  (substitute*
                      "python/mozbuild/mozbuild/backend/recursivemake.py"
                    (("\\['dist_include'\\].add_symlink")
                     "['dist_include'].add_copy"))

                  ;; Remove bundled libraries.
                  (for-each delete-file-recursively
                            '("intl"
                              "js/src/ctypes/libffi"
                              "js/src/ctypes/libffi-patches"
                              "modules/zlib"))
                  #t))))
    (arguments
     `(;; XXX: parallel build fails, lacking:
       ;;   mkdir -p "system_wrapper_js/"
       #:parallel-build? #f
       ;; See https://bugzilla.mozilla.org/show_bug.cgi?id=1008470.
       #:tests? #f
       #:phases
       (modify-phases %standard-phases
         (replace 'configure
           (lambda* (#:key outputs #:allow-other-keys)
             (let ((out (assoc-ref outputs "out")))
               (chdir "js/src")
               (setenv "SHELL" (which "sh"))
               (setenv "CONFIG_SHELL" (which "sh"))
               (zero? (system* "./configure"
                               (string-append "--prefix=" out)
                               "--enable-ctypes"
                               "--enable-gcgenerational"
                               "--enable-optimize"
                               "--enable-pie"
                               "--enable-readline"
                               "--enable-shared-js"
                               "--enable-system-ffi"
                               "--enable-threadsafe"
                               "--enable-xterm-updates"
                               "--with-system-icu"
                               "--with-system-nspr"
                               "--with-system-zlib"

                               ;; Intl API requires bundled ICU.
                               "--without-intl-api"))))))))
    (native-inputs
     `(("perl" ,perl)
       ("pkg-config" ,pkg-config)
       ("python-2" ,python-2)))
    (inputs
     `(("libffi" ,libffi)
       ("readline" ,readline)
       ("icu4c" ,icu4c)
       ("zlib" ,zlib)))))

(define-public nspr
  (package
    (name "nspr")

A gnu/packages/patches/mozjs38-pkg-config-version.patch => gnu/packages/patches/mozjs38-pkg-config-version.patch +24 -0
@@ 0,0 1,24 @@
Taken from https://bug1339931.bmoattachments.org/attachment.cgi?id=8837770.

Add major version to pkg-config filename.
Author: Rico Tzschichholz <ricotz@ubuntu.com>
Forwarded: no
Last-Update: 2015-05-04

Index: b/js/src/Makefile.in
===================================================================
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -214,10 +214,10 @@
 $(JS_CONFIG_NAME): js-config
    cp $^ $@
 
-$(LIBRARY_NAME).pc: js.pc
+$(JS_LIBRARY_NAME).pc: js.pc
 	cp $^ $@
 
-install:: $(LIBRARY_NAME).pc
+install:: $(JS_LIBRARY_NAME).pc
 	$(SYSINSTALL) $^ $(DESTDIR)$(libdir)/pkgconfig
 
 install:: js-config.h

A gnu/packages/patches/mozjs38-shell-version.patch => gnu/packages/patches/mozjs38-shell-version.patch +67 -0
@@ 0,0 1,67 @@
Taken from https://bug1339931.bmoattachments.org/attachment.cgi?id=8837771.

# HG changeset patch
# Parent 4732a0e5d22bc7e5c1f1ace7a182d537d9cc2c6a
Add major version to shell and js-config filenames.
Author: Rico Tzschichholz <ricotz@ubuntu.com>
Forwarded: no
Last-Update: 2014-10-29

---
diff --git a/js/src/configure b/js/src/configure
--- a/js/src/configure
+++ b/js/src/configure
@@ -1696,8 +1696,13 @@
 MOZJS_PATCH_VERSION=`echo $MOZILLA_VERSION | sed "s|^[0-9]*\.[0-9]*[^0-9]*||"`
 IS_ALPHA=`echo $MOZILLA_VERSION | grep '[ab]'`
 
+if test -n "$JS_STANDALONE"; then
+JS_SHELL_NAME=js$MOZJS_MAJOR_VERSION
+JS_CONFIG_NAME=js$MOZJS_MAJOR_VERSION-config
+else
 JS_SHELL_NAME=js
 JS_CONFIG_NAME=js-config
+fi
 
 
 if test -n "$IS_ALPHA"; then

diff --git a/js/src/configure.in b/js/src/configure.in
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -234,16 +234,13 @@ MOZJS_MINOR_VERSION=`echo $MOZILLA_VERSI
 MOZJS_PATCH_VERSION=`echo $MOZILLA_VERSION | sed "s|^[0-9]*\.[0-9]*[^0-9]*||"`
 IS_ALPHA=`echo $MOZILLA_VERSION | grep '[ab]'`
 
-dnl XXX in a temporary bid to avoid developer anger at renaming files
-dnl XXX before "js" symlinks exist, don't change names.
-dnl
-dnl if test -n "$JS_STANDALONE"; then
-dnl JS_SHELL_NAME=js$MOZJS_MAJOR_VERSION
-dnl JS_CONFIG_NAME=js$MOZJS_MAJOR_VERSION-config
-dnl else
+if test -n "$JS_STANDALONE"; then
+JS_SHELL_NAME=js$MOZJS_MAJOR_VERSION
+JS_CONFIG_NAME=js$MOZJS_MAJOR_VERSION-config
+else
 JS_SHELL_NAME=js
 JS_CONFIG_NAME=js-config
-dnl fi
+fi
 
 changequote([,])
 if test -n "$IS_ALPHA"; then

diff -r 80a9e64d75f5 js/src/Makefile.in
--- a/js/src/Makefile.in        Wed Jun 25 15:11:42 2014 +0200
+++ b/js/src/Makefile.in        Sat Jul 05 14:08:38 2014 +0200
@@ -273,6 +273,9 @@
 SCRIPTS = $(JS_CONFIG_NAME)
 SDK_BINARY = $(JS_CONFIG_NAME)
 
+$(JS_CONFIG_NAME): js-config
+	cp $^ $@
+
 $(JS_LIBRARY_NAME).pc: js.pc
 	cp $^ $@
 

A gnu/packages/patches/mozjs38-tracelogger.patch => gnu/packages/patches/mozjs38-tracelogger.patch +608 -0
@@ 0,0 1,608 @@
Squashed version of several commits to fix the tracelogger.

Taken from
https://github.com/GNOME/jhbuild/blob/master/patches/mozjs38-fix-tracelogger.patch.

# === Fix the SM38 tracelogger ===
# This patch is a squashed version of several patches that were adapted
# to fix failing hunks.
#
# Applied in the following order, they are:
# * https://bugzilla.mozilla.org/show_bug.cgi?id=1223767
#    Assertion failure: i < size_, at js/src/vm/TraceLoggingTypes.h:210 
#    Also fix stop-information to make reduce.py work correctly.
# * https://bugzilla.mozilla.org/show_bug.cgi?id=1227914
#    Limit the memory tracelogger can take.
#    This causes tracelogger to flush data to the disk regularly and prevents out of 
#    memory issues if a lot of data gets logged.
# * https://bugzilla.mozilla.org/show_bug.cgi?id=1155618
#    Fix tracelogger destructor that touches possibly uninitialised hash table.
# * https://bugzilla.mozilla.org/show_bug.cgi?id=1223636
#    Don't treat extraTextId as containing only extra ids.
#    This fixes an assertion failure: id == nextTextId at js/src/vm/TraceLoggingGraph.cpp
# * https://bugzilla.mozilla.org/show_bug.cgi?id=1227028
#    Fix when to keep the payload of a TraceLogger event.
#    This fixes an assertion failure: textId < uint32_t(1 << 31) at js/src/vm/TraceLoggingGraph.h
# * https://bugzilla.mozilla.org/show_bug.cgi?id=1266649
#    Handle failing to add to pointermap gracefully.
# * https://bugzilla.mozilla.org/show_bug.cgi?id=1280648
#    Don't cache based on pointers to movable GC things.
# * https://bugzilla.mozilla.org/show_bug.cgi?id=1224123
#    Fix the use of LastEntryId in tracelogger.h.
# * https://bugzilla.mozilla.org/show_bug.cgi?id=1231170
#    Use size in debugger instead of the current id to track last logged item.
# * https://bugzilla.mozilla.org/show_bug.cgi?id=1221844
#    Move TraceLogger_Invalidation to LOG_ITEM.
#    Add some debug checks to logTimestamp.
# * https://bugzilla.mozilla.org/show_bug.cgi?id=1255766
#    Also mark resizing of memory.
# * https://bugzilla.mozilla.org/show_bug.cgi?id=1259403
#    Only increase capacity by multiples of 2.
#    Always make sure there are 3 free slots for events.
# ===

diff --git a/js/src/jit-test/tests/tracelogger/bug1231170.js b/js/src/jit-test/tests/tracelogger/bug1231170.js
new file mode 100644
index 0000000..023e93e
--- /dev/null
+++ b/js/src/jit-test/tests/tracelogger/bug1231170.js
@@ -0,0 +1,3 @@
+var du = new Debugger();
+if (typeof du.drainTraceLogger === "function")
+    du.drainTraceLogger();
diff --git a/js/src/jit-test/tests/tracelogger/bug1266649.js b/js/src/jit-test/tests/tracelogger/bug1266649.js
new file mode 100644
index 0000000..81ae7ad
--- /dev/null
+++ b/js/src/jit-test/tests/tracelogger/bug1266649.js
@@ -0,0 +1,10 @@
+
+var du = new Debugger();
+if (typeof du.setupTraceLogger === "function" &&
+    typeof oomTest === 'function')
+{
+    du.setupTraceLogger({
+        Scripts: true
+    })
+    oomTest(() => function(){});
+}
diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp
index 93e2fda..09049d6 100644
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -1055,6 +1055,8 @@ IonScript::Destroy(FreeOp* fop, IonScript* script)
 
     script->destroyCaches();
     script->unlinkFromRuntime(fop);
+    // Frees the potential event we have set.
+    script->traceLoggerScriptEvent_ = TraceLoggerEvent();
     fop->free_(script);
 }
 
diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp
index 26262fd..af7f313 100644
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -369,10 +369,10 @@ Debugger::Debugger(JSContext* cx, NativeObject* dbg)
     objects(cx),
     environments(cx),
 #ifdef NIGHTLY_BUILD
-    traceLoggerLastDrainedId(0),
+    traceLoggerLastDrainedSize(0),
     traceLoggerLastDrainedIteration(0),
 #endif
-    traceLoggerScriptedCallsLastDrainedId(0),
+    traceLoggerScriptedCallsLastDrainedSize(0),
     traceLoggerScriptedCallsLastDrainedIteration(0)
 {
     assertSameCompartment(cx, dbg);
@@ -3907,9 +3907,9 @@ Debugger::drainTraceLogger(JSContext* cx, unsigned argc, Value* vp)
     size_t num;
     TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
     bool lostEvents = logger->lostEvents(dbg->traceLoggerLastDrainedIteration,
-                                         dbg->traceLoggerLastDrainedId);
+                                         dbg->traceLoggerLastDrainedSize);
     EventEntry* events = logger->getEventsStartingAt(&dbg->traceLoggerLastDrainedIteration,
-                                                     &dbg->traceLoggerLastDrainedId,
+                                                     &dbg->traceLoggerLastDrainedSize,
                                                      &num);
 
     RootedObject array(cx, NewDenseEmptyArray(cx));
@@ -4002,10 +4002,10 @@ Debugger::drainTraceLoggerScriptCalls(JSContext* cx, unsigned argc, Value* vp)
     size_t num;
     TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
     bool lostEvents = logger->lostEvents(dbg->traceLoggerScriptedCallsLastDrainedIteration,
-                                         dbg->traceLoggerScriptedCallsLastDrainedId);
+                                         dbg->traceLoggerScriptedCallsLastDrainedSize);
     EventEntry* events = logger->getEventsStartingAt(
                                          &dbg->traceLoggerScriptedCallsLastDrainedIteration,
-                                         &dbg->traceLoggerScriptedCallsLastDrainedId,
+                                         &dbg->traceLoggerScriptedCallsLastDrainedSize,
                                          &num);
 
     RootedObject array(cx, NewDenseEmptyArray(cx));
diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h
index 8cac36a..c92d685 100644
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -314,10 +314,10 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
      * lost events.
      */
 #ifdef NIGHTLY_BUILD
-    uint32_t traceLoggerLastDrainedId;
+    uint32_t traceLoggerLastDrainedSize;
     uint32_t traceLoggerLastDrainedIteration;
 #endif
-    uint32_t traceLoggerScriptedCallsLastDrainedId;
+    uint32_t traceLoggerScriptedCallsLastDrainedSize;
     uint32_t traceLoggerScriptedCallsLastDrainedIteration;
 
     class FrameRange;
diff --git a/js/src/vm/TraceLogging.cpp b/js/src/vm/TraceLogging.cpp
index 6715b36..9766a6f 100644
--- a/js/src/vm/TraceLogging.cpp
+++ b/js/src/vm/TraceLogging.cpp
@@ -131,7 +131,7 @@ TraceLoggerThread::init()
 {
     if (!pointerMap.init())
         return false;
-    if (!extraTextId.init())
+    if (!textIdPayloads.init())
         return false;
     if (!events.init())
         return false;
@@ -185,10 +185,10 @@ TraceLoggerThread::~TraceLoggerThread()
         graph = nullptr;
     }
 
-    for (TextIdHashMap::Range r = extraTextId.all(); !r.empty(); r.popFront())
-        js_delete(r.front().value());
-    extraTextId.finish();
-    pointerMap.finish();
+    if (textIdPayloads.initialized()) {
+        for (TextIdHashMap::Range r = textIdPayloads.all(); !r.empty(); r.popFront())
+            js_delete(r.front().value());
+    }
 }
 
 bool
@@ -287,7 +287,7 @@ TraceLoggerThread::eventText(uint32_t id)
     if (id < TraceLogger_Last)
         return TLTextIdString(static_cast<TraceLoggerTextId>(id));
 
-    TextIdHashMap::Ptr p = extraTextId.lookup(id);
+    TextIdHashMap::Ptr p = textIdPayloads.lookup(id);
     MOZ_ASSERT(p);
 
     return p->value()->string();
@@ -341,13 +341,15 @@ TraceLoggerThread::extractScriptDetails(uint32_t textId, const char** filename,
 TraceLoggerEventPayload*
 TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId textId)
 {
-    TextIdHashMap::AddPtr p = extraTextId.lookupForAdd(textId);
-    if (p)
+    TextIdHashMap::AddPtr p = textIdPayloads.lookupForAdd(textId);
+    if (p) {
+        MOZ_ASSERT(p->value()->textId() == textId); // Sanity check.
         return p->value();
+    }
 
     TraceLoggerEventPayload* payload = js_new<TraceLoggerEventPayload>(textId, (char*)nullptr);
 
-    if (!extraTextId.add(p, textId, payload))
+    if (!textIdPayloads.add(p, textId, payload))
         return nullptr;
 
     return payload;
@@ -357,8 +359,10 @@ TraceLoggerEventPayload*
 TraceLoggerThread::getOrCreateEventPayload(const char* text)
 {
     PointerHashMap::AddPtr p = pointerMap.lookupForAdd((const void*)text);
-    if (p)
+    if (p) {
+        MOZ_ASSERT(p->value()->textId() < nextTextId); // Sanity check.
         return p->value();
+    }
 
     size_t len = strlen(text);
     char* str = js_pod_malloc<char>(len + 1);
@@ -369,7 +373,7 @@ TraceLoggerThread::getOrCreateEventPayload(const char* text)
     MOZ_ASSERT(ret == len);
     MOZ_ASSERT(strlen(str) == len);
 
-    uint32_t textId = extraTextId.count() + TraceLogger_Last;
+    uint32_t textId = nextTextId;
 
     TraceLoggerEventPayload* payload = js_new<TraceLoggerEventPayload>(textId, str);
     if (!payload) {
@@ -377,17 +381,19 @@ TraceLoggerThread::getOrCreateEventPayload(const char* text)
         return nullptr;
     }
 
-    if (!extraTextId.putNew(textId, payload)) {
+    if (!textIdPayloads.putNew(textId, payload)) {
         js_delete(payload);
         return nullptr;
     }
 
-    if (!pointerMap.add(p, text, payload))
-        return nullptr;
-
     if (graph.get())
         graph->addTextId(textId, str);
 
+    nextTextId++;
+
+    if (!pointerMap.add(p, text, payload))
+        return nullptr;
+
     return payload;
 }
 
@@ -407,9 +413,14 @@ TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type, const char* f
     if (!traceLoggerState->isTextIdEnabled(type))
         return getOrCreateEventPayload(type);
 
-    PointerHashMap::AddPtr p = pointerMap.lookupForAdd(ptr);
-    if (p)
-        return p->value();
+    PointerHashMap::AddPtr p;
+    if (ptr) {
+        p = pointerMap.lookupForAdd(ptr);
+        if (p) {
+            MOZ_ASSERT(p->value()->textId() < nextTextId); // Sanity check.
+            return p->value();
+        }
+    }
 
     // Compute the length of the string to create.
     size_t lenFilename = strlen(filename);
@@ -428,24 +439,28 @@ TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type, const char* f
     MOZ_ASSERT(ret == len);
     MOZ_ASSERT(strlen(str) == len);
 
-    uint32_t textId = extraTextId.count() + TraceLogger_Last;
+    uint32_t textId = nextTextId;
     TraceLoggerEventPayload* payload = js_new<TraceLoggerEventPayload>(textId, str);
     if (!payload) {
         js_free(str);
         return nullptr;
     }
 
-    if (!extraTextId.putNew(textId, payload)) {
+    if (!textIdPayloads.putNew(textId, payload)) {
         js_delete(payload);
         return nullptr;
     }
 
-    if (!pointerMap.add(p, ptr, payload))
-        return nullptr;
-
     if (graph.get())
         graph->addTextId(textId, str);
 
+    nextTextId++;
+
+    if (ptr) {
+        if (!pointerMap.add(p, ptr, payload))
+            return nullptr;
+    }
+
     return payload;
 }
 
@@ -453,14 +468,14 @@ TraceLoggerEventPayload*
 TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type, JSScript* script)
 {
     return getOrCreateEventPayload(type, script->filename(), script->lineno(), script->column(),
-                                   script);
+                                   nullptr);
 }
 
 TraceLoggerEventPayload*
 TraceLoggerThread::getOrCreateEventPayload(TraceLoggerTextId type,
                                            const JS::ReadOnlyCompileOptions& script)
 {
-    return getOrCreateEventPayload(type, script.filename(), script.lineno, script.column, &script);
+    return getOrCreateEventPayload(type, script.filename(), script.lineno, script.column, nullptr);
 }
 
 void
@@ -485,7 +500,7 @@ TraceLoggerThread::startEvent(uint32_t id)
     if (!traceLoggerState->isTextIdEnabled(id))
        return;
 
-    logTimestamp(id);
+    log(id);
 }
 
 void
@@ -510,7 +525,7 @@ TraceLoggerThread::stopEvent(uint32_t id)
     if (!traceLoggerState->isTextIdEnabled(id))
         return;
 
-    logTimestamp(TraceLogger_Stop);
+    log(TraceLogger_Stop);
 }
 
 void
@@ -522,23 +537,57 @@ TraceLoggerThread::logTimestamp(TraceLoggerTextId id)
 void
 TraceLoggerThread::logTimestamp(uint32_t id)
 {
+    MOZ_ASSERT(id > TraceLogger_LastTreeItem && id < TraceLogger_Last);
+    log(id);
+}
+
+void
+TraceLoggerThread::log(uint32_t id)
+{
     if (enabled == 0)
         return;
 
     MOZ_ASSERT(traceLoggerState);
-    if (!events.ensureSpaceBeforeAdd()) {
+
+    // We request for 3 items to add, since if we don't have enough room
+    // we record the time it took to make more place. To log this information
+    // we need 2 extra free entries.
+    if (!events.hasSpaceForAdd(3)) {
         uint64_t start = rdtsc() - traceLoggerState->startupTime;
 
-        if (graph.get())
-            graph->log(events);
+        if (!events.ensureSpaceBeforeAdd(3)) {
+            if (graph.get())
+                graph->log(events);
+
+            iteration_++;
+            events.clear();
+
+            // Remove the item in the pointerMap for which the payloads
+            // have no uses anymore
+            for (PointerHashMap::Enum e(pointerMap); !e.empty(); e.popFront()) {
+                if (e.front().value()->uses() != 0)
+                    continue;
+
+                TextIdHashMap::Ptr p = textIdPayloads.lookup(e.front().value()->textId());
+                MOZ_ASSERT(p);
+                textIdPayloads.remove(p);
+
+                e.removeFront();
+            }
 
-        iteration_++;
-        events.clear();
+            // Free all payloads that have no uses anymore.
+            for (TextIdHashMap::Enum e(textIdPayloads); !e.empty(); e.popFront()) {
+                if (e.front().value()->uses() == 0) {
+                    js_delete(e.front().value());
+                    e.removeFront();
+                }
+            }
+        }
 
         // Log the time it took to flush the events as being from the
         // Tracelogger.
         if (graph.get()) {
-            MOZ_ASSERT(events.capacity() > 2);
+            MOZ_ASSERT(events.hasSpaceForAdd(2));
             EventEntry& entryStart = events.pushUninitialized();
             entryStart.time = start;
             entryStart.textId = TraceLogger_Internal;
@@ -548,13 +597,6 @@ TraceLoggerThread::logTimestamp(uint32_t id)
             entryStop.textId = TraceLogger_Stop;
         }
 
-        // Free all TextEvents that have no uses anymore.
-        for (TextIdHashMap::Enum e(extraTextId); !e.empty(); e.popFront()) {
-            if (e.front().value()->uses() == 0) {
-                js_delete(e.front().value());
-                e.removeFront();
-            }
-        }
     }
 
     uint64_t time = rdtsc() - traceLoggerState->startupTime;
@@ -956,3 +998,16 @@ TraceLoggerEvent::~TraceLoggerEvent()
     if (payload_)
         payload_->release();
 }
+
+TraceLoggerEvent&
+TraceLoggerEvent::operator=(const TraceLoggerEvent& other)
+{
+    if (hasPayload())
+        payload()->release();
+    if (other.hasPayload())
+        other.payload()->use();
+
+    payload_ = other.payload_;
+
+    return *this;
+}
diff --git a/js/src/vm/TraceLogging.h b/js/src/vm/TraceLogging.h
index a124dcb..91a1eb0 100644
--- a/js/src/vm/TraceLogging.h
+++ b/js/src/vm/TraceLogging.h
@@ -110,6 +110,9 @@ class TraceLoggerEvent {
     bool hasPayload() const {
         return !!payload_;
     }
+
+    TraceLoggerEvent& operator=(const TraceLoggerEvent& other);
+    TraceLoggerEvent(const TraceLoggerEvent& event) = delete;
 };
 
 /**
@@ -130,6 +133,10 @@ class TraceLoggerEventPayload {
         uses_(0)
     { }
 
+    ~TraceLoggerEventPayload() {
+        MOZ_ASSERT(uses_ == 0);
+    }
+
     uint32_t textId() {
         return textId_;
     }
@@ -166,7 +173,8 @@ class TraceLoggerThread
     mozilla::UniquePtr<TraceLoggerGraph> graph;
 
     PointerHashMap pointerMap;
-    TextIdHashMap extraTextId;
+    TextIdHashMap textIdPayloads;
+    uint32_t nextTextId;
 
     ContinuousSpace<EventEntry> events;
 
@@ -181,6 +189,7 @@ class TraceLoggerThread
       : enabled(0),
         failed(false),
         graph(),
+        nextTextId(TraceLogger_Last),
         iteration_(0),
         top(nullptr)
     { }
@@ -195,22 +204,22 @@ class TraceLoggerThread
     bool enable(JSContext* cx);
     bool disable();
 
-    // Given the previous iteration and lastEntryId, return an array of events
+    // Given the previous iteration and size, return an array of events
     // (there could be lost events). At the same time update the iteration and
-    // lastEntry and gives back how many events there are.
-    EventEntry* getEventsStartingAt(uint32_t* lastIteration, uint32_t* lastEntryId, size_t* num) {
+    // size and gives back how many events there are.
+    EventEntry* getEventsStartingAt(uint32_t* lastIteration, uint32_t* lastSize, size_t* num) {
         EventEntry* start;
         if (iteration_ == *lastIteration) {
-            MOZ_ASSERT(events.lastEntryId() >= *lastEntryId);
-            *num = events.lastEntryId() - *lastEntryId;
-            start = events.data() + *lastEntryId + 1;
+            MOZ_ASSERT(*lastSize <= events.size());
+            *num = events.size() - *lastSize;
+            start = events.data() + *lastSize;
         } else {
-            *num = events.lastEntryId() + 1;
+            *num = events.size();
             start = events.data();
         }
 
         *lastIteration = iteration_;
-        *lastEntryId = events.lastEntryId();
+        *lastSize = events.size();
         return start;
     }
 
@@ -220,16 +229,16 @@ class TraceLoggerThread
                               const char** lineno, size_t* lineno_len, const char** colno,
                               size_t* colno_len);
 
-    bool lostEvents(uint32_t lastIteration, uint32_t lastEntryId) {
+    bool lostEvents(uint32_t lastIteration, uint32_t lastSize) {
         // If still logging in the same iteration, there are no lost events.
         if (lastIteration == iteration_) {
-            MOZ_ASSERT(lastEntryId <= events.lastEntryId());
+            MOZ_ASSERT(lastSize <= events.size());
             return false;
         }
 
-        // When proceeded to the next iteration and lastEntryId points to
-        // the maximum capacity there are no logs that are lost.
-        if (lastIteration + 1 == iteration_ && lastEntryId == events.capacity())
+        // If we are in a consecutive iteration we are only sure we didn't lose any events,
+        // when the lastSize equals the maximum size 'events' can get.
+        if (lastIteration == iteration_ - 1 && lastSize == events.maxSize())
             return false;
 
         return true;
@@ -268,6 +277,7 @@ class TraceLoggerThread
     void stopEvent(uint32_t id);
   private:
     void stopEvent();
+    void log(uint32_t id);
 
   public:
     static unsigned offsetOfEnabled() {
diff --git a/js/src/vm/TraceLoggingGraph.cpp b/js/src/vm/TraceLoggingGraph.cpp
index d1b7f2e..a4eb273 100644
--- a/js/src/vm/TraceLoggingGraph.cpp
+++ b/js/src/vm/TraceLoggingGraph.cpp
@@ -276,7 +276,7 @@ TraceLoggerGraph::flush()
         if (bytesWritten < tree.size())
             return false;
 
-        treeOffset += tree.lastEntryId();
+        treeOffset += tree.size();
         tree.clear();
     }
 
@@ -359,7 +359,7 @@ TraceLoggerGraph::startEventInternal(uint32_t id, uint64_t timestamp)
 
     if (parent.lastChildId() == 0) {
         MOZ_ASSERT(!entry.hasChildren());
-        MOZ_ASSERT(parent.treeId() == tree.lastEntryId() + treeOffset);
+        MOZ_ASSERT(parent.treeId() == treeOffset + tree.size() - 1);
 
         if (!updateHasChildren(parent.treeId()))
             return false;
diff --git a/js/src/vm/TraceLoggingTypes.h b/js/src/vm/TraceLoggingTypes.h
index f1c9d0c..10b76d6 100644
--- a/js/src/vm/TraceLoggingTypes.h
+++ b/js/src/vm/TraceLoggingTypes.h
@@ -21,7 +21,6 @@
     _(Internal)                                       \
     _(Interpreter)                                    \
     _(InlinedScripts)                                 \
-    _(Invalidation)                                   \
     _(IonCompilation)                                 \
     _(IonCompilationPaused)                           \
     _(IonLinking)                                     \
@@ -60,6 +59,7 @@
 
 #define TRACELOGGER_LOG_ITEMS(_)                      \
     _(Bailout)                                        \
+    _(Invalidation)                                   \
     _(Disable)                                        \
     _(Enable)                                         \
     _(Stop)
@@ -130,6 +130,9 @@ class ContinuousSpace {
     uint32_t size_;
     uint32_t capacity_;
 
+    // The maximum amount of ram memory a continuous space structure can take (in bytes).
+    static const uint32_t LIMIT = 200 * 1024 * 1024;
+
   public:
     ContinuousSpace ()
      : data_(nullptr)
@@ -151,6 +154,10 @@ class ContinuousSpace {
         data_ = nullptr;
     }
 
+    static uint32_t maxSize() {
+        return LIMIT / sizeof(T);
+    }
+
     T* data() {
         return data_;
     }
@@ -187,11 +194,14 @@ class ContinuousSpace {
         if (hasSpaceForAdd(count))
             return true;
 
+        // Limit the size of a continuous buffer.
+        if (size_ + count > maxSize())
+            return false;
+
         uint32_t nCapacity = capacity_ * 2;
-        if (size_ + count > nCapacity)
-            nCapacity = size_ + count;
-        T* entries = (T*) js_realloc(data_, nCapacity * sizeof(T));
+        nCapacity = (nCapacity < maxSize()) ? nCapacity : maxSize();
 
+        T* entries = (T*) js_realloc(data_, nCapacity * sizeof(T));
         if (!entries)
             return false;
 

A gnu/packages/patches/mozjs38-version-detection.patch => gnu/packages/patches/mozjs38-version-detection.patch +180 -0
@@ 0,0 1,180 @@
Taken from
https://trac.wildfiregames.com/export/18656/ps/trunk/libraries/source/spidermonkey/FixVersionDetectionConfigure.diff.

Fixes a version detection issue in 0ad.  See
https://lists.gnu.org/archive/html/guix-devel/2017-01/msg00625.html.

diff --git a/js/src/configure b/js/src/configure
--- a/js/src/configure
+++ b/js/src/configure
@@ -1662,70 +1662,6 @@ esac
 
 fi
 
-MOZILLA_VERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir`
-MOZILLA_UAVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir --uaversion`
-MOZILLA_SYMBOLVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir --symbolversion`
-
-cat >> confdefs.pytmp <<EOF
-    (''' MOZILLA_VERSION ''', r''' "$MOZILLA_VERSION" ''')
-EOF
-cat >> confdefs.h <<EOF
-#define MOZILLA_VERSION "$MOZILLA_VERSION"
-EOF
-
-cat >> confdefs.pytmp <<EOF
-    (''' MOZILLA_VERSION_U ''', r''' $MOZILLA_VERSION ''')
-EOF
-cat >> confdefs.h <<EOF
-#define MOZILLA_VERSION_U $MOZILLA_VERSION
-EOF
-
-cat >> confdefs.pytmp <<EOF
-    (''' MOZILLA_UAVERSION ''', r''' "$MOZILLA_UAVERSION" ''')
-EOF
-cat >> confdefs.h <<EOF
-#define MOZILLA_UAVERSION "$MOZILLA_UAVERSION"
-EOF
-
-
-
-# Separate version into components for use in shared object naming etc
-
-MOZJS_MAJOR_VERSION=`echo $MOZILLA_VERSION | sed "s|\(^[0-9]*\)\.[0-9]*.*|\1|"`
-MOZJS_MINOR_VERSION=`echo $MOZILLA_VERSION | sed "s|^[0-9]*\.\([0-9]*\).*|\1|"`
-MOZJS_PATCH_VERSION=`echo $MOZILLA_VERSION | sed "s|^[0-9]*\.[0-9]*[^0-9]*||"`
-IS_ALPHA=`echo $MOZILLA_VERSION | grep '[ab]'`
-
-JS_SHELL_NAME=js
-JS_CONFIG_NAME=js-config
-
-
-if test -n "$IS_ALPHA"; then
-  
-  MOZJS_ALPHA=`echo $MOZILLA_VERSION | sed "s|^[0-9]*\.[0-9\.]*\([^0-9]\).*|\1|"`
-  
-fi
-cat >> confdefs.pytmp <<EOF
-    (''' MOZJS_MAJOR_VERSION ''', r''' $MOZJS_MAJOR_VERSION ''')
-EOF
-cat >> confdefs.h <<EOF
-#define MOZJS_MAJOR_VERSION $MOZJS_MAJOR_VERSION
-EOF
-
-cat >> confdefs.pytmp <<EOF
-    (''' MOZJS_MINOR_VERSION ''', r''' $MOZJS_MINOR_VERSION ''')
-EOF
-cat >> confdefs.h <<EOF
-#define MOZJS_MINOR_VERSION $MOZJS_MINOR_VERSION
-EOF
-
-
-
-
-
-
-
-
 
 AR_FLAGS='crs $@'
 
@@ -5731,6 +5565,71 @@ XCFLAGS="$X_CFLAGS"
 
 fi # COMPILE_ENVIRONMENT
 
+MOZILLA_VERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir`
+MOZILLA_UAVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir --uaversion`
+MOZILLA_SYMBOLVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir --symbolversion`
+
+cat >> confdefs.pytmp <<EOF
+    (''' MOZILLA_VERSION ''', r''' "$MOZILLA_VERSION" ''')
+EOF
+cat >> confdefs.h <<EOF
+#define MOZILLA_VERSION "$MOZILLA_VERSION"
+EOF
+
+cat >> confdefs.pytmp <<EOF
+    (''' MOZILLA_VERSION_U ''', r''' $MOZILLA_VERSION ''')
+EOF
+cat >> confdefs.h <<EOF
+#define MOZILLA_VERSION_U $MOZILLA_VERSION
+EOF
+
+cat >> confdefs.pytmp <<EOF
+    (''' MOZILLA_UAVERSION ''', r''' "$MOZILLA_UAVERSION" ''')
+EOF
+cat >> confdefs.h <<EOF
+#define MOZILLA_UAVERSION "$MOZILLA_UAVERSION"
+EOF
+
+
+
+# Separate version into components for use in shared object naming etc
+
+MOZJS_MAJOR_VERSION=`echo $MOZILLA_VERSION | sed "s|\(^[0-9]*\)\.[0-9]*.*|\1|"`
+MOZJS_MINOR_VERSION=`echo $MOZILLA_VERSION | sed "s|^[0-9]*\.\([0-9]*\).*|\1|"`
+MOZJS_PATCH_VERSION=`echo $MOZILLA_VERSION | sed "s|^[0-9]*\.[0-9]*[^0-9]*||"`
+IS_ALPHA=`echo $MOZILLA_VERSION | grep '[ab]'`
+
+JS_SHELL_NAME=js
+JS_CONFIG_NAME=js-config
+
+
+if test -n "$IS_ALPHA"; then
+  
+  MOZJS_ALPHA=`echo $MOZILLA_VERSION | sed "s|^[0-9]*\.[0-9\.]*\([^0-9]\).*|\1|"`
+  
+fi
+cat >> confdefs.pytmp <<EOF
+    (''' MOZJS_MAJOR_VERSION ''', r''' $MOZJS_MAJOR_VERSION ''')
+EOF
+cat >> confdefs.h <<EOF
+#define MOZJS_MAJOR_VERSION $MOZJS_MAJOR_VERSION
+EOF
+
+cat >> confdefs.pytmp <<EOF
+    (''' MOZJS_MINOR_VERSION ''', r''' $MOZJS_MINOR_VERSION ''')
+EOF
+cat >> confdefs.h <<EOF
+#define MOZJS_MINOR_VERSION $MOZJS_MINOR_VERSION
+EOF
+
+
+
+
+
+
+
+
+
 AS_BIN=$AS
 AR_LIST='$(AR) t'
 AR_EXTRACT='$(AR) x'
@@ -16003,13 +15908,6 @@ sed 's/$/,/' >> $CONFIG_STATUS <<EOF
     (''' ANDROID_NDK ''', r''' $ANDROID_NDK ''')
     (''' ANDROID_TOOLCHAIN ''', r''' $ANDROID_TOOLCHAIN ''')
     (''' ANDROID_PLATFORM ''', r''' $ANDROID_PLATFORM ''')
-    (''' MOZILLA_SYMBOLVERSION ''', r''' $MOZILLA_SYMBOLVERSION ''')
-    (''' JS_SHELL_NAME ''', r''' $JS_SHELL_NAME ''')
-    (''' JS_CONFIG_NAME ''', r''' $JS_CONFIG_NAME ''')
-    (''' MOZJS_MAJOR_VERSION ''', r''' $MOZJS_MAJOR_VERSION ''')
-    (''' MOZJS_MINOR_VERSION ''', r''' $MOZJS_MINOR_VERSION ''')
-    (''' MOZJS_PATCH_VERSION ''', r''' $MOZJS_PATCH_VERSION ''')
-    (''' MOZJS_ALPHA ''', r''' $MOZJS_ALPHA ''')
     (''' HOST_CC ''', r''' $HOST_CC ''')
     (''' HOST_CXX ''', r''' $HOST_CXX ''')
     (''' HOST_RANLIB ''', r''' $HOST_RANLIB ''')
@@ -16061,6 +15959,13 @@ sed 's/$/,/' >> $CONFIG_STATUS <<EOF
     (''' X_PRE_LIBS ''', r''' $X_PRE_LIBS ''')
     (''' X_LIBS ''', r''' $X_LIBS ''')
     (''' X_EXTRA_LIBS ''', r''' $X_EXTRA_LIBS ''')
+    (''' MOZILLA_SYMBOLVERSION ''', r''' $MOZILLA_SYMBOLVERSION ''')
+    (''' JS_SHELL_NAME ''', r''' $JS_SHELL_NAME ''')
+    (''' JS_CONFIG_NAME ''', r''' $JS_CONFIG_NAME ''')
+    (''' MOZJS_MAJOR_VERSION ''', r''' $MOZJS_MAJOR_VERSION ''')
+    (''' MOZJS_MINOR_VERSION ''', r''' $MOZJS_MINOR_VERSION ''')
+    (''' MOZJS_PATCH_VERSION ''', r''' $MOZJS_PATCH_VERSION ''')
+    (''' MOZJS_ALPHA ''', r''' $MOZJS_ALPHA ''')
     (''' SOLARIS_SUNPRO_CC ''', r''' $SOLARIS_SUNPRO_CC ''')
     (''' SOLARIS_SUNPRO_CXX ''', r''' $SOLARIS_SUNPRO_CXX ''')
     (''' MOZ_THUMB2 ''', r''' $MOZ_THUMB2 ''')