Closed Bug 1359653 Opened 7 years ago Closed 7 years ago

Pre-load scripts needed during startup in a background thread

Categories

(Core :: XPConnect, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla55
Performance Impact high
Tracking Status
firefox55 --- fixed

People

(Reporter: kmag, Assigned: kmag)

References

(Depends on 2 open bugs, Blocks 2 open bugs)

Details

Attachments

(9 files)

59 bytes, text/x-review-board-request
erahm
: review+
shu
: review+
Details
59 bytes, text/x-review-board-request
shu
: review+
Details
59 bytes, text/x-review-board-request
shu
: review+
Details
59 bytes, text/x-review-board-request
Waldo
: review+
Details
59 bytes, text/x-review-board-request
shu
: review+
Details
59 bytes, text/x-review-board-request
mccr8
: review+
shu
: review+
Details
59 bytes, text/x-review-board-request
billm
: review+
Details
59 bytes, text/x-review-board-request
jimb
: review+
Details
59 bytes, text/x-review-board-request
erahm
: review+
Details
      No description provided.
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

Not really sure who should review this at this point, so f?ing some likely people:

I've been working on improving our startup performance in a lot of different
areas, mainly for the sake of shipping WebExtensions as system add-ons. One of
the things that I've noticed is that, even with the startup cache, we spend
about 130ms just loading and decoding scripts from the startup cache.

I think we should be able to do better than that by doing some of that work in
the background for scripts that we know we'll need during startup.

I've been doing some experiments, and the crude prototype I have so far seems
to save around 2.5-4% on sessionrestore and ts_paint tests on talos. But
there's a lot of room for tuning, and I think we get some considerable
improvement with a few tweaks:

https://treeherder.mozilla.org/perf.html#/compare?originalProject=mozilla-inbound&originalRevision=3c9671705cdaca87c9bf94b2890108d62cacdc40&newProject=try&newRevision=4e55863a77200519f1cf434352d6b0720b8c679e&framework=1&showOnlyImportant=0

Some notes about the approach I took:

- Setting up the off-thread compile is fairly expensive, since we need to
create a global object, and a lot of its built-in prototype objects for each
compile. Shu doesn't think there's any easy way to improve that at this point,
but we might be able to with some significant investment. So in order for
there to be a performance improvement for OMT compiles, the script has to be
pretty large. Right now, the tipping point seems to be about 20K.

- The time we spend setting up scripts for OMT compile is almost entirely
CPU-bound. That means that we have a chunk of about 20-50ms where we can
safely schedule thread-safe IO work during early startup, so if we schedule
some of our current synchronous IO operations on background threads during the
script cache setup, we basically get them for free, and can probably increase
the number of scripts we compile in the background.

- I went with an uncompressed mmap of the raw XDR data for a storage format.
That currently occupies about 5MB of disk space. Gzipped, it's ~1.2MB, so
compressing it might save some startup disk IO, but keeping it uncompressed
simplifies a lot of the OMT and even main thread decoding process, but, more
importantly:

- We currently don't use the startup cache in content processes, for a variety
of reasons. However, with this approach, I think we can safely store the
cached script data from a content process before we load any untrusted code
into it, and then share mmapped startup cache data between all content
processes. That should speed up content process startup *a lot*, and very
likely save memory, too. And:

- If we're especially concerned about saving per-process memory, and we keep
the cache data mapped for the lifetime of the JS runtime, I think that with
some effort we can probably share the static string data from scripts between
content processes, without any copying. Right now, it looks like for the main
process, there's about 1.5MB of string-ish data in the XDR dumps. It's
probably less for content processes, but if we could save .5MB per process
this way, it might make it easier to increase the number of content processes
we allow.
Attachment #8861706 - Flags: feedback?(shu)
Attachment #8861706 - Flags: feedback?(ehsan)
Attachment #8861706 - Flags: feedback?(benjamin)
Thanks a lot for working on this, it's a huge help.

(In reply to Kris Maglione [:kmag] from comment #2)
> - We currently don't use the startup cache in content processes, for a
> variety
> of reasons.

So I had high hopes for enabling the startup cache for the content process and tried out a raw hack a while ago but the result was very unimpressive on content process startup :( (still is worth to do just didn't make sense to block the release on it). Do you have numbers how much it helps? I might have missed something back then.

A good way to quickly measure the impact is to run the tabpaint talos test without forcing it to use single content process (http://searchfox.org/mozilla-central/source/testing/talos/talos/tests/tabpaint/bootstrap.js#76)

> - If we're especially concerned about saving per-process memory, and we keep
> the cache data mapped for the lifetime of the JS runtime, I think that with
> some effort we can probably share the static string data from scripts between
> content processes, without any copying. Right now, it looks like for the main
> process, there's about 1.5MB of string-ish data in the XDR dumps. It's
> probably less for content processes, but if we could save .5MB per process
> this way, it might make it easier to increase the number of content processes
> we allow.

Is there a way to share all these scripts? All these scripts should be static anyway, no?
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

I'm not a good person to provide feedback here, but I suggest you reach out to njn and erahm for memshrink, threading, and other general expertise.
Attachment #8861706 - Flags: feedback?(benjamin)
(In reply to Gabor Krizsanits [:krizsa :gabor] from comment #3)
> So I had high hopes for enabling the startup cache for the content process
> and tried out a raw hack a while ago but the result was very unimpressive on
> content process startup :( (still is worth to do just didn't make sense to
> block the release on it). Do you have numbers how much it helps? I might
> have missed something back then.

No, I haven't tested this for content processes yet. There's a significant
amount of extra work required for that, and I wanted to ask for feedback as
soon as I got to the point where I could show whether this would have an
advantage.

But I think this should have a much bigger benefit for content processes than
the normal startup cache for a few reasons:

- It has much less overhead than the normal startup cache. It only deals with
scripts that are needed during early startup, and those only get written out
once, in a single chunk. And for content processes, we'd have a separate cache
file that would only contain the scripts needed for content process startup.

- The mmapped data would be shared between processes, so as long as it hasn't
been unmapped between process startups, it shouldn't require any additional IO
for subsequent content processes. In theory this is also the case for the
normal startup cache, but that gets updated during runtime, and has a lot of
non-contiguous data, so I think we miss a lot of opportunities for sharing.

- Large scripts are pre-compiled in a background thread early during process
startup. That helps in the normal case, but I suspect it will help even more
when we're blocked on sync IPC, where the background threads will be able to
continue compiling scripts even if the JS runtime is blocked in the main
thread.

> > - If we're especially concerned about saving per-process memory, and we keep
> > the cache data mapped for the lifetime of the JS runtime, I think that with
> > some effort we can probably share the static string data from scripts between
> > content processes, without any copying. Right now, it looks like for the main
> > process, there's about 1.5MB of string-ish data in the XDR dumps. It's
> > probably less for content processes, but if we could save .5MB per process
> > this way, it might make it easier to increase the number of content processes
> > we allow.
>
> Is there a way to share all these scripts? All these scripts should be
> static anyway, no?

You mean share the decoded scripts between processes? No, the decoded scripts
are arena allocated and tied to the JS runtime. But we can definitely share
the XDR data, and we can *probably* share static string data, and maybe even
XDR data for things like lazified functions.
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

Adding njn and erahm per comment 4.
Attachment #8861706 - Flags: feedback?(n.nethercote)
Attachment #8861706 - Flags: feedback?(erahm)
(In reply to Kris Maglione [:kmag] from comment #2)
> - Setting up the off-thread compile is fairly expensive, since we need to
> create a global object, and a lot of its built-in prototype objects for each
> compile. Shu doesn't think there's any easy way to improve that at this
> point, but we might be able to with some significant investment. So in order
> for there to be a performance improvement for OMT compiles, the script has
> to be pretty large. Right now, the tipping point seems to be about 20K.

Another possibility here is to batch the loads of several smaller scripts into
one OMT compiler operation, so we only need a single setup and merge operation
for all of them. Shu things this should be possible, so I'll probably look
into it as a follow-up.
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review137156

There is a lot in this patch that is way outside my reviewing comfort zone. I went through and made a few comments in places, though.

::: js/xpconnect/loader/ScriptPreloader.h:75
(Diff revision 1)
> +    T* Get() { MOZ_ASSERT(mAddr); return static_cast<T*>(mAddr); }
> +
> +    template<typename T = void>
> +    const T* Get() const { MOZ_ASSERT(mAddr); return static_cast<const T*>(mAddr); }
> +
> +    size_t SizeOfExcludingThis() { return mSize; }

I'd probably call this NonHeapSizeOfExcludingThis(), to make clear it's measuring the mmap memory. (We have precedent for this in VolatileBuffer, for example.)

::: js/xpconnect/loader/ScriptPreloader.h:156
(Diff revision 1)
> +
> +    Vector<uint8_t> mXDRData;
> +  };
> +
> +  // There's a trade-off between the time it takes to setup an off-thread
> +  // decode and the time we safe by doing the decode off-thread. At this

*save

::: js/xpconnect/loader/ScriptPreloader.h:157
(Diff revision 1)
> +    Vector<uint8_t> mXDRData;
> +  };
> +
> +  // There's a trade-off between the time it takes to setup an off-thread
> +  // decode and the time we safe by doing the decode off-thread. At this
> +  // point, the setup is quite espensive, and 20K is about where we start to

*expensive

::: js/xpconnect/loader/ScriptPreloader.h:194
(Diff revision 1)
> +  {
> +    return mallocSizeOf(this);
> +  }
> +
> +  template<typename T>
> +  size_t SizeOfLinkedList(LinkedList<T>& list, mozilla::MallocSizeOf mallocSizeOf)

Should this be |static|?

::: js/xpconnect/loader/ScriptPreloader.cpp:272
(Diff revision 1)
> +    SizeOfLinkedList(mRestoredScripts, MallocSizeOf),
> +    "Memory used to hold the scripts which have been restored from the "
> +    "startup script cache file, but have not been executed in this session.");
> +
> +  MOZ_COLLECT_REPORT(
> +    "explicit/startup-cache/service", KIND_HEAP, UNITS_BYTES,

Do you really want "/startup-cache/" here, rather than "/script-preloader/"? (I'm not sure.)
Attachment #8861706 - Flags: feedback?(n.nethercote)
(In reply to Kris Maglione [:kmag] from comment #5)
> But I think this should have a much bigger benefit for content processes than
> the normal startup cache for a few reasons:

I think you should try to talk to :bholley about this since he is the owner of this code, but I'm afraid he will be too busy to do all the review. The other person I would definitely talk to is :jandem, he worked on sharing JS internal bits between processes and in general I think he will feel comfortable reviewing this patch, and I would expect Bobby to fully trust his review.

> > Is there a way to share all these scripts? All these scripts should be
> > static anyway, no?
> 
> You mean share the decoded scripts between processes? No, the decoded scripts
> are arena allocated and tied to the JS runtime. But we can definitely share
> the XDR data, and we can *probably* share static string data, and maybe even
> XDR data for things like lazified functions.

We do cache the compiled scripts/functions [1], I was thinking something at that level. So as much I understand it right now we compile the scripts at the first occurrence then cache them in an XDR encoded format. But then if we compile all scripts only once, does it make sense to do OMT compile? Or should we do the XDR decode part only OMT?

Now for the content process there are two reasons why we don't have startup cache, one is that it's dynamic and synchronization would be a PITA. The other is sandboxing, only the parent process can write to a file. I guess you will have to deal with the later issue... but I think you can pass file handles to an already opened file so it should not be that bad.

I also wonder if we could use the same cache for frame/process scripts later...

[1] http://searchfox.org/mozilla-central/rev/ce5ccb6a8ca803271c946ccb8b43b7e7d8b64e7a/js/xpconnect/loader/mozJSComponentLoader.cpp#855
(In reply to Gabor Krizsanits [:krizsa :gabor] from comment #9)
> (In reply to Kris Maglione [:kmag] from comment #5)
> > But I think this should have a much bigger benefit for content processes than
> > the normal startup cache for a few reasons:
> 
> I think you should try to talk to :bholley about this since he is the owner
> of this code, but I'm afraid he will be too busy to do all the review. The
> other person I would definitely talk to is :jandem, he worked on sharing JS
> internal bits between processes and in general I think he will feel
> comfortable reviewing this patch, and I would expect Bobby to fully trust
> his review.

Yeah, also billm and mccr8 could be good people to give feedback and review here. I have much less strong opinions about xpconnect/loader than I do about xpconnect/wrappers (and xpconnect/src, to some extent), so I'm happy to delegate that to the people actively working on this stuff.
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review137156

> I'd probably call this NonHeapSizeOfExcludingThis(), to make clear it's measuring the mmap memory. (We have precedent for this in VolatileBuffer, for example.)

Sounds reasonable.

> Should this be |static|?

Yeah, it probably should.

> Do you really want "/startup-cache/" here, rather than "/script-preloader/"? (I'm not sure.)

No, I meant it to be "script-preloader". I actually noticed this typo just after I pushed...
(In reply to Gabor Krizsanits [:krizsa :gabor] from comment #9)
> I think you should try to talk to :bholley about this since he is the owner
> of this code, but I'm afraid he will be too busy to do all the review. The
> other person I would definitely talk to is :jandem, he worked on sharing JS
> internal bits between processes and in general I think he will feel
> comfortable reviewing this patch, and I would expect Bobby to fully trust
> his review.

Thanks. I didn't CC bholley at this point since he hasn't had much to do with
the script loader lately and is pretty busy, but I'd definitely like his
sign-off before it lands.

> We do cache the compiled scripts/functions [1], I was thinking something at
> that level. So as much I understand it right now we compile the scripts at
> the first occurrence then cache them in an XDR encoded format.

Yes, that's essentially what this does, except that we get more cross-process
sharing since the data is directly mmapped rather than compressed, and
dynamically updated.

> But then if we compile all scripts only once, does it make sense to do OMT
> compile? Or should we do the XDR decode part only OMT?

Only the XDR decode part is OMT, but yes, it makes sense. The XDR decode part
is about 90ms of startup overhead on my (relatively high end) machine, plus
another 40-50ms for the startup cache read.. Doing it OMT cuts both of those
down to almost nothing, but the OMT compile setup currently adds enough extra
overhead that it's only worth doing for large scripts.

> Now for the content process there are two reasons why we don't have startup
> cache, one is that it's dynamic and synchronization would be a PITA. The
> other is sandboxing, only the parent process can write to a file. I guess
> you will have to deal with the later issue... but I think you can pass file
> handles to an already opened file so it should not be that bad.

My plan was to have the first content process send back the list of all
scripts that it had loaded during early startup, and XDR data for any that
weren't already in the cache, just before it executes any untrusted code.
After that point, no further updates would be accepted from any content
process, and they'd all share the read-only startup cache file that was
present at application startup (or probably the new one if there wasn't one
present at startup).

> I also wonder if we could use the same cache for frame/process scripts
> later...

Yes, I was planning on doing that before the first iteration lands, actually.
I actually meant to do it before I even pushed the initial f? patch, but I
forgot.
Whiteboard: [qf] → [qf:p1]
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review137452

I spent a few hours trying to understand this, I have a lot of rambling questions.

::: js/xpconnect/loader/ScriptPreloader.h:54
(Diff revision 1)
> +
> +protected:
> +  virtual ~ScriptPreloader() = default;
> +
> +private:
> +  class MOZ_RAII AutoMemMap

See prior art in [mozilla::devtools::AutoMemMap](http://searchfox.org/mozilla-central/source/devtools/shared/heapsnapshot/AutoMemMap.h). I imagine we could modify that to handle nsIFile if necessary.

::: js/xpconnect/loader/ScriptPreloader.h:89
(Diff revision 1)
> +    AutoMemMap(const AutoMemMap& aOther) = delete;
> +    void operator=(const AutoMemMap& aOther) = delete;
> +  };
> +
> +
> +  class Script : public LinkedListElement<Script>

Calling this just `Script` gets a bit confusing. Maybe `CacheableScript` or something would make more sense.

::: js/xpconnect/loader/ScriptPreloader.h:102
(Diff revision 1)
> +      , mScript(script)
> +      , mFinished(true)
> +    {}
> +
> +    template<typename Buffer>
> +    Script(Buffer& buf) { Code(buf); }

This is...odd, a constructor that writes empty values to a buffer?

After reading through I think I get what's going on, but maybe lets just not play games with templated constructors. This should only be used by `InputBuffer` right?

::: js/xpconnect/loader/ScriptPreloader.h:124
(Diff revision 1)
> +
> +    void
> +    AdoptData(uint8_t* buf, size_t size)
> +    {
> +      mRestored = true;
> +      return mXDRData.replaceRawBuffer(buf, size);

nit: Can remove return

::: js/xpconnect/loader/ScriptPreloader.cpp:105
(Diff revision 1)
> +  {
> +    return true;
> +  }
> +};
> +
> +using StaticVector = Vector<uint8_t, 0, NoAllocPolicy>;

I think you just want a Range? I'm not super sure what's going on here.

::: js/xpconnect/loader/ScriptPreloader.cpp:119
(Diff revision 1)
> +  }
> +
> +  void EnsureCapacity(size_t size);
> +
> +  uint8_t*
> +  Write(size_t size)

Probably better named `BeginWrite` or something, it's not actually writing.

::: js/xpconnect/loader/ScriptPreloader.cpp:124
(Diff revision 1)
> +  Write(size_t size)
> +  {
> +    if (mCursor + size > mData.capacity()) {
> +      EnsureCapacity(size);
> +    }
> +    mData.infallibleGrowByUninitialized(size);

If changing to nsTArray this would just be: buf = mData.AppendElements(size)

::: js/xpconnect/loader/ScriptPreloader.cpp:134
(Diff revision 1)
> +  }
> +
> +  void
> +  CodeUint16(const uint16_t& val)
> +  {
> +    LittleEndian::writeUint16(Write(2), val);

nit: use sizeof instead of 2 directly

::: js/xpconnect/loader/ScriptPreloader.cpp:140
(Diff revision 1)
> +  }
> +
> +  void
> +  CodeUint32(const uint32_t& val)
> +  {
> +    LittleEndian::writeUint32(Write(4), val);

Ditto

::: js/xpconnect/loader/ScriptPreloader.cpp:146
(Diff revision 1)
> +  }
> +
> +  void
> +  CodeString(const nsCString& str)
> +  {
> +    uint16_t len = str.Length();

You can use CheckedUint16 for this.

::: js/xpconnect/loader/ScriptPreloader.cpp:153
(Diff revision 1)
> +
> +    CodeUint16(len);
> +    memcpy(Write(len), str.BeginReading(), len);
> +  }
> +
> +  size_t Cursor() const { return mCursor; }

I *think* this should just be called `Length`, right?

::: js/xpconnect/loader/ScriptPreloader.cpp:161
(Diff revision 1)
> +  uint8_t* Get() { return mData.begin(); }
> +
> +  const uint8_t* Get() const { return mData.begin(); }
> +
> +private:
> +  Vector<uint8_t> mData;

Seems like nsTArray might be a better options, you get things like EnsuerCapacity and sane growth strategies for free.

::: js/xpconnect/loader/ScriptPreloader.cpp:197
(Diff revision 1)
> +  }
> +
> +  bool
> +  CodeUint16(uint16_t& val)
> +  {
> +    if (CheckCapacity(4)) {

4?

::: js/xpconnect/loader/ScriptPreloader.cpp:248
(Diff revision 1)
> +  }
> +
> +  bool mError = false;
> +
> +public:
> +  const StaticVector& mData;

Range or Span would probably work here.

::: js/xpconnect/loader/ScriptPreloader.cpp:290
(Diff revision 1)
> +ScriptPreloader&
> +ScriptPreloader::GetSingleton()
> +{
> +  static RefPtr<ScriptPreloader> singleton;
> +
> +  if (!singleton) {

Note this isn't thread-safe, I'm not sure if that's a concern here.

::: js/xpconnect/loader/ScriptPreloader.cpp:341
(Diff revision 1)
> +{
> +  if (mSaveThread) {
> +    MonitorAutoLock mal(mSaveMonitor);
> +
> +    // Prepare the cache data while we're on the main thread, so we don't
> +    // deadlock trying to dispatch the prepare operation to the main thread.

Perhaps add a main thread assert here.

::: js/xpconnect/loader/ScriptPreloader.cpp:342
(Diff revision 1)
> +  if (mSaveThread) {
> +    MonitorAutoLock mal(mSaveMonitor);
> +
> +    // Prepare the cache data while we're on the main thread, so we don't
> +    // deadlock trying to dispatch the prepare operation to the main thread.
> +    PrepareCache();

Why are we preparing in cleanup?

::: js/xpconnect/loader/ScriptPreloader.cpp:351
(Diff revision 1)
> +      mal.Wait();
> +    }
> +  }
> +
> +  mSavedScripts.~AutoCleanLinkedList();
> +  mRestoredScripts.~AutoCleanLinkedList();

There's gotta be a better way to do this...

Something like the following might do the job:
```
auto to_clear = Move(mSavedScripts);
```

::: js/xpconnect/loader/ScriptPreloader.cpp:429
(Diff revision 1)
> +  RegisterWeakMemoryReporter(this);
> +
> +  MOZ_TRY(OpenCache());
> +
> +  auto size = mCacheData.Size();
> +  if (size < sizeof(MAGIC) + 4) {

nit: use sizeof

::: js/xpconnect/loader/ScriptPreloader.cpp:442
(Diff revision 1)
> +    return Err(NS_ERROR_UNEXPECTED);
> +  }
> +  data += sizeof(MAGIC);
> +
> +  auto headerSize = LittleEndian::readUint32(data);
> +  data += 4;

nit: sizeof

::: js/xpconnect/loader/ScriptPreloader.cpp:450
(Diff revision 1)
> +    return Err(NS_ERROR_UNEXPECTED);
> +  }
> +
> +  {
> +    auto cleanup = MakeScopeExit([&] () {
> +      mRestoredScripts.~AutoCleanLinkedList();

you could just do:

```
AutoCleanLinkedList scripts;
//...
scripts.insertBack(script.release());
//...
mRestoredScripts = Move(scripts);
```

::: js/xpconnect/loader/ScriptPreloader.cpp:454
(Diff revision 1)
> +    auto cleanup = MakeScopeExit([&] () {
> +      mRestoredScripts.~AutoCleanLinkedList();
> +    });
> +
> +    StaticVector vec;
> +    vec.replaceRawBuffer(data, headerSize);

Again, `Range` is probably fine here.

::: js/xpconnect/loader/ScriptPreloader.cpp:475
(Diff revision 1)
> +      if (script->mOffset != offset) {
> +        return Err(NS_ERROR_UNEXPECTED);
> +      }
> +      offset += script->mSize;
> +
> +      script->AdoptData(scriptData, script->mSize);;

I don't fully understand this, adopting would imply ownership transfer, but I don't think we want that. We really want to copy right? Or is this more of a range type thing, where we want a portion of already allocated memory?

::: js/xpconnect/loader/ScriptPreloader.cpp:499
(Diff revision 1)
> +  for (auto script : mRestoredScripts) {
> +    if (script->mSize > MIN_OFFTHREAD_SIZE &&
> +        JS::CanCompileOffThread(cx, options, script->mSize)) {
> +      ParseScript(cx, script);
> +    } else {
> +      script->mFinished = true;

Could use some comments here, it's not clear what's going on. If it's too small we just don't try to parse it at all? Why keep it around?

::: js/xpconnect/loader/ScriptPreloader.cpp:532
(Diff revision 1)
> +
> +  for (Script* next = mSavedScripts.getFirst(); next; ) {
> +    Script* script = next;
> +    next = script->getNext();
> +
> +    if (!script->mSize && !script->Encode(jsapi.cx())) {

Again comments would be helpful here. So this is checking if we haven't encoded the script yet, tries to encode it and then removes it if we failed?

What's a situation where we've already encoded it?

::: js/xpconnect/loader/ScriptPreloader.cpp:548
(Diff revision 1)
> +  }
> +
> +  // Store async-compiled scripts contiguously, since they're loaded
> +  // immediately at startup.
> +  while (Script* s = asyncScripts.popLast()) {
> +    mSavedScripts.insertFront(s);

So `mSavedScripts` is really `mScriptsWeWantToSave` in this case, right?

::: js/xpconnect/loader/ScriptPreloader.cpp:570
(Diff revision 1)
> +
> +  PRFileDesc* fd = nullptr;
> +  NS_TRY(cacheFile->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE, 0644, &fd));
> +
> +  auto closeFd = MakeScopeExit([&] () {
> +    Unused << PR_Close(fd);

We have a scopedfd thing [1], but this is probably fine.

[1] http://searchfox.org/mozilla-central/rev/068e6f292503df13515a52321fc3844e237bf6a9/xpcom/glue/FileUtils.h#71

::: js/xpconnect/loader/ScriptPreloader.cpp:573
(Diff revision 1)
> +
> +  auto closeFd = MakeScopeExit([&] () {
> +    Unused << PR_Close(fd);
> +  });
> +
> +  if (!mDataPrepared) {

When would the data already be prepared?

::: js/xpconnect/loader/ScriptPreloader.cpp:575
(Diff revision 1)
> +    Unused << PR_Close(fd);
> +  });
> +
> +  if (!mDataPrepared) {
> +    NS_DispatchToMainThread(
> +      NewRunnableMethod(this, &ScriptPreloader::PrepareCache),

Okay so we have `InitCache` and `PrepareCache` and it's confusing :) I *think* `PrepareCache` is really `PrepareToWriteCacheToDiskButMainthreadOnlyStuff`, is that right?

If that's right, I'm kind of surprised we only allow xdr encoding on main thread...

::: js/xpconnect/loader/ScriptPreloader.cpp:583
(Diff revision 1)
> +
> +  OutputBuffer buf;
> +  size_t offset = 0;
> +  for (auto script : mSavedScripts) {
> +    script->mOffset = offset;
> +    script->Code(buf);

I'm not super stoked about encoding everything into a buffer and then writing it to the fd. It would be nice if we could write directly.

Ideally something like:

```
seek(fd, header_size)
for (script : scripts)
   script->Code(fd)

seek(fd, 0)
write_header
```

::: js/xpconnect/loader/ScriptPreloader.cpp:597
(Diff revision 1)
> +  MOZ_TRY(Write(fd, headerSize, sizeof(headerSize)));
> +  MOZ_TRY(Write(fd, buf.Get(), buf.Cursor()));
> +
> +  for (auto script : mSavedScripts) {
> +    MOZ_TRY(Write(fd, script->mXDRData.begin(), script->mSize));
> +    script->FreeData();

Why don't we just remove the script here?

::: js/xpconnect/loader/ScriptPreloader.cpp:612
(Diff revision 1)
> +{
> +  MonitorAutoLock mal(mSaveMonitor);
> +
> +  // Ideally wait about 10 seconds before saving, to avoid unnecessary IO
> +  // during early startup.
> +  mal.Wait(10000);

It seems like we could wait for a notification as well (not that I know which one is appropriate).

::: js/xpconnect/loader/ScriptPreloader.cpp:626
(Diff revision 1)
> +}
> +
> +ScriptPreloader::Script*
> +ScriptPreloader::FindScript(LinkedList<Script>& scripts, const nsCString& cachePath)
> +{
> +  for (auto script : scripts) {

We should be using a hashtable here

::: js/xpconnect/loader/ScriptPreloader.cpp:652
(Diff revision 1)
> +  if (existing) {
> +    existing->remove();
> +    mSavedScripts.insertBack(existing);
> +
> +    existing->mScript = script;
> +    existing->mFinished = true;

So is this saying: We loaded this script from the cache, but didn't use it and someone else loaded and now we're attaching that script object to it and moving it to saved.

Does that have weird implications if the script content changed?

::: js/xpconnect/loader/ScriptPreloader.cpp:677
(Diff revision 1)
> +}
> +
> +JSScript*
> +ScriptPreloader::WaitForCachedScript(JSContext* cx, Script* script)
> +{
> +  if (!script->mFinished) {

I think we're poking mFinished from multiple threads, it should at least be made atomic.

::: js/xpconnect/loader/ScriptPreloader.cpp:683
(Diff revision 1)
> +    printf_stderr("Must wait for async script load: %s\n", script->mURL.get());
> +    auto started = TimeStamp::Now();
> +
> +    MonitorAutoLock mal(mMonitor);
> +
> +    if (!script->mFinished && script->mSize < MAX_RECOMPILE_SIZE) {

Isn't `mSize == 0` if it's not finished?

::: js/xpconnect/loader/ScriptPreloader.cpp:747
(Diff revision 1)
> +
> +void
> +ScriptPreloader::Script::FreeData()
> +{
> +  if (mRestored) {
> +    StaticVector vec = Move(*reinterpret_cast<StaticVector*>(&mXDRData));

Comments would be helpful here, I have no idea what's going on but it looks super sketchy.

::: js/xpconnect/loader/ScriptPreloader.cpp:771
(Diff revision 1)
> +}
> +
> +JSScript*
> +ScriptPreloader::Script::GetJSScript(JSContext* cx)
> +{
> +  MOZ_ASSERT(mFinished);

I think maybe renaming `mFinished` would be helpful, I keep losing track of what it means. What's finished? Reading from the cache file?

::: js/xpconnect/loader/ScriptPreloader.cpp:776
(Diff revision 1)
> +  MOZ_ASSERT(mFinished);
> +  if (mScript) {
> +    return mScript;
> +  }
> +
> +  if (mXDRData.length() && !mToken) {

The lifetime of mToke is a little confusing to me.

So it's set if we call `ParseScript` (I think) once the off main thread decode callback is hit. So is this racing with that? Or is it definitely only called *after* `ParseScript` is complete?

::: js/xpconnect/loader/mozJSComponentLoader.cpp:857
(Diff revision 1)
>      // otherwise.
>      MOZ_ASSERT(!!script != !!function);
>      MOZ_ASSERT(!!script == JS_IsGlobalObject(obj));
>  
> +    if (script) {
> +        ScriptPreloader::GetSingleton().NoteScript(nativePath, cachePath, script);

Are there instances where we shouldn't note a script?

::: js/xpconnect/loader/mozJSComponentLoader.cpp:903
(Diff revision 1)
>                                   "component loader load module");
>          JSContext* aescx = aes.cx();
>          bool ok;
>          if (script) {
> -            ok = JS_ExecuteScript(aescx, script);
> +            JS::RootedValue rval(cx);
> +            ok = JS::CloneAndExecuteScript(aescx, script, &rval);

Why do we need to clone now? Are there instances where that's not necessary?

::: js/xpconnect/loader/mozJSSubScriptLoader.cpp:719
(Diff revision 1)
>      } else {
>          cache = nullptr;
>      }
>  
> +    if (script) {
> +        ScriptPreloader::GetSingleton().NoteScript(uriStr, cachePath, script);

Should we only note "cacheable" scripts?
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review137452

> See prior art in [mozilla::devtools::AutoMemMap](http://searchfox.org/mozilla-central/source/devtools/shared/heapsnapshot/AutoMemMap.h). I imagine we could modify that to handle nsIFile if necessary.

Yeah, I basically stole this from that, but I didn't feel comfortable using a devtools helper in xpconnect. Moving it to xpc and making it sharable might do, though.

> This is...odd, a constructor that writes empty values to a buffer?
> 
> After reading through I think I get what's going on, but maybe lets just not play games with templated constructors. This should only be used by `InputBuffer` right?

This is only used for reading the buffer, yes, so I suppose making it only accept InputBuffer rather than a template might be a good idea. The pattern was mostly inspred by Xdr, which handles encoding and decoding the same way.

> I think you just want a Range? I'm not super sure what's going on here.

Kind of. The main issue is the XDR decode code only accepts a Vector<uint8_t>, and I needed a way instantiate and destroy those without trying to realloc or free mmapped data. I'd like a better solution, but this was good enough for a prototype.

The other is that I want to reuse the same code for encoding and decoding, and that's easier if both types use a Vector. But I mostly just copied this pattern from Xdr, since the Xdr buffer code isn't public.

> If changing to nsTArray this would just be: buf = mData.AppendElements(size)

I know, I didn't like now much more complicated this is with Vectors. :( This code probably may as well use nsTArray. I originally went with Vector mainly for compatibility with XDR, but I wound up not using it directly.

> I *think* this should just be called `Length`, right?

For the output buffer, it could be, but I wanted consistency between the read and write code, and it is definitely a cursor rather than a length in the input code.

> There's gotta be a better way to do this...
> 
> Something like the following might do the job:
> ```
> auto to_clear = Move(mSavedScripts);
> ```

Hm. Maybe. I'd rather just add a clear method, to be honest, but I haven't gotten to that point yet. I want to make sure I'm on vaguely the right track before I start doing that kind of cleanup.

> I don't fully understand this, adopting would imply ownership transfer, but I don't think we want that. We really want to copy right? Or is this more of a range type thing, where we want a portion of already allocated memory?

It's more of a range type thing, yes, only it's mostly a terrible hack until I get feedback, and then find a cleaner way to pass a readonly chunk of data to XDR without copying.

> Could use some comments here, it's not clear what's going on. If it's too small we just don't try to parse it at all? Why keep it around?

I put the comments with the definition of MIN_OFFTHREAD_SIZE, but it could do with a mention here.

If it's too small, we decode it on the main thread when it's loaded, rather than trying to asynchronously parse it off-thread.

> Again comments would be helpful here. So this is checking if we haven't encoded the script yet, tries to encode it and then removes it if we failed?
> 
> What's a situation where we've already encoded it?

Yes.

When the script was loaded from the cache file at startup, it already has XDR data, so we write that back to the new cache file directly rather than encoding the script again.

> So `mSavedScripts` is really `mScriptsWeWantToSave` in this case, right?

Well, I was thinking of saved as "we saved this JSScript that we've already compiled, and will reuse it the next time the script is loaded, and write it to the cache file"

> We have a scopedfd thing [1], but this is probably fine.
> 
> [1] http://searchfox.org/mozilla-central/rev/068e6f292503df13515a52321fc3844e237bf6a9/xpcom/glue/FileUtils.h#71

Handy.

> When would the data already be prepared?

When we started shutting down before the write timeout ended, and the main thread prepared it so we wouldn't deadlock here.

> Okay so we have `InitCache` and `PrepareCache` and it's confusing :) I *think* `PrepareCache` is really `PrepareToWriteCacheToDiskButMainthreadOnlyStuff`, is that right?
> 
> If that's right, I'm kind of surprised we only allow xdr encoding on main thread...

Agree it's confusing, but yes. I'll try to come up with better names.

We only allow XDR encoding on the main thread because script data isn't threadsafe. Decoding offthread requires all sorts of special hacks to put everything in its own zone where we know it won't be touched by anything on the main thread until we eventually merge the zones on the main thread.

We don't have anything similar to encoding. We'd basically have to do the reverse, and clone the script into a new zone, and decode from that on the main thread. That might be worth doing for lazification, or something, but here it's probably not worth the effort.

> I'm not super stoked about encoding everything into a buffer and then writing it to the fd. It would be nice if we could write directly.
> 
> Ideally something like:
> 
> ```
> seek(fd, header_size)
> for (script : scripts)
>    script->Code(fd)
> 
> seek(fd, 0)
> write_header
> ```

The header size only comes to a few K in the worst of cases, and it doesn't stick around for long. I'd be willing to bet that encoding to a buffer first is considerably more efficient than encoding directly to a FD, and it's certainly simpler.

> Why don't we just remove the script here?

Because we may still need to reload it after this point. We definitely will in the case of frame scripts, for instance. But I don't have an especially strong opinion on that. They might not be worth keeping around except in particular cases.

> It seems like we could wait for a notification as well (not that I know which one is appropriate).

Not sure what you mean.

> We should be using a hashtable here

Yeah, I considered it, but this was good enough for a prototype, and I'm not sure how much a hashtable would actually buy us here.

> So is this saying: We loaded this script from the cache, but didn't use it and someone else loaded and now we're attaching that script object to it and moving it to saved.
> 
> Does that have weird implications if the script content changed?

It's saying "we loaded this script from the cache, and did use it, and are going to save it to the cache for the next startup". In practice, `mScript` should always be non-null here, I think, and `mFinished` should always be true, so it might make more sense to just assert that.

> I think we're poking mFinished from multiple threads, it should at least be made atomic.

It's always used with a lock in the cases where atomicity matters. The unguarded check is just an optimization so we can avoid locking where we don't need to.

> Isn't `mSize == 0` if it's not finished?

No, `mSize` is only 0 for scripts that weren't loaded from the cache, but are going to go into the next cache and haven't been encoded yet. Scripts loaded from the cache never have `mSize == 0`.

> Comments would be helpful here, I have no idea what's going on but it looks super sketchy.

It is super sketchy. I need a better solution before this gets closer to landing.

But basically, the XDR decoder only accepts a Vector<uint8_t> with the default MallocAllocPolicy for decoding. We can't pass a chunk of mmapped data to free(), though, so this prevents that from happing by moving the vector to one with allocation disabled.

> I think maybe renaming `mFinished` would be helpful, I keep losing track of what it means. What's finished? Reading from the cache file?

Finished decoding XDR data.

> The lifetime of mToke is a little confusing to me.
> 
> So it's set if we call `ParseScript` (I think) once the off main thread decode callback is hit. So is this racing with that? Or is it definitely only called *after* `ParseScript` is complete?

This is only ever called after `mFinished` is true, and `mFinished` and `mToken` are only changed when mMonitor is held. Once `mFinished` is true, `mToken` will never be changed except on the main thread, so there isn't a race here.

> Are there instances where we shouldn't note a script?

Not really. There are some corner cases where we compile things with different options that I still need to deal with, but in general, `NoteScript` takes care of deciding whether something needs to be done with the script, which is why I went with `Note` rather than `Save` or something like that.

> Why do we need to clone now? Are there instances where that's not necessary?

`CloneAndExecute` already checks whether the clone is actually necessary, and only clones if the script belongs to a different compartment than the target. The cloning is necessary because the scripts are compiled for `CompilationScope()` in the off-thread case.

At the moment, the final decoded script from the off-thread compile still winds up in the first target global that requests it, rather than the compilation scope (even though that's where the compile was started), but I'm not actually sure how safe that is, so it may have to change. But after that, it needs to be cloned for any other global that wants to load it.

> Should we only note "cacheable" scripts?

I'm pretty sure we only ever wind up with cachable scripts here. Or at least, I was when I wrote this, but I don't remember the exact details.
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review137518

I've just started reading this. I'd really like some big block comment, some of these method names are very generic and confused me.

What actually get written out to cache? A header for each script + its XDR data?

::: js/src/jscntxt.cpp:1450
(Diff revision 1)
>  
>      if (compartment() && compartment()->behaviors().version() != JSVERSION_UNKNOWN)
>          return compartment()->behaviors().version();
>  
> +    if (!CurrentThreadCanAccessRuntime(runtime()))
> +        return JSVERSION_LATEST;

Man it'd be really nice to get away from versions. Why the choice to return the LATEST instead of DEFAULT?

::: js/xpconnect/loader/ScriptPreloader.h:110
(Diff revision 1)
> +
> +    void FreeData();
> +    bool Encode(JSContext* cx);
> +
> +    template<typename Buffer>
> +    void Code(Buffer& buffer)

So... Encode() does the XDR encoding, and Code() encodes/decodes metadata about the script? Pretty confusing naming. :)

::: js/xpconnect/loader/ScriptPreloader.h:183
(Diff revision 1)
> +
> +  Script* FindScript(LinkedList<Script>& scripts, const nsCString& cachePath);
> +
> +  JSScript* WaitForCachedScript(JSContext* cx, Script* script);
> +
> +  void ParseScript(JSContext* cx, Script* script);

So this actually decodes (XDR data -> JSScript), not parses (text -> JSScript)?
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review137518

Yeah, sorry, I tried to put most of the block comments in the bug until I got initial feedback.

Yes, the cache file has a header block at the start with a header for each script, followed by the raw XDR data for all of the scripts in the header block.

> Man it'd be really nice to get away from versions. Why the choice to return the LATEST instead of DEFAULT?

Only because I don't expect this to ever be used for anything other than system code, which sometimes still required LATEST. But I'd be surprised if it ever made a difference for regexp parsing, so I wouldn't mind changing it to default.

> So... Encode() does the XDR encoding, and Code() encodes/decodes metadata about the script? Pretty confusing naming. :)

Yeah... that made me a bit uncomfortable too, but I tried to stick with the naming convention used in the XDR code, since this code is so closely linked to it...

> So this actually decodes (XDR data -> JSScript), not parses (text -> JSScript)?

Yeah, should be Decode rather than Parse.
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review137518

> Only because I don't expect this to ever be used for anything other than system code, which sometimes still required LATEST. But I'd be surprised if it ever made a difference for regexp parsing, so I wouldn't mind changing it to default.

(Or, at least, not before we get rid of versions)
(In reply to Kris Maglione [:kmag] from comment #12)
> Only the XDR decode part is OMT, but yes, it makes sense. The XDR decode part
> is about 90ms of startup overhead on my (relatively high end) machine, plus
> another 40-50ms for the startup cache read.. Doing it OMT cuts both of those
> down to almost nothing, but the OMT compile setup currently adds enough extra
> overhead that it's only worth doing for large scripts.

Makes sense.

> My plan was to have the first content process send back the list of all
> scripts that it had loaded

So in case of multiple concurrent process startups where each starts to build that list, the first that finishes will be the winner and we just ignore the other lists right? Anyway, I'm sure you can figure out the details just wanted to have the high level overview.

> Yes, I was planning on doing that before the first iteration lands, actually.
> I actually meant to do it before I even pushed the initial f? patch, but I
> forgot.

It's enough in this patch to process for the first feedback already so no worries :) But big thanks for that work too in advance!
Updated with comments, and cleanups for the dodgier prototype code now that I've gotten some initial feedback.
(In reply to Gabor Krizsanits [:krizsa :gabor] from comment #18)
> > My plan was to have the first content process send back the list of all
> > scripts that it had loaded
> 
> So in case of multiple concurrent process startups where each starts to
> build that list, the first that finishes will be the winner and we just
> ignore the other lists right?

I think we'd probably want to always use the data from the first content process we start, rather than the first one that finishes, so we don't waste any cycles encoding the new scripts in multiple processes. But, yeah, basically something along those lines.

> > Yes, I was planning on doing that before the first iteration lands, actually.
> > I actually meant to do it before I even pushed the initial f? patch, but I
> > forgot.
> 
> It's enough in this patch to process for the first feedback already so no
> worries :) But big thanks for that work too in advance!

Well, I added it in the last patch anyway, and it got the non-e10s ts_paint improvement to about 4.75% :) Feel free to look over it and chime in.
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review137452

> you could just do:
> 
> ```
> AutoCleanLinkedList scripts;
> //...
> scripts.insertBack(script.release());
> //...
> mRestoredScripts = Move(scripts);
> ```

LinkedLists aren't current Move-able, and they probably shouldn't be, since each list element has a reference to the list it belongs to, which makes moving them between lists fairly costly.
(In reply to Kris Maglione [:kmag] from comment #28)
> LinkedLists aren't current Move-able, and they probably shouldn't be, since
> each list element has a reference to the list it belongs to, which makes
> moving them between lists fairly costly.

I just started following this bug, but that's not true in the general case. LinkedList does have a Move constructor, and LinkedListElement doesn't keep a reference to its list.
(In reply to Bill McCloskey (:billm) from comment #29)
> (In reply to Kris Maglione [:kmag] from comment #28)
> > LinkedLists aren't current Move-able, and they probably shouldn't be, since
> > each list element has a reference to the list it belongs to, which makes
> > moving them between lists fairly costly.
> 
> I just started following this bug, but that's not true in the general case.
> LinkedList does have a Move constructor, and LinkedListElement doesn't keep
> a reference to its list.

Interesting. I guess it's only AutoCleanLinkedList that doesn't have a move constructor, then. Which also means I probably shouldn't have given up on prepending an entire list to another one in one operation so easily, then...
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review137814

Looks pretty good! Mainly just asking for clarification and comments. A few larger points are using hashtables for more efficient lookups and avoiding writing out the cache if we don't have to.

On a more boring note, this should probably be updated to use gecko style (I know xpconnect is a mess, but new stuff should use our style). Mainly that just means `aParams`.

::: js/xpconnect/loader/AutoMemMap.h:55
(Diff revision 2)
> +
> +  size_t NonHeapSizeOfExcludingThis() { return mSize; }
> +
> +  size_t HeapSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
> +  {
> +    return mallocSizeOf(mFd.get()) + mallocSizeOf(mFileMap);

We should probably just treat these as opaque handles and ignore them.

::: js/xpconnect/loader/ScriptPreloader.h:62
(Diff revision 2)
> +
> +protected:
> +  virtual ~ScriptPreloader() = default;
> +
> +private:
> +  class CachedScript : public LinkedListElement<CachedScript>

Can you add a comment here documenting the possible states of a CachedScript? The coments below are pretty good, but it would be nice to have a clear summary.

::: js/xpconnect/loader/ScriptPreloader.h:157
(Diff revision 2)
> +  };
> +
> +  // There's a trade-off between the time it takes to setup an off-thread
> +  // decode and the time we save by doing the decode off-thread. At this
> +  // point, the setup is quite expensive, and 20K is about where we start to
> +  // see an improvement rather than a regression.

What kind of hardware are we talking about here? What's the perf like on android or an old laptop?

::: js/xpconnect/loader/ScriptPreloader.cpp:36
(Diff revision 2)
> +
> +using mozilla::dom::AutoJSAPI;
> +using namespace mozilla::loader;
> +
> +nsresult
> +ScriptPreloader::CollectReports(nsIHandleReportCallback* aHandleReport,

It might make sense to add a non-explicit entry with the names and sizes of the cached scripts.

::: js/xpconnect/loader/ScriptPreloader.cpp:250
(Diff revision 2)
> +  {
> +    auto cleanup = MakeScopeExit([&] () {
> +      mRestoredScripts.Clear();
> +    });
> +
> +    Range<uint8_t> range(data, data + headerSize);

Perhaps `header` is a more descriptive name.

::: js/xpconnect/loader/ScriptPreloader.cpp:288
(Diff revision 2)
> +  AutoJSAPI jsapi;
> +  MOZ_RELEASE_ASSERT(jsapi.Init(xpc::CompilationScope()));
> +  JSContext* cx = jsapi.cx();
> +
> +  auto start = TimeStamp::Now();
> +  printf_stderr("Off-thread decoding scripts...\n");

This and other printfs should be converted to a MOZ_LOG

::: js/xpconnect/loader/ScriptPreloader.cpp:344
(Diff revision 2)
> +        asyncScripts.insertBack(script);
> +      }
> +    }
> +  }
> +
> +  // Store async-compiled scripts contiguously, since they're loaded

Maybe 'compiled' instead of 'loaded' here if I'm understanding correctly.

::: js/xpconnect/loader/ScriptPreloader.cpp:368
(Diff revision 2)
> +//   - The size of its XDR data in the XDR data block.
> +//
> +// - A block of XDR data for the encoded scripts, with each script's data at
> +//   an offset from the start of the block, as specified above.
> +Result<Ok, nsresult>
> +ScriptPreloader::WriteCache()

I feel like we should make an effort here to not write out the file if nothing changed. I'm not exactly sure how that would work as-is

::: js/xpconnect/loader/ScriptPreloader.cpp:392
(Diff revision 2)
> +      NS_DISPATCH_SYNC);
> +  }
> +
> +  OutputBuffer buf;
> +  size_t offset = 0;
> +  for (auto script : mSavedScripts) {

I wonder if we should have a hard limit on the number of scripts/size of the cache file.

::: js/xpconnect/loader/ScriptPreloader.cpp:451
(Diff revision 2)
> +
> +void
> +ScriptPreloader::NoteScript(const nsCString& url, const nsCString& cachePath,
> +                            JSScript* script)
> +{
> +  if (mStartupFinished || !mCacheInitialized) {

We should probably call this `mXpcomStartupFinished` or something.

::: js/xpconnect/loader/ScriptPreloader.cpp:459
(Diff revision 2)
> +
> +  if (FindScript(mSavedScripts, cachePath)) {
> +    return;
> +  }
> +
> +  CachedScript* existing = FindScript(mRestoredScripts, cachePath);

I still really think these should be hashtables, we're trying to improve perf. How many entries do you expect? If it's something like 7 then LinkedList is fine.

::: js/xpconnect/loader/ScriptPreloader.cpp:581
(Diff revision 2)
> +  MOZ_ASSERT(mFinished);
> +  if (mScript) {
> +    return mScript;
> +  }
> +
> +  if (mXDRRange.isSome() && !mToken) {

Can you add a comment here about what's going on? I think this case is where we have XDR but it's small enough that decoding on main thread is prefered, right?

::: js/xpconnect/loader/ScriptPreloader.cpp:590
(Diff revision 2)
> +    }
> +
> +    return mScript;
> +  }
> +
> +  if (!mToken) {

How do we get to this point? Should this be an assertion? If not can you add a comment.
Attachment #8861706 - Flags: review?(erahm) → review-
> On a more boring note, this should probably be updated to use gecko style (I know xpconnect is a mess, but new stuff should use our style). Mainly that just means `aParams`.

XPConnect is supposed to use JS style.
(In reply to Andrew McCreight [:mccr8] from comment #37)
> > On a more boring note, this should probably be updated to use gecko style (I know xpconnect is a mess, but new stuff should use our style). Mainly that just means `aParams`.
> 
> XPConnect is supposed to use JS style.

A stand by my xpconnect is a mess statement, but I'll take Andrew's word on this :)
(In reply to Andrew McCreight [:mccr8] from comment #37)
> > On a more boring note, this should probably be updated to use gecko style (I know xpconnect is a mess, but new stuff should use our style). Mainly that just means `aParams`.
> 
> XPConnect is supposed to use JS style.

Yeah, I always have trouble with code style in XPConnect. I went with Gecko style for method and member names, since the public API is mostly used in Gecko and the subscript loader follows that style, but tried to stick to JS style otherwise.
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review137814

> What kind of hardware are we talking about here? What's the perf like on android or an old laptop?

I only tested the various timeout values on one of my work laptops, which is pretty high end, but still has a platter drive. I also tested the end result on try, but not with very many different size limits, because try is too slow. These values show an improvement there, too, it's just harder to say whether they're optimal.

> Maybe 'compiled' instead of 'loaded' here if I'm understanding correctly.

Should be "decoded" rather than compiled. But "loaded" is right, since the fact that they're read immediately is what matters as far as the contiguous storage goes.

> I feel like we should make an effort here to not write out the file if nothing changed. I'm not exactly sure how that would work as-is

It should be relatively easy. The startup code already falls back to "scriptCache-current.bin" if "scriptCache.bin" doesn't exist, so it's just a matter of checking that the restored script list is empty and no new scripts have been added to the saved list. It's possible that the ordering will have changed, but that probably doesn't matter much.

> I wonder if we should have a hard limit on the number of scripts/size of the cache file.

I don't think so. If we're loading enough scripts before startup for it to matter, we have bigger problems to worry about.

> I still really think these should be hashtables, we're trying to improve perf. How many entries do you expect? If it's something like 7 then LinkedList is fine.

Currently it's about 200, so maybe a hash table would be worth it. But I'd be surprised if it makes a measurable difference in startup speed, and it would mean a fair amount of extra memory (and the current startup cache doesn't use a hash table, just a zip file header list). But I suppose I can try it and measure the difference.

> Can you add a comment here about what's going on? I think this case is where we have XDR but it's small enough that decoding on main thread is prefered, right?

Yes

> How do we get to this point? Should this be an assertion? If not can you add a comment.

I think we probably can't get to this point, as things currently stand. Originally, it was for the case when decoding failed, but now the XDR data is still kept around in that case.
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review137814

> It might make sense to add a non-explicit entry with the names and sizes of the cached scripts.

I'll file a follow-up for that.
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review137868

::: js/xpconnect/loader/ScriptPreloader.cpp:334
(Diff revision 4)
> +    }
> +
> +    if (mRestoredScripts.isEmpty()) {
> +        // Check for any new scripts that we need to save. If there aren't
> +        // any, and there aren't any saved scripts that we need to remove,
> +        // don't bother writing out a new cache fild.

*file
(In reply to Gabor Krizsanits [:krizsa :gabor] from comment #3)
> So I had high hopes for enabling the startup cache for the content process
> and tried out a raw hack a while ago but the result was very unimpressive on
> content process startup :( (still is worth to do just didn't make sense to
> block the release on it). Do you have numbers how much it helps? I might
> have missed something back then.
> 
> A good way to quickly measure the impact is to run the tabpaint talos test
> without forcing it to use single content process
> (http://searchfox.org/mozilla-central/source/testing/talos/talos/tests/
> tabpaint/bootstrap.js#76)

Early results without changing the process count limit:

https://treeherder.mozilla.org/perf.html#/compare?originalProject=mozilla-inbound&originalRevision=3c9671705cdaca87c9bf94b2890108d62cacdc40&newProject=try&newRevision=886dc319573a84ad572f4ec56aab6931e84bea69&framework=1&filter=ts_paint&showOnlyImportant=0

About a 3.6% (55ms) improvement on ts_paint e10s, compared to a ~0-2% improvement without enabling the cache in the content process.
(In reply to Kris Maglione [:kmag] from comment #46)
> Early results without changing the process count limit:
> 
> https://treeherder.mozilla.org/perf.html#/compare?originalProject=mozilla-
> inbound&originalRevision=3c9671705cdaca87c9bf94b2890108d62cacdc40&newProject=
> try&newRevision=886dc319573a84ad572f4ec56aab6931e84bea69&framework=1&filter=t
> s_paint&showOnlyImportant=0
> 
> About a 3.6% (55ms) improvement on ts_paint e10s, compared to a ~0-2%
> improvement without enabling the cache in the content process.

Ah. And with the content process limit removed:

https://treeherder.mozilla.org/perf.html#/compare?originalProject=try&originalRevision=920e71866a441ba7ec1eeb5eec1fe0b696ac1c91&newProject=try&newRevision=f7816acef7b035aae8c03329e50f37dbc9495aad&framework=1&filter=paint&showOnlyImportant=0

It looks like about a 3% improvement on ts_paint and ~5% on tabpaint vs. not using the script cache in the child process.
Comment on attachment 8863005 [details]
Bug 1359653: Part 6 - Use the script precompiler in the JS component loader and subscript loader.

https://reviewboard.mozilla.org/r/134848/#review138150

::: js/xpconnect/loader/mozJSComponentLoader.cpp:27
(Diff revision 3)
>  #include "nsIComponentManager.h"
>  #include "mozilla/Module.h"
>  #include "nsIFile.h"
>  #include "mozJSComponentLoader.h"
>  #include "mozJSLoaderUtils.h"
> +#include "ScriptPreloader.h"

mozilla/ScriptPreloader.h

::: js/xpconnect/loader/mozJSComponentLoader.cpp:698
(Diff revision 3)
>          } else {
>              rv = ReadCachedFunction(cache, cachePath, cx, mSystemPrincipal,
>                                      function.address());
>          }
>  
> -        if (NS_SUCCEEDED(rv)) {
> +        if (NS_SUCCEEDED(rv) && script) {

What's the purpose of this |script| guard? Doesn't this break the function case?

::: js/xpconnect/loader/mozJSComponentLoader.cpp:856
(Diff revision 3)
>      // script when we're not reusing the loader global, and a function
>      // otherwise.
>      MOZ_ASSERT(!!script != !!function);
>      MOZ_ASSERT(!!script == JS_IsGlobalObject(obj));
>  
> +    if (script) {

So, you need this guard on |script| because you don't put functions in your new preloader?

::: js/xpconnect/loader/mozJSComponentLoader.cpp:903
(Diff revision 3)
>                                   "component loader load module");
>          JSContext* aescx = aes.cx();
>          bool ok;
>          if (script) {
> -            ok = JS_ExecuteScript(aescx, script);
> +            JS::RootedValue rval(cx);
> +            ok = JS::CloneAndExecuteScript(aescx, script, &rval);

Why do you need to clone the script? I guess to avoid using the copy from the preloader?

::: js/xpconnect/loader/mozJSSubScriptLoader.cpp:10
(Diff revision 3)
>   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
>  
>  #include "mozJSSubScriptLoader.h"
>  #include "mozJSComponentLoader.h"
>  #include "mozJSLoaderUtils.h"
> +#include "ScriptPreloader.h"

mozilla/ScriptPreloader.h
Attachment #8863005 - Flags: review?(continuation) → review+
Comment on attachment 8863006 [details]
Bug 1359653: Part 7 - Use the script preloader for loading frame scripts.

https://reviewboard.mozilla.org/r/134850/#review138206

::: dom/base/nsFrameMessageManager.cpp:1651
(Diff revision 3)
>  <span class="indent">>></span>  }
>  
> -  JS::SourceBufferHolder srcBuf(dataStringBuf, dataStringLength,
> +    JS::SourceBufferHolder srcBuf(dataStringBuf, dataStringLength,
> -                                JS::SourceBufferHolder::GiveOwnership);
> +                                  JS::SourceBufferHolder::GiveOwnership);
>  
> -  if (dataStringBuf && dataStringLength > 0) {
> +    if (dataStringBuf && dataStringLength > 0) {

If this test fails, we have no script. Your patch makes it so we cache anyway. There's nothing wrong with that, but it seems slightly more dangerous than not caching. And I don't think it buys us anything. So maybe just return immediately if this test fails?
Attachment #8863006 - Flags: review?(wmccloskey) → review+
Comment on attachment 8863005 [details]
Bug 1359653: Part 6 - Use the script precompiler in the JS component loader and subscript loader.

https://reviewboard.mozilla.org/r/134848/#review138150

> What's the purpose of this |script| guard? Doesn't this break the function case?

Hm. Yeah, I guess it does break the function case. I think I accidentally rebased this from a follow-up where I started checking the ScriptPreloader even if cache was null. In that case, if GetCachedScript failed and cache was null, rv would still be true. But I buess I should just set rv to a failure code in that case.

> So, you need this guard on |script| because you don't put functions in your new preloader?

Yes. As far as I know, we don't even compile functions anymore now that b2g is gone, so I didn't see the point.

> Why do you need to clone the script? I guess to avoid using the copy from the preloader?

The pre-compiled scripts are compiled into xpc::CompileScope(), which means they need to be cloned before they can be used in a module scope.

Or, at least, mostly. Currently, the final step of the compilation happens in the scope of the first module that requested it (even though the first part happened in CompileScope()), so no clone is necessary for the first module it's loaded into. But if we unload and reload, or if we change this so that the compilation finishes in CompileScope(), the clone will always be necessary.

But CloneAndExecuteScript checks whether a clone is necessary, and skips it if it's not, so this works either way.

I guess I should add a comment.
Comment on attachment 8863006 [details]
Bug 1359653: Part 7 - Use the script preloader for loading frame scripts.

https://reviewboard.mozilla.org/r/134850/#review138206

> If this test fails, we have no script. Your patch makes it so we cache anyway. There's nothing wrong with that, but it seems slightly more dangerous than not caching. And I don't think it buys us anything. So maybe just return immediately if this test fails?

Hm. Yeah, we'd run into the assertion if we get past this point without a script, anyway, so returning makes sense.
Comment on attachment 8863001 [details]
Bug 1359653: Part 1 - Use a const Range rather than a Vector for XDR decoding.

https://reviewboard.mozilla.org/r/134840/#review138232

Yay run-time checks.

::: js/src/vm/HelperThreads.h:646
(Diff revision 1)
>      ParseTask(ParseTaskKind kind, JSContext* cx, JSObject* parseGlobal,
>                const char16_t* chars, size_t length,
>                JS::OffThreadCompileCallback callback, void* callbackData);
>      ParseTask(ParseTaskKind kind, JSContext* cx, JSObject* parseGlobal,
>                JS::TranscodeBuffer& buffer, size_t cursor,
>                JS::OffThreadCompileCallback callback, void* callbackData);

I think there aren't any other users of the TranscodeBuffer variant other than ScriptDecodeTask, and you're switching to that TranscodeRange instead. Please remove the TranscodeBuffer variant.

::: js/src/vm/Xdr.h:18
(Diff revision 1)
>  #include "jsatom.h"
>  #include "jsfriendapi.h"
>  
>  namespace js {
>  
> -class XDRBuffer {
> +class XDRBufferBase {

While you're here, could you put { on its own line for these classes?

::: js/src/vm/Xdr.h:44
(Diff revision 1)
> +template <>
> +class XDRBuffer<XDR_ENCODE> : public XDRBufferBase {
> +  public:
> +    XDRBuffer(JSContext* cx, JS::TranscodeBuffer& buffer, size_t cursor = 0)
> +      : XDRBufferBase(cx, cursor)
> +      , buffer_(buffer) { }

I think technically JS style for initializer lists is the inferior

Ctor()
  : foo_(foo),
    bar_(bar)

I'm fine with this though.
Attachment #8863001 - Flags: review?(shu) → review+
Comment on attachment 8863001 [details]
Bug 1359653: Part 1 - Use a const Range rather than a Vector for XDR decoding.

https://reviewboard.mozilla.org/r/134840/#review138232

I wanted to use compile-time checks, but the way all of the XDR transcoding stuff is implemented, I couldn't think of a way to do it without rewriting all of it :(

> I think technically JS style for initializer lists is the inferior
> 
> Ctor()
>   : foo_(foo),
>     bar_(bar)
> 
> I'm fine with this though.

Yeah, that's what I thought, but everything else in this file used this style. I'm happy to fix the ones that I touched, though.
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review138574

This looks good, sorry about all the style related changes :(

I have yet another design change proposal that I think is worth considering, but it could just be a follow up as well (or not at all).

::: js/xpconnect/loader/ScriptPreloader.h:107
(Diff revisions 3 - 4)
> -    template<typename Buffer>
> -    CachedScript(Buffer& buf) { Code(buf); }
> +        inline CachedScript(InputBuffer& buf);
> +
> +        ~CachedScript()
> +        {
> +            auto& cache = GetSingleton();
> +            if (cache.mScripts.Get(mCachePath) == this) {

What's the situation where the CachedScript in mScripts with this path is *not* `this`? That seems assert worthy, but maybe I'm missing something?

::: js/xpconnect/loader/ScriptPreloader.cpp:287
(Diff revisions 3 - 4)
> -    }
> +        }
>  
> +        for (auto script : scripts) {
> +            mScripts.Put(script->mCachePath, script);
> +        }
> -    mRestoredScripts = Move(scripts);
> +        mRestoredScripts = Move(scripts);

They way all of this is shaping up I think we might be able to get rid of `mRestoredScripts` and `mSavedScripts` now that we have `mScripts` (and probably improve perf).

Basically we'd just add a state to CachedScripts of `{ Restored, Saved, RestoredAndSaved }` instead of juggling scripts around.

WDYT?

::: js/xpconnect/loader/ScriptPreloader.cpp:294
(Diff revisions 3 - 4)
>  
> -  AutoJSAPI jsapi;
> +    AutoJSAPI jsapi;
> -  MOZ_RELEASE_ASSERT(jsapi.Init(xpc::CompilationScope()));
> +    MOZ_RELEASE_ASSERT(jsapi.Init(xpc::CompilationScope()));
> -  JSContext* cx = jsapi.cx();
> +    JSContext* cx = jsapi.cx();
>  
> -  auto start = TimeStamp::Now();
> +    auto start = TimeStamp::Now();

Maybe only set the timestamp if logging is enabled?

::: js/xpconnect/loader/ScriptPreloader.cpp:331
(Diff revisions 3 - 4)
>  
> -  if (mDataPrepared) {
> +    if (mDataPrepared) {
> -    return;
> +        return;
> -  }
> +    }
>  
> +    if (mRestoredScripts.isEmpty()) {

If we get rid of the lists, this would become something like:

```
needs_save = find(mScripts, [s] => {
  s.mState == Restored || s.mState == Saved
})
```

::: js/xpconnect/loader/ScriptPreloader.cpp:358
(Diff revisions 3 - 4)
> -    CachedScript* script = next;
> +        CachedScript* script = next;
> -    next = script->getNext();
> +        next = script->getNext();
>  
> -    if (!script->mSize && !script->XDREncode(jsapi.cx())) {
> +        if (!script->mSize && !script->XDREncode(jsapi.cx())) {
> -      script->remove();
> +            script->remove();
> -      delete script;
> +            delete script;

This leaves a dead pointer in `mScripts`, right?

::: js/xpconnect/loader/ScriptPreloader.cpp:490
(Diff revisions 3 - 4)
> -  if (FindScript(mSavedScripts, cachePath)) {
> +    // parameters.
> +    if (cachePath.FindChar('?') >= 0) {
> -    return;
> +        return;
> -  }
> +    }
>  
> -  CachedScript* existing = FindScript(mRestoredScripts, cachePath);
> +    bool exists = mScripts.Get(cachePath);

If we get rid of the lists this would become:

```
CachedScript* s = mScripts.Get(cachePath);
if (!s) {
   // add new Saved script
} else if (s->mState == Restored) {
   // attach script, set state to RestoredAndSaved
}
```
Attachment #8861706 - Flags: review?(erahm) → review-
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review138574

> What's the situation where the CachedScript in mScripts with this path is *not* `this`? That seems assert worthy, but maybe I'm missing something?

You're right, it should probably be an assert.

> They way all of this is shaping up I think we might be able to get rid of `mRestoredScripts` and `mSavedScripts` now that we have `mScripts` (and probably improve perf).
> 
> Basically we'd just add a state to CachedScripts of `{ Restored, Saved, RestoredAndSaved }` instead of juggling scripts around.
> 
> WDYT?

We need to be able to keep track of the order that scripts are loaded in, which the hashtable doesn't keep track of. In the follow-ups to support OOP script caches, I added a load timestamp, so we could preserve the approximate ordering across processes, so I should be able to get rid of the lists in that patch.

> Maybe only set the timestamp if logging is enabled?

Maybe, but I kind of wonder whether it's worth it. I'm not sure how much cheaper it is to check whether logging is enabled than it is to just set the timestamp... Anyway, this only happens once or twice per process, so it's probably not worth worrying about.

> This leaves a dead pointer in `mScripts`, right?

No, the destructor always deletes the script from mScripts, because I was worried we'd wind up with dangling pointers there otherwise.
Comment on attachment 8863003 [details]
Bug 1359653: Part 3 - Add a clear() method and move asssignment operator to AutoCleanLinkedList.

https://reviewboard.mozilla.org/r/134844/#review138676

::: mfbt/LinkedList.h:660
(Diff revision 2)
> +  {
> +    LinkedList<T>::operator=(Forward<LinkedList<T>>(aOther));
> +    return *this;
> +  }
> +
> +  void Clear()

Naming consistent with the rest of LinkedList's functions should make this `clear`, not `Clear`.  No need to re-review this with that change made.
Attachment #8863003 - Flags: review?(jwalden+bmo) → review+
Comment on attachment 8863002 [details]
Bug 1359653: Part 2 - Allow CloneAndExecuteScript with non-lexical scripts.

https://reviewboard.mozilla.org/r/134842/#review138706

::: commit-message-77b4b:1
(Diff revision 1)
> +Bug 1359653: Part 2 - Allow CloneAndExecuteScript with non-lexical scripts. r?shu

non-syntactic, not non-lexical.

::: js/src/jsapi.h:4378
(Diff revision 1)
>   */
>  extern JS_PUBLIC_API(bool)
>  CloneAndExecuteScript(JSContext* cx, JS::Handle<JSScript*> script,
>                        JS::MutableHandleValue rval);
>  
> +extern JS_PUBLIC_API(bool)

Please add a comment, something that says like CloneAndExecuteScript, but is able to execute under a non-syntactic environment chain.
Attachment #8863002 - Flags: review?(shu) → review+
Comment on attachment 8863004 [details]
Bug 1359653: Part 4 - Fallback to the default JS version when decoding regexps off-thread.

https://reviewboard.mozilla.org/r/134846/#review138710

::: js/src/jscntxt.cpp:1450
(Diff revision 2)
>  
>      if (compartment() && compartment()->behaviors().version() != JSVERSION_UNKNOWN)
>          return compartment()->behaviors().version();
>  
> +    if (!CurrentThreadCanAccessRuntime(runtime()))
> +        return JSVERSION_DEFAULT;

You're gonna like this, this is funny.

So JSRuntime::defaultVersion_ defaults to JSVERSION_DEFAULT and can be overridden with JSRuntime::setDefaultVersion, which has no users! Gotta get rid of this legacy version stuff.
Attachment #8863004 - Flags: review?(shu) → review+
Comment on attachment 8863001 [details]
Bug 1359653: Part 1 - Use a const Range rather than a Vector for XDR decoding.

Requesting review again, since I forgot ParseTask stored pointers rather than values, and was passing it a stack-allocated value.

On the upside, this makes the decode data union a lot simpler.
Attachment #8863001 - Flags: review+ → review?(shu)
Comment on attachment 8863004 [details]
Bug 1359653: Part 4 - Fallback to the default JS version when decoding regexps off-thread.

https://reviewboard.mozilla.org/r/134846/#review138710

> You're gonna like this, this is funny.
> 
> So JSRuntime::defaultVersion_ defaults to JSVERSION_DEFAULT and can be overridden with JSRuntime::setDefaultVersion, which has no users! Gotta get rid of this legacy version stuff.

I think we used to use that, and it wound up changing the JS version scripts would get depending on what was on the stack when they got compiled. Which was not fun. I'm pretty sure the JS shell used to use it, too.

It would be nice to get rid of that, if it's not used anymore...
Comment on attachment 8863953 [details]
Bug 1359653: Part 8 - Ignore script cache when loading scripts in gcd script breakpoint tests.

https://reviewboard.mozilla.org/r/135676/#review138718

Looks good to me.
Attachment #8863953 - Flags: review?(jimb) → review+
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review138954

Looks good, I'm still not convinced on using the linked lists with linear search but that can just be a follow up if we decide we need even better perf.

::: js/xpconnect/loader/ScriptPreloader.h:108
(Diff revisions 4 - 5)
>  
>          ~CachedScript()
>          {
>              auto& cache = GetSingleton();
> -            if (cache.mScripts.Get(mCachePath) == this) {
> +#ifdef DEBUG
> +            auto hashValue = cache.mScripts.Get(mCachePath);

Slightly better perf-wise for debug builds would be:

```
DebugOnly<...> s = cache.mScripts.GetAndRemove(...);
MOZ_ASSERT(s == this);
```

I don't care that strongly about this, feel free to change or not.
Attachment #8861706 - Flags: review?(erahm) → review+
Blocks: 1361900
Comment on attachment 8864287 [details]
Bug 1359653: Part 9 - Observe "startupcache-invalidate" and flush the cache when received.

https://reviewboard.mozilla.org/r/135912/#review139038

This looks good, just some minor comments.

::: js/xpconnect/loader/ScriptPreloader.cpp:176
(Diff revision 1)
> +        // still being parsed off-thread have a non-refcounted reference to
> +        // this script, which needs to stay alive until they finish parsing.
> +        if (script->mFinished) {
> +            script->Cancel();
> +            script->remove();
> +            delete script;

Deleting a `LinkedListElement` should remove it as well, so I guess the remove call could go. OTOH being explicit is fine.

::: js/xpconnect/loader/ScriptPreloader.cpp:190
(Diff revision 1)
> +
> +    FlushScripts(mSavedScripts);
> +    FlushScripts(mRestoredScripts);
> +
> +    // If we've already finished saving the cache at this point, start a new
> +    // delayed save operation.

Does this actually make sense? Does a startup cache flush imply all the startup scripts will be run again? Or are we just going to cache a bunch of scripts we'll evict next time?

If so can you expand the comment a litte?

::: js/xpconnect/loader/ScriptPreloader.cpp:667
(Diff revision 1)
>  }
>  
> +void
> +ScriptPreloader::CachedScript::Cancel()
> +{
> +    if (mToken) {

Can you add an `mMonitor.assertCurrentThreadOwns()` here? At least I think that's a requirement since we're poking `mToken`.
Attachment #8864287 - Flags: review?(erahm) → review+
Comment on attachment 8864287 [details]
Bug 1359653: Part 9 - Observe "startupcache-invalidate" and flush the cache when received.

https://reviewboard.mozilla.org/r/135912/#review139038

> Deleting a `LinkedListElement` should remove it as well, so I guess the remove call could go. OTOH being explicit is fine.

It does, yes, I just generally prefer to be explicit.

> Does this actually make sense? Does a startup cache flush imply all the startup scripts will be run again? Or are we just going to cache a bunch of scripts we'll evict next time?
> 
> If so can you expand the comment a litte?

The only scripts we'll wind up writing for the next session are scripts that are added after this point. In practice, that means an empty cache file, since we don't add any scripts after the cache file has been initially written. The only other option is to make sure the mmapped cache files are closed in every process and then delete them (since we can't delete them while they're in use on Windows), which is more trouble than it's worth.
Blocks: 1361792
Comment on attachment 8863001 [details]
Bug 1359653: Part 1 - Use a const Range rather than a Vector for XDR decoding.

https://reviewboard.mozilla.org/r/134840/#review139724

::: js/src/jsapi.cpp:4207
(Diff revision 2)
>  JS::DecodeOffThreadScript(JSContext* cx, const ReadOnlyCompileOptions& options,
>                            mozilla::Vector<uint8_t>& buffer /* TranscodeBuffer& */, size_t cursor,
>                            OffThreadCompileCallback callback, void* callbackData)
>  {
> -    MOZ_ASSERT(CanCompileOffThread(cx, options, buffer.length() - cursor));
> -    return StartOffThreadDecodeScript(cx, options, buffer, cursor, callback, callbackData);
> +    JS::TranscodeRange range(buffer.begin() + cursor, buffer.length() - cursor);
> +

Nit: don't need extra newline.

::: js/src/vm/HelperThreads.h:599
(Diff revision 2)
>  struct ParseTask
>  {
>      ParseTaskKind kind;
>      OwningCompileOptions options;
> -    // Anonymous union, the only correct interpretation is provided by the
> -    // ParseTaskKind value, or from the virtual parse function.
> +
> +    mozilla::MaybeOneOf<const JS::TranscodeRange, JS::TwoByteChars> data;

Nice.
Attachment #8863001 - Flags: review?(shu) → review+
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review138714

The space for state transitions for the 2 linked lists of scripts and individual CacheScripts, depending on when their JSScripts are requested and whether they are OMT decoded, is large enough to warrant more documentation.

The main thing I'd like to see is for this to be collected and documented in a block comment somewhere, referencing the variables used to signal those state transitions.

::: js/xpconnect/loader/AutoMemMap.cpp:23
(Diff revision 6)
> +    if (addr) {
> +        Unused << NS_WARN_IF(PR_MemUnmap(addr, size()) != PR_SUCCESS);
> +        addr = nullptr;
> +    }
> +
> +    if (fileMap) {

addr being non-null implies fileMap being non-null. Could move |if (fileMap)| inside |if (addr)|.

::: js/xpconnect/loader/ScriptPreloader-inl.h:59
(Diff revision 6)
> +        cursor_ += size;
> +        return buf;
> +    }
> +
> +    void
> +    codeUint16(const uint16_t& val)

Why do these methods take const& of machine types, instead of by value?

Edit: Oh I see, so you could pass the Buffers as template parameters.

::: js/xpconnect/loader/ScriptPreloader-inl.h:87
(Diff revision 6)
> +    uint8_t* Get() { return data.Elements(); }
> +
> +    const uint8_t* Get() const { return data.Elements(); }
> +
> +private:
> +    nsTArray<uint8_t> data;

Hm, gut reaction here is I'd rather see Vector than nsTArray. Up to you.

::: js/xpconnect/loader/ScriptPreloader-inl.h:159
(Diff revision 6)
> +            error_ = true;
> +        }
> +        return !error_;
> +    }
> +
> +    bool error_ = false;

Whoa what is this syntax? Does this mean for any constructors that don't explicitly initialize error\_ to a value, it'll be false?

::: js/xpconnect/loader/ScriptPreloader.h:102
(Diff revision 6)
> +            , mCachePath(cachePath)
> +            , mScript(script)
> +            , mFinished(true)
> +        {}
> +
> +        inline CachedScript(InputBuffer& buf);

explicit

::: js/xpconnect/loader/ScriptPreloader.h:175
(Diff revision 6)
> +
> +        // True if this script is ready to be executed. This means that either the
> +        // off-thread portion of an off-thread decode has finished, or the script
> +        // is too small to be decoded off-thread, and may be immediately decoded
> +        // whenever it is first executed.
> +        bool mFinished = false;

Perhaps rename this mReadyToExecute then? :)

::: js/xpconnect/loader/ScriptPreloader.h:198
(Diff revision 6)
> +    // point, the setup is quite expensive, and 20K is about where we start to
> +    // see an improvement rather than a regression.
> +    //
> +    // This also means that we get much better performance loading one big
> +    // script than several small scripts, since the setup is per-script, and the
> +    // OMT compile is almost always complete by the time we need a given script.

Please file a bug for batching OMT parse tasks, I'll try to take a look.

::: js/xpconnect/loader/ScriptPreloader.h:201
(Diff revision 6)
> +    // This also means that we get much better performance loading one big
> +    // script than several small scripts, since the setup is per-script, and the
> +    // OMT compile is almost always complete by the time we need a given script.
> +    static constexpr int MIN_OFFTHREAD_SIZE = 20 * 1024;
> +
> +    static constexpr int MAX_RECOMPILE_SIZE = 50 * 1024;

Please add a comment explaining MAX_RECOMPILE_SIZE as well. Should be renamed MAX_MAINTHREAD_DECODE_SIZE or something as well.

::: js/xpconnect/loader/ScriptPreloader.h:253
(Diff revision 6)
> +        return size;
> +    }
> +
> +    // The list of scripts executed during this session, and being saved for
> +    // potential reuse, and to be written to the next session's cache file.
> +    AutoCleanLinkedList<CachedScript> mSavedScripts;

Seems more accurate as mToBeSavedScripts

::: js/xpconnect/loader/ScriptPreloader.cpp:173
(Diff revision 6)
> +
> +        mStartupFinished = true;
> +
> +        if (XRE_IsParentProcess()) {
> +            Unused << NS_NewNamedThread("SaveScripts",
> +                                        getter_AddRefs(mSaveThread), this);

What happens if NS_NewNamedThread fails here? We keep track of scripts but do not write the cache on shutdown?

::: js/xpconnect/loader/ScriptPreloader.cpp:192
(Diff revision 6)
> +{
> +    nsCOMPtr<nsIFile> cacheFile;
> +    NS_TRY(mProfD->Clone(getter_AddRefs(cacheFile)));
> +
> +    NS_TRY(cacheFile->AppendNative(NS_LITERAL_CSTRING("startupCache")));
> +    Unused << cacheFile->Create(nsIFile::DIRECTORY_TYPE, 0777);

Why 777 instead of 755?

::: js/xpconnect/loader/ScriptPreloader.cpp:212
(Diff revision 6)
> +    MOZ_TRY_VAR(cacheFile, GetCacheFile());
> +
> +    bool exists;
> +    NS_TRY(cacheFile->Exists(&exists));
> +    if (exists) {
> +        NS_TRY(cacheFile->MoveTo(nullptr, NS_LITERAL_STRING("scriptCache-current.bin")));

I don't like the mix of hardcoding "scriptCache-current.bin" and being able to override the default "scriptCache.bin" in ScriptPreloader::GetCacheFile.

I'd remove the default parameter value.

::: js/xpconnect/loader/ScriptPreloader.cpp:214
(Diff revision 6)
> +    bool exists;
> +    NS_TRY(cacheFile->Exists(&exists));
> +    if (exists) {
> +        NS_TRY(cacheFile->MoveTo(nullptr, NS_LITERAL_STRING("scriptCache-current.bin")));
> +    } else {
> +        NS_TRY(cacheFile->SetLeafName(NS_LITERAL_STRING("scriptCache-current.bin")));

Is this case for crashes, where the previous run's scriptCache.bin has already been moved to scriptCache-current.bin, and due to the crash, no new cache was written to on shutdown?

If so, why is the scriptCache.bin "evicted" so early when it's first opened? Seems cleaner to do this moving when saving the new cache.

::: js/xpconnect/loader/ScriptPreloader.cpp:349
(Diff revision 6)
> +        // Check for any new scripts that we need to save. If there aren't
> +        // any, and there aren't any saved scripts that we need to remove,
> +        // don't bother writing out a new cache file.
> +        bool found = false;
> +        for (auto script : mSavedScripts) {
> +            if (script->mXDRRange.isNothing()) {

You explained this on IRC on the set intersection semantics here between mRestoredScripts and mSavedScripts. I was confused by the attention given to optimize the specific case that no scripts were restored -- is that common?

That is, isn't the more common case that some scripts were encoded, but mRestoredScripts - mSavedScripts is the empty set?

Edit: I see that in NoteScript, restored scripts that are also re-used get removed from mRestoredScripts. These lists are named misleadingly.

mRestored is really "stale and to be evicted"
mSaved is really "to be saved at shutdown and persisted until next session"

::: js/xpconnect/loader/ScriptPreloader.cpp:506
(Diff revision 6)
> +
> +    bool exists = mScripts.Get(cachePath);
> +
> +    CachedScript* restored = nullptr;
> +    if (exists) {
> +        restored = FindScript(mRestoredScripts, cachePath);

The 2 linked list + hashtable + moving scripts from one set to the other seems unwieldy to me. I don't feel too strongly about it, but would like more documentation about the relationship between the 2 lists of scripts.

::: js/xpconnect/loader/ScriptPreloader.cpp:566
(Diff revision 6)
> +ScriptPreloader::DecodeScriptOffThread(JSContext* cx, CachedScript* script)
> +{
> +    JS::CompileOptions options(cx, JSVERSION_LATEST);
> +
> +    options.setNoScriptRval(true)
> +        .setFileAndLine(script->mURL.get(), 1);

Nit: line up .

::: js/xpconnect/loader/ScriptPreloader.cpp:589
(Diff revision 6)
> +{
> +    auto script = static_cast<CachedScript*>(context);
> +
> +    MonitorAutoLock mal(GetSingleton().mMonitor);
> +
> +    if (script->mFinished) {

Is this case hit when the script is requested before OMT decoding is done? Please comment if so.
Attachment #8861706 - Flags: review?(shu)
Comment on attachment 8863005 [details]
Bug 1359653: Part 6 - Use the script precompiler in the JS component loader and subscript loader.

https://reviewboard.mozilla.org/r/134848/#review139766
Attachment #8863005 - Flags: review?(shu) → review+
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review138714

> Hm, gut reaction here is I'd rather see Vector than nsTArray. Up to you.

I started out with a Vector but Eric asked me to switch it to a nsTArray :)

> Whoa what is this syntax? Does this mean for any constructors that don't explicitly initialize error\_ to a value, it'll be false?

Yeah, it's a C++11 thing.

> explicit

I already fixed this after I did a try run on OS-X and the clang plugin complained...

> Perhaps rename this mReadyToExecute then? :)

Fair.

> Please file a bug for batching OMT parse tasks, I'll try to take a look.

I was planning to look into it myself, but if you want to do it, that works for me too :)

> Seems more accurate as mToBeSavedScripts

Eric had this comment too... I was thinking of saved in terms of the JSScript being saved, since it gets reused the next time it's needed even if it hasn't been saved to a file. But I guess this is confusing enough...

> What happens if NS_NewNamedThread fails here? We keep track of scripts but do not write the cache on shutdown?

Yeah, we would just wind up reusing the last cache file on the next restart.

> Why 777 instead of 755?

The typical umask of 022 changes this to 0755. If someone has a more lenient umask, it winds up as 0777, but in that case, it's what they're asking for.

> Is this case for crashes, where the previous run's scriptCache.bin has already been moved to scriptCache-current.bin, and due to the crash, no new cache was written to on shutdown?
> 
> If so, why is the scriptCache.bin "evicted" so early when it's first opened? Seems cleaner to do this moving when saving the new cache.

Because Windows file locking is a pain in the ass, and it's safest if we rename the file before we open it, and never have to deal with the possibility of scriptCache.bin being locked when we want to write out the new one.

> You explained this on IRC on the set intersection semantics here between mRestoredScripts and mSavedScripts. I was confused by the attention given to optimize the specific case that no scripts were restored -- is that common?
> 
> That is, isn't the more common case that some scripts were encoded, but mRestoredScripts - mSavedScripts is the empty set?
> 
> Edit: I see that in NoteScript, restored scripts that are also re-used get removed from mRestoredScripts. These lists are named misleadingly.
> 
> mRestored is really "stale and to be evicted"
> mSaved is really "to be saved at shutdown and persisted until next session"

Yeah, I got rid of the separate lists in the last patch of bug 1361792, so it's just one list with a state flag in each object.

> The 2 linked list + hashtable + moving scripts from one set to the other seems unwieldy to me. I don't feel too strongly about it, but would like more documentation about the relationship between the 2 lists of scripts.

Yeah, I agree. I didn't want the hashtable in the first place, but Eric asked for it. In bug 1361792, I added timestamps to the hash elements, and got rid of the linked lists.

> Is this case hit when the script is requested before OMT decoding is done? Please comment if so.

Yeah. I thought I already had a comment for that.
Comment on attachment 8861706 [details]
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread.

https://reviewboard.mozilla.org/r/133686/#review139772

Giving r+ since the biggest confusions I had and called docs for are going away in followup bugs.
Attachment #8861706 - Flags: review+
https://hg.mozilla.org/integration/mozilla-inbound/rev/473e6a1ef169a9ac556486680306b9c286774b74
Bug 1359653: Part 1 - Use a const Range rather than a Vector for XDR decoding. r=shu

https://hg.mozilla.org/integration/mozilla-inbound/rev/3f94cd9d95b99436ea5f77aee5d220092b6b32d6
Bug 1359653: Part 2 - Allow CloneAndExecuteScript with non-lexical scripts. r=shu

https://hg.mozilla.org/integration/mozilla-inbound/rev/b49bd726c8a6e955c672df17b2b9134ab3ad34d5
Bug 1359653: Part 3 - Add a clear() method and move asssignment operator to AutoCleanLinkedList. r=waldo

https://hg.mozilla.org/integration/mozilla-inbound/rev/16259c1af36e138881d18a3f8b0a803f5d4fc3ec
Bug 1359653: Part 4 - Fallback to the default JS version when decoding regexps off-thread. r=shu

https://hg.mozilla.org/integration/mozilla-inbound/rev/1c7df945505930d2d86a076ee20807104324c8cc
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread. r=shu,erahm

https://hg.mozilla.org/integration/mozilla-inbound/rev/a505dcbe8a02bf4b4f975e62cc2b651ef7eebdd0
Bug 1359653: Part 6 - Use the script precompiler in the JS component loader and subscript loader. r=mccr8,shu

https://hg.mozilla.org/integration/mozilla-inbound/rev/c1b0ed47743f9b09376fbb88ecbd3dcbabe27265
Bug 1359653: Part 7 - Use the script preloader for loading frame scripts. r=billm

https://hg.mozilla.org/integration/mozilla-inbound/rev/d8dc72ab2406371cc53ba228f347815b6aea74f4
Bug 1359653: Part 8 - Ignore script cache when loading scripts in gcd script breakpoint tests. r=jimb

https://hg.mozilla.org/integration/mozilla-inbound/rev/8f4637881ddc42a948c894e62c8486fe8677a938
Bug 1359653: Part 9 - Observe "startupcache-invalidate" and flush the cache when received. r=erahm
Backed out for rooting hazard and crashing during Marionette's test_quit_restart.py TestQuitRestart.test_in_app_restart_with_callback with [@ js::gc::MergeCompartments] on Linux debug builds:

https://treeherder.mozilla.org/#/jobs?repo=mozilla-inbound&revision=fecd86df5a2eb463ef74f325088d06130ce4472b&filter-resultStatus=testfailed&filter-resultStatus=busted&filter-resultStatus=exception&filter-resultStatus=retry&filter-resultStatus=usercancel&filter-resultStatus=runnable

Push with failures: https://treeherder.mozilla.org/#/jobs?repo=mozilla-inbound&revision=8f4637881ddc42a948c894e62c8486fe8677a938&filter-resultStatus=testfailed&filter-resultStatus=busted&filter-resultStatus=exception&filter-resultStatus=retry&filter-resultStatus=usercancel&filter-resultStatus=runnable

Failure log hazard: https://treeherder.mozilla.org/logviewer.html#?job_id=97066218&repo=mozilla-inbound
More information in https://queue.taskcluster.net/v1/task/JVxwc4AgT9qBx2XKacnc8g/runs/0/artifacts/public/build/hazards.txt.gz

Failure log devtools leak: https://treeherder.mozilla.org/logviewer.html#?job_id=97069323&repo=mozilla-inbound
> [task 2017-05-06T03:36:12.256614Z] 03:36:12    ERROR - TEST-UNEXPECTED-FAIL | devtools/client/responsivedesign/test/browser_responsive_cmd.js | leaked 1 window(s) until shutdown [url = data:text/html;charset=utf-8,hi]

Failure log Marionette: https://treeherder.mozilla.org/logviewer.html#?job_id=97069221&repo=mozilla-inbound
[task 2017-05-06T03:23:49.943320Z] 03:23:49     INFO - TEST-START | test_quit_restart.py TestQuitRestart.test_in_app_restart_with_callback
[task 2017-05-06T03:25:50.510777Z] 03:25:50     INFO - mozcrash Copy/paste: /usr/local/bin/linux64-minidump_stackwalk /tmp/tmpE7SgC6.mozrunner/minidumps/26511e39-c281-c24d-c5af-213ffba31d5e.dmp /home/worker/workspace/build/symbols
[task 2017-05-06T03:25:57.052242Z] 03:25:57     INFO - mozcrash Saved minidump as /home/worker/workspace/build/blobber_upload_dir/26511e39-c281-c24d-c5af-213ffba31d5e.dmp
[task 2017-05-06T03:25:57.052357Z] 03:25:57     INFO - mozcrash Saved app info as /home/worker/workspace/build/blobber_upload_dir/26511e39-c281-c24d-c5af-213ffba31d5e.extra
[task 2017-05-06T03:25:57.229306Z] 03:25:57     INFO - PROCESS-CRASH | test_quit_restart.py TestQuitRestart.test_in_app_restart_with_callback | application crashed [@ js::gc::MergeCompartments]
[task 2017-05-06T03:25:57.230378Z] 03:25:57     INFO - Crash dump filename: /tmp/tmpE7SgC6.mozrunner/minidumps/26511e39-c281-c24d-c5af-213ffba31d5e.dmp
[task 2017-05-06T03:25:57.230801Z] 03:25:57     INFO - Operating system: Linux
[task 2017-05-06T03:25:57.232418Z] 03:25:57     INFO -                   0.0.0 Linux 3.13.0-112-generic #159-Ubuntu SMP Fri Mar 3 15:26:07 UTC 2017 x86_64
[task 2017-05-06T03:25:57.233093Z] 03:25:57     INFO - CPU: amd64
[task 2017-05-06T03:25:57.233875Z] 03:25:57     INFO -      family 6 model 62 stepping 4
[task 2017-05-06T03:25:57.234688Z] 03:25:57     INFO -      2 CPUs
[task 2017-05-06T03:25:57.235388Z] 03:25:57     INFO - 
[task 2017-05-06T03:25:57.236078Z] 03:25:57     INFO - GPU: UNKNOWN
[task 2017-05-06T03:25:57.236729Z] 03:25:57     INFO - 
[task 2017-05-06T03:25:57.237401Z] 03:25:57     INFO - Crash reason:  SIGSEGV
[task 2017-05-06T03:25:57.238082Z] 03:25:57     INFO - Crash address: 0x0
[task 2017-05-06T03:25:57.238826Z] 03:25:57     INFO - Process uptime: not available
[task 2017-05-06T03:25:57.239602Z] 03:25:57     INFO - 
[task 2017-05-06T03:25:57.240546Z] 03:25:57     INFO - Thread 0 (crashed)
[task 2017-05-06T03:25:57.241530Z] 03:25:57     INFO -  0  libxul.so!js::gc::MergeCompartments [jsgc.cpp:8f4637881ddc : 7081 + 0x18]
[task 2017-05-06T03:25:57.242384Z] 03:25:57     INFO -     rax = 0x0000000000000000   rdx = 0x0000000000000000
[task 2017-05-06T03:25:57.243472Z] 03:25:57     INFO -     rcx = 0x00007f254bbd86fd   rbx = 0x00007f253393d800
[task 2017-05-06T03:25:57.246258Z] 03:25:57     INFO -     rsi = 0x00007f254bea7770   rdi = 0x00007f254bea6540
[task 2017-05-06T03:25:57.247157Z] 03:25:57     INFO -     rbp = 0x00007ffc7a38e200   rsp = 0x00007ffc7a38e090
[task 2017-05-06T03:25:57.247984Z] 03:25:57     INFO -      r8 = 0x00007f254bea7770    r9 = 0x00007f254cf6f740
[task 2017-05-06T03:25:57.248709Z] 03:25:57     INFO -     r10 = 0x0000000000000058   r11 = 0x00007f254bb4f7a0
[task 2017-05-06T03:25:57.249407Z] 03:25:57     INFO -     r12 = 0x00007f252dd7b000   r13 = 0x00007f2539e16e20
[task 2017-05-06T03:25:57.251008Z] 03:25:57     INFO -     r14 = 0x00007ffc7a38e270   r15 = 0x00007ffc7a38e2b0
[task 2017-05-06T03:25:57.251695Z] 03:25:57     INFO -     rip = 0x00007f253ec351a8
[task 2017-05-06T03:25:57.252483Z] 03:25:57     INFO -     Found by: given as instruction pointer in context
[task 2017-05-06T03:25:57.253195Z] 03:25:57     INFO -  1  libxul.so!js::GlobalHelperThreadState::mergeParseTaskCompartment [HelperThreads.cpp:8f4637881ddc : 1464 + 0x13]
[task 2017-05-06T03:25:57.253881Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a38e340
[task 2017-05-06T03:25:57.254552Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38e210   r12 = 0x00007f2533878040
[task 2017-05-06T03:25:57.255257Z] 03:25:57     INFO -     r13 = 0x00007f2539e16e20   r14 = 0x00007ffc7a38e270
[task 2017-05-06T03:25:57.255956Z] 03:25:57     INFO -     r15 = 0x00007ffc7a38e2b0   rip = 0x00007f253eda9d10
[task 2017-05-06T03:25:57.256607Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.257296Z] 03:25:57     INFO -  2  libxul.so!js::GlobalHelperThreadState::finishParseTask [HelperThreads.cpp:8f4637881ddc : 1318 + 0xb]
[task 2017-05-06T03:25:57.257975Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a38e3e0
[task 2017-05-06T03:25:57.258668Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38e350   r12 = 0x00007ffc7a38e360
[task 2017-05-06T03:25:57.259352Z] 03:25:57     INFO -     r13 = 0x00007ffc7a38e390   r14 = 0x00007ffc7a38e370
[task 2017-05-06T03:25:57.260051Z] 03:25:57     INFO -     r15 = 0x00007f2539e95c00   rip = 0x00007f253edb618e
[task 2017-05-06T03:25:57.260733Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.261435Z] 03:25:57     INFO -  3  libxul.so!js::GlobalHelperThreadState::finishScriptDecodeTask [HelperThreads.cpp:8f4637881ddc : 1365 + 0x5]
[task 2017-05-06T03:25:57.262126Z] 03:25:57     INFO -     rbx = 0x00007f254b878f80   rbp = 0x00007ffc7a38e3f0
[task 2017-05-06T03:25:57.262798Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38e3f0   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.263503Z] 03:25:57     INFO -     r13 = 0x00007f254b878fc0   r14 = 0x00007ffc7a38e680
[task 2017-05-06T03:25:57.264194Z] 03:25:57     INFO -     r15 = 0x0000000000000000   rip = 0x00007f253edb6561
[task 2017-05-06T03:25:57.264869Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.265563Z] 03:25:57     INFO -  4  libxul.so!mozilla::ScriptPreloader::CachedScript::GetJSScript [ScriptPreloader.cpp:8f4637881ddc : 715 + 0x8]
[task 2017-05-06T03:25:57.266247Z] 03:25:57     INFO -     rbx = 0x00007f254b878f80   rbp = 0x00007ffc7a38e450
[task 2017-05-06T03:25:57.266957Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38e400   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.267638Z] 03:25:57     INFO -     r13 = 0x00007f254b878fc0   r14 = 0x00007ffc7a38e680
[task 2017-05-06T03:25:57.268349Z] 03:25:57     INFO -     r15 = 0x0000000000000000   rip = 0x00007f253c4fd3f7
[task 2017-05-06T03:25:57.269005Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.269692Z] 03:25:57     INFO -  5  libxul.so!mozilla::ScriptPreloader::WaitForCachedScript [ScriptPreloader.cpp:8f4637881ddc : 603 + 0xb]
[task 2017-05-06T03:25:57.270367Z] 03:25:57     INFO -     rbx = 0x00007f254b878f80   rbp = 0x00007ffc7a38e4b0
[task 2017-05-06T03:25:57.271048Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38e460   r12 = 0x00007ffc7a38e5a8
[task 2017-05-06T03:25:57.271721Z] 03:25:57     INFO -     r13 = 0x00007f2537662000   r14 = 0x00007ffc7a38e680
[task 2017-05-06T03:25:57.272444Z] 03:25:57     INFO -     r15 = 0x0000000000000000   rip = 0x00007f253c4fd62e
[task 2017-05-06T03:25:57.273168Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.273835Z] 03:25:57     INFO -  6  libxul.so!mozJSSubScriptLoader::DoLoadSubScriptWithOptions [mozJSSubScriptLoader.cpp:8f4637881ddc : 702 + 0x13]
[task 2017-05-06T03:25:57.274514Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a38e710
[task 2017-05-06T03:25:57.275175Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38e4c0   r12 = 0x00007ffc7a38e5a8
[task 2017-05-06T03:25:57.275819Z] 03:25:57     INFO -     r13 = 0x00007f2531122c20   r14 = 0x00007ffc7a38e680
[task 2017-05-06T03:25:57.276492Z] 03:25:57     INFO -     r15 = 0x0000000000000000   rip = 0x00007f253c501744
[task 2017-05-06T03:25:57.277123Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.277788Z] 03:25:57     INFO -  7  libxul.so!mozJSSubScriptLoader::LoadSubScript [mozJSSubScriptLoader.cpp:8f4637881ddc : 569 + 0x11]
[task 2017-05-06T03:25:57.278458Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38e738   rbp = 0x00007ffc7a38e7c0
[task 2017-05-06T03:25:57.279193Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38e720   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.279879Z] 03:25:57     INFO -     r13 = 0x00007ffc7a38e8f0   r14 = 0x00007f2539e9c1b0
[task 2017-05-06T03:25:57.280608Z] 03:25:57     INFO -     r15 = 0x00007ffc7a38e938   rip = 0x00007f253c501b8b
[task 2017-05-06T03:25:57.281282Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.281947Z] 03:25:57     INFO -  8  libxul.so!NS_InvokeByIndex + 0x8e
[task 2017-05-06T03:25:57.282631Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38e890   rbp = 0x00007ffc7a38e810
[task 2017-05-06T03:25:57.283351Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38e7d0   r12 = 0x00007f2531122c20
[task 2017-05-06T03:25:57.284020Z] 03:25:57     INFO -     r13 = 0x0000000000000003   r14 = 0x00007ffc7a38e838
[task 2017-05-06T03:25:57.284685Z] 03:25:57     INFO -     r15 = 0x0000000000000004   rip = 0x00007f253be62212
[task 2017-05-06T03:25:57.285354Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.286049Z] 03:25:57     INFO -  9  libxul.so!CallMethodHelper::Call [XPCWrappedNative.cpp:8f4637881ddc : 1996 + 0x5]
[task 2017-05-06T03:25:57.286738Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38e890   rbp = 0x00007ffc7a38e870
[task 2017-05-06T03:25:57.287407Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38e820   r12 = 0x0000000000000004
[task 2017-05-06T03:25:57.288066Z] 03:25:57     INFO -     r13 = 0x0000000000000000   r14 = 0x00007ffc7a38e838
[task 2017-05-06T03:25:57.288793Z] 03:25:57     INFO -     r15 = 0x0000000000000004   rip = 0x00007f253c54dc6a
[task 2017-05-06T03:25:57.289449Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.290122Z] 03:25:57     INFO - 10  libxul.so!XPCWrappedNative::CallMethod [XPCWrappedNative.cpp:8f4637881ddc : 1282 + 0x8]
[task 2017-05-06T03:25:57.290800Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38ea48   rbp = 0x00007ffc7a38e9d0
[task 2017-05-06T03:25:57.291493Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38e880   r12 = 0x00007ffc7a38e890
[task 2017-05-06T03:25:57.292532Z] 03:25:57     INFO -     r13 = 0x00007ffc7a38e8d0   r14 = 0x00007ffc7a38e8c8
[task 2017-05-06T03:25:57.293282Z] 03:25:57     INFO -     r15 = 0x0000000000000001   rip = 0x00007f253c54de18
[task 2017-05-06T03:25:57.293937Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.294658Z] 03:25:57     INFO - 11  libxul.so!XPC_WN_CallMethod [XPCWrappedNativeJSOps.cpp:8f4637881ddc : 982 + 0xa]
[task 2017-05-06T03:25:57.295350Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38ea48   rbp = 0x00007ffc7a38eb20
[task 2017-05-06T03:25:57.297800Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38e9e0   r12 = 0x00007ffc7a38ea18
[task 2017-05-06T03:25:57.298142Z] 03:25:57     INFO -     r13 = 0x00007ffc7a38ea30   r14 = 0x00007ffc7a38e9f0
[task 2017-05-06T03:25:57.298490Z] 03:25:57     INFO -     r15 = 0x0000000000000001   rip = 0x00007f253c554a23
[task 2017-05-06T03:25:57.298834Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.299692Z] 03:25:57     INFO - 12  libxul.so!js::CallJSNative [jscntxtinlines.h:8f4637881ddc : 293 + 0x6]
[task 2017-05-06T03:25:57.300277Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38ee00   rbp = 0x00007ffc7a38eb80
[task 2017-05-06T03:25:57.300845Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38eb30   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.301415Z] 03:25:57     INFO -     r13 = 0x00007ffc7a38eb40   r14 = 0x00007f253c554834
[task 2017-05-06T03:25:57.302035Z] 03:25:57     INFO -     r15 = 0x00007f2534102628   rip = 0x00007f253e7b86f0
[task 2017-05-06T03:25:57.302599Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.304238Z] 03:25:57     INFO - 13  libxul.so!js::InternalCallOrConstruct [Interpreter.cpp:8f4637881ddc : 470 + 0x12]
[task 2017-05-06T03:25:57.304912Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38ee00   rbp = 0x00007ffc7a38ec40
[task 2017-05-06T03:25:57.305965Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38eb90   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.306690Z] 03:25:57     INFO -     r13 = 0x00007f2537669000   r14 = 0x0000000000000000
[task 2017-05-06T03:25:57.307372Z] 03:25:57     INFO -     r15 = 0x0000000000000000   rip = 0x00007f253e7da756
[task 2017-05-06T03:25:57.308044Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.308718Z] 03:25:57     INFO - 14  libxul.so!Interpret [Interpreter.cpp:8f4637881ddc : 521 + 0xf]
[task 2017-05-06T03:25:57.309371Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a38f210
[task 2017-05-06T03:25:57.310064Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38ec50   r12 = 0x0000000000000000
[task 2017-05-06T03:25:57.310732Z] 03:25:57     INFO -     r13 = 0x00007f2540fed540   r14 = 0x00007ffc7a38f3b0
[task 2017-05-06T03:25:57.311411Z] 03:25:57     INFO -     r15 = 0x00007f2537662020   rip = 0x00007f253e7cd2ca
[task 2017-05-06T03:25:57.312072Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.312738Z] 03:25:57     INFO - 15  libxul.so!js::RunScript [Interpreter.cpp:8f4637881ddc : 410 + 0xb]
[task 2017-05-06T03:25:57.313485Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a38f320
[task 2017-05-06T03:25:57.314156Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38f220   r12 = 0x00007ffc7a38f250
[task 2017-05-06T03:25:57.314864Z] 03:25:57     INFO -     r13 = 0x00007ffc7a38f3b0   r14 = 0x00007ffc7a38f240
[task 2017-05-06T03:25:57.315545Z] 03:25:57     INFO -     r15 = 0x00007ffc7a38f230   rip = 0x00007f253e7da32b
[task 2017-05-06T03:25:57.316203Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.316901Z] 03:25:57     INFO - 16  libxul.so!js::ExecuteKernel [Interpreter.cpp:8f4637881ddc : 699 + 0x5]
[task 2017-05-06T03:25:57.317566Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38f700   rbp = 0x00007ffc7a38f450
[task 2017-05-06T03:25:57.318226Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38f330   r12 = 0x00007ffc7a38f3c0
[task 2017-05-06T03:25:57.318917Z] 03:25:57     INFO -     r13 = 0x00007ffc7a38f3d8   r14 = 0x00007ffc7a38f3f0
[task 2017-05-06T03:25:57.319593Z] 03:25:57     INFO -     r15 = 0x00007f254103dfa0   rip = 0x00007f253e7dc501
[task 2017-05-06T03:25:57.320265Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.320968Z] 03:25:57     INFO - 17  libxul.so!js::Execute [Interpreter.cpp:8f4637881ddc : 732 + 0x28]
[task 2017-05-06T03:25:57.321637Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a38f4d0
[task 2017-05-06T03:25:57.322352Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38f460   r12 = 0x00007f252dd7b000
[task 2017-05-06T03:25:57.323032Z] 03:25:57     INFO -     r13 = 0x00007ffc7a38f480   r14 = 0x00007ffc7a38f510
[task 2017-05-06T03:25:57.323682Z] 03:25:57     INFO -     r15 = 0x0000000000000000   rip = 0x00007f253e7dc8a8
[task 2017-05-06T03:25:57.324351Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.325009Z] 03:25:57     INFO - 18  libxul.so!Evaluate [jsapi.cpp:8f4637881ddc : 4633 + 0x8]
[task 2017-05-06T03:25:57.325673Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38f520   rbp = 0x00007ffc7a38f600
[task 2017-05-06T03:25:57.326331Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38f4e0   r12 = 0x00007ffc7a38f640
[task 2017-05-06T03:25:57.327031Z] 03:25:57     INFO -     r13 = 0x00007ffc7a38f500   r14 = 0x00007ffc7a38f4f0
[task 2017-05-06T03:25:57.327690Z] 03:25:57     INFO -     r15 = 0x00007f2537662000   rip = 0x00007f253ebb0042
[task 2017-05-06T03:25:57.328357Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.329041Z] 03:25:57     INFO - 19  libxul.so!JS::Evaluate [jsapi.cpp:8f4637881ddc : 4666 + 0x5]
[task 2017-05-06T03:25:57.329717Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a38f670
[task 2017-05-06T03:25:57.330372Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38f610   r12 = 0x00007ffc7a38f630
[task 2017-05-06T03:25:57.331081Z] 03:25:57     INFO -     r13 = 0x00007ffc7a38f798   r14 = 0x00007ffc7a38f700
[task 2017-05-06T03:25:57.331743Z] 03:25:57     INFO -     r15 = 0x00000000000000bf   rip = 0x00007f253ebb0497
[task 2017-05-06T03:25:57.332410Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.333082Z] 03:25:57     INFO - 20  libxul.so!xpc::EvalInSandbox [Sandbox.cpp:8f4637881ddc : 1870 + 0x20]
[task 2017-05-06T03:25:57.333833Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38f840   rbp = 0x00007ffc7a38f920
[task 2017-05-06T03:25:57.334485Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38f680   r12 = 0x00007ffc7a38f6f0
[task 2017-05-06T03:25:57.335250Z] 03:25:57     INFO -     r13 = 0x00007ffc7a38f708   r14 = 0x00007ffc7a38f798
[task 2017-05-06T03:25:57.335896Z] 03:25:57     INFO -     r15 = 0x00000000000000bf   rip = 0x00007f253c526ac9
[task 2017-05-06T03:25:57.336578Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.337287Z] 03:25:57     INFO - 21  libxul.so!nsXPCComponents_Utils::EvalInSandbox [XPCComponents.cpp:8f4637881ddc : 2441 + 0x14]
[task 2017-05-06T03:25:57.337964Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38f998   rbp = 0x00007ffc7a38f9f0
[task 2017-05-06T03:25:57.338638Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38f930   r12 = 0x00007ffc7a38f980
[task 2017-05-06T03:25:57.339347Z] 03:25:57     INFO -     r13 = 0x0000000000000000   r14 = 0x00007ffc7a38f9a8
[task 2017-05-06T03:25:57.339981Z] 03:25:57     INFO -     r15 = 0x00000000000000b9   rip = 0x00007f253c5292c1
[task 2017-05-06T03:25:57.340618Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.341287Z] 03:25:57     INFO - 22  libxul.so!NS_InvokeByIndex + 0x8e
[task 2017-05-06T03:25:57.341960Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38fad0   rbp = 0x00007ffc7a38fa50
[task 2017-05-06T03:25:57.342601Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38fa00   r12 = 0x00007f25307ee1c0
[task 2017-05-06T03:25:57.343356Z] 03:25:57     INFO -     r13 = 0x0000000000000005   r14 = 0x00007ffc7a38fa78
[task 2017-05-06T03:25:57.344002Z] 03:25:57     INFO -     r15 = 0x0000000000000006   rip = 0x00007f253be62212
[task 2017-05-06T03:25:57.344668Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.345336Z] 03:25:57     INFO - 23  libxul.so!CallMethodHelper::Call [XPCWrappedNative.cpp:8f4637881ddc : 1996 + 0x5]
[task 2017-05-06T03:25:57.346001Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38fad0   rbp = 0x00007ffc7a38fab0
[task 2017-05-06T03:25:57.346652Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38fa60   r12 = 0x0000000000000006
[task 2017-05-06T03:25:57.347340Z] 03:25:57     INFO -     r13 = 0x0000000000000000   r14 = 0x00007ffc7a38fa78
[task 2017-05-06T03:25:57.347985Z] 03:25:57     INFO -     r15 = 0x0000000000000006   rip = 0x00007f253c54dc6a
[task 2017-05-06T03:25:57.348615Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.349279Z] 03:25:57     INFO - 24  libxul.so!XPCWrappedNative::CallMethod [XPCWrappedNative.cpp:8f4637881ddc : 1282 + 0x8]
[task 2017-05-06T03:25:57.349958Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38fc88   rbp = 0x00007ffc7a38fc10
[task 2017-05-06T03:25:57.350611Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38fac0   r12 = 0x00007ffc7a38fad0
[task 2017-05-06T03:25:57.351292Z] 03:25:57     INFO -     r13 = 0x00007ffc7a38fb10   r14 = 0x00007ffc7a38fb08
[task 2017-05-06T03:25:57.351938Z] 03:25:57     INFO -     r15 = 0x0000000000000001   rip = 0x00007f253c54de18
[task 2017-05-06T03:25:57.352596Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.353251Z] 03:25:57     INFO - 25  libxul.so!XPC_WN_CallMethod [XPCWrappedNativeJSOps.cpp:8f4637881ddc : 982 + 0xa]
[task 2017-05-06T03:25:57.353968Z] 03:25:57     INFO -     rbx = 0x00007ffc7a38fc88   rbp = 0x00007ffc7a38fd60
[task 2017-05-06T03:25:57.354621Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38fc20   r12 = 0x00007ffc7a38fc58
[task 2017-05-06T03:25:57.355343Z] 03:25:57     INFO -     r13 = 0x00007ffc7a38fc70   r14 = 0x00007ffc7a38fc30
[task 2017-05-06T03:25:57.357305Z] 03:25:57     INFO -     r15 = 0x0000000000000001   rip = 0x00007f253c554a23
[task 2017-05-06T03:25:57.357993Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.358641Z] 03:25:57     INFO - 26  0x2728c396666f
[task 2017-05-06T03:25:57.359319Z] 03:25:57     INFO -     rbx = 0xfffe7f25306fbba0   rbp = 0x00007ffc7a38fdd0
[task 2017-05-06T03:25:57.359974Z] 03:25:57     INFO -     rsp = 0x00007ffc7a38fd70   r12 = 0x0000000000000008
[task 2017-05-06T03:25:57.360642Z] 03:25:57     INFO -     r13 = 0x00007f2534102550   r14 = 0x00007f25306fbba0
[task 2017-05-06T03:25:57.361350Z] 03:25:57     INFO -     r15 = 0x00007f2533ad7ee0   rip = 0x00002728c396666f
[task 2017-05-06T03:25:57.362025Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.362658Z] 03:25:57     INFO - 27  0x7f252dd6d910
[task 2017-05-06T03:25:57.363324Z] 03:25:57     INFO -     rbp = 0x00007ffc7a38fe78   rsp = 0x00007ffc7a38fde0
[task 2017-05-06T03:25:57.363957Z] 03:25:57     INFO -     rip = 0x00007f252dd6d910
[task 2017-05-06T03:25:57.364600Z] 03:25:57     INFO -     Found by: previous frame's frame pointer
[task 2017-05-06T03:25:57.365276Z] 03:25:57     INFO - 28  0x2728c38f3e3b
[task 2017-05-06T03:25:57.365946Z] 03:25:57     INFO -     rbp = 0x00007ffc7a38ff20   rsp = 0x00007ffc7a38fe88
[task 2017-05-06T03:25:57.366598Z] 03:25:57     INFO -     rip = 0x00002728c38f3e3b
[task 2017-05-06T03:25:57.367316Z] 03:25:57     INFO -     Found by: previous frame's frame pointer
[task 2017-05-06T03:25:57.368044Z] 03:25:57     INFO - 29  libxul.so!EnterBaseline [BaselineJIT.cpp:8f4637881ddc : 162 + 0xd]
[task 2017-05-06T03:25:57.368852Z] 03:25:57     INFO -     rbp = 0x00007ffc7a390240   rsp = 0x00007ffc7a38ff30
[task 2017-05-06T03:25:57.369543Z] 03:25:57     INFO -     rip = 0x00007f253e87e588
[task 2017-05-06T03:25:57.370212Z] 03:25:57     INFO -     Found by: previous frame's frame pointer
[task 2017-05-06T03:25:57.370899Z] 03:25:57     INFO - 30  libxul.so!js::jit::EnterBaselineMethod [BaselineJIT.cpp:8f4637881ddc : 200 + 0xb]
[task 2017-05-06T03:25:57.371579Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a390370
[task 2017-05-06T03:25:57.372306Z] 03:25:57     INFO -     rsp = 0x00007ffc7a390250   r12 = 0x00007ffc7a3902d0
[task 2017-05-06T03:25:57.373009Z] 03:25:57     INFO -     r13 = 0x00007ffc7a390280   r14 = 0x0000000000000001
[task 2017-05-06T03:25:57.373656Z] 03:25:57     INFO -     r15 = 0x00007ffc7a3904d0   rip = 0x00007f253e88d4bb
[task 2017-05-06T03:25:57.374441Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.375154Z] 03:25:57     INFO - 31  libxul.so!js::RunScript [Interpreter.cpp:8f4637881ddc : 400 + 0xb]
[task 2017-05-06T03:25:57.375858Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a390480
[task 2017-05-06T03:25:57.376539Z] 03:25:57     INFO -     rsp = 0x00007ffc7a390380   r12 = 0x00007ffc7a3903b0
[task 2017-05-06T03:25:57.377235Z] 03:25:57     INFO -     r13 = 0x00007ffc7a3904d0   r14 = 0x00007ffc7a3903a0
[task 2017-05-06T03:25:57.377915Z] 03:25:57     INFO -     r15 = 0x00007ffc7a390390   rip = 0x00007f253e7da56b
[task 2017-05-06T03:25:57.378579Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.379257Z] 03:25:57     INFO - 32  libxul.so!js::InternalCallOrConstruct [Interpreter.cpp:8f4637881ddc : 488 + 0xb]
[task 2017-05-06T03:25:57.379940Z] 03:25:57     INFO -     rbx = 0x00007ffc7a390700   rbp = 0x00007ffc7a390540
[task 2017-05-06T03:25:57.380612Z] 03:25:57     INFO -     rsp = 0x00007ffc7a390490   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.381272Z] 03:25:57     INFO -     r13 = 0x00007f2537669000   r14 = 0x0000000000000000
[task 2017-05-06T03:25:57.381979Z] 03:25:57     INFO -     r15 = 0x00007ffc7a3904d0   rip = 0x00007f253e7da941
[task 2017-05-06T03:25:57.382650Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.385373Z] 03:25:57     INFO - 33  libxul.so!Interpret [Interpreter.cpp:8f4637881ddc : 521 + 0xf]
[task 2017-05-06T03:25:57.386105Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a390b10
[task 2017-05-06T03:25:57.386757Z] 03:25:57     INFO -     rsp = 0x00007ffc7a390550   r12 = 0x0000000000000000
[task 2017-05-06T03:25:57.387461Z] 03:25:57     INFO -     r13 = 0x00007f2540fed540   r14 = 0x00007ffc7a390c70
[task 2017-05-06T03:25:57.388108Z] 03:25:57     INFO -     r15 = 0x00007f2537662020   rip = 0x00007f253e7cd2ca
[task 2017-05-06T03:25:57.388770Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.389419Z] 03:25:57     INFO - 34  libxul.so!js::RunScript [Interpreter.cpp:8f4637881ddc : 410 + 0xb]
[task 2017-05-06T03:25:57.390108Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a390c20
[task 2017-05-06T03:25:57.390763Z] 03:25:57     INFO -     rsp = 0x00007ffc7a390b20   r12 = 0x00007ffc7a390b50
[task 2017-05-06T03:25:57.391441Z] 03:25:57     INFO -     r13 = 0x00007ffc7a390c70   r14 = 0x00007ffc7a390b40
[task 2017-05-06T03:25:57.392101Z] 03:25:57     INFO -     r15 = 0x00007ffc7a390b30   rip = 0x00007f253e7da32b
[task 2017-05-06T03:25:57.393308Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.394058Z] 03:25:57     INFO - 35  libxul.so!js::InternalCallOrConstruct [Interpreter.cpp:8f4637881ddc : 488 + 0xb]
[task 2017-05-06T03:25:57.394815Z] 03:25:57     INFO -     rbx = 0x00007ffc7a390ea0   rbp = 0x00007ffc7a390ce0
[task 2017-05-06T03:25:57.395485Z] 03:25:57     INFO -     rsp = 0x00007ffc7a390c30   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.396247Z] 03:25:57     INFO -     r13 = 0x00007f2537669000   r14 = 0x0000000000000000
[task 2017-05-06T03:25:57.396917Z] 03:25:57     INFO -     r15 = 0x00007ffc7a390c70   rip = 0x00007f253e7da941
[task 2017-05-06T03:25:57.397598Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.398317Z] 03:25:57     INFO - 36  libxul.so!Interpret [Interpreter.cpp:8f4637881ddc : 521 + 0xf]
[task 2017-05-06T03:25:57.399050Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a3912b0
[task 2017-05-06T03:25:57.399757Z] 03:25:57     INFO -     rsp = 0x00007ffc7a390cf0   r12 = 0x0000000000000000
[task 2017-05-06T03:25:57.400472Z] 03:25:57     INFO -     r13 = 0x00007f2540fed540   r14 = 0x00007ffc7a391410
[task 2017-05-06T03:25:57.401144Z] 03:25:57     INFO -     r15 = 0x00007f2537662020   rip = 0x00007f253e7cd2ca
[task 2017-05-06T03:25:57.401856Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.402600Z] 03:25:57     INFO - 37  libxul.so!js::RunScript [Interpreter.cpp:8f4637881ddc : 410 + 0xb]
[task 2017-05-06T03:25:57.403351Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a3913c0
[task 2017-05-06T03:25:57.404023Z] 03:25:57     INFO -     rsp = 0x00007ffc7a3912c0   r12 = 0x00007ffc7a3912f0
[task 2017-05-06T03:25:57.404754Z] 03:25:57     INFO -     r13 = 0x00007ffc7a391410   r14 = 0x00007ffc7a3912e0
[task 2017-05-06T03:25:57.405448Z] 03:25:57     INFO -     r15 = 0x00007ffc7a3912d0   rip = 0x00007f253e7da32b
[task 2017-05-06T03:25:57.406156Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.406835Z] 03:25:57     INFO - 38  libxul.so!js::InternalCallOrConstruct [Interpreter.cpp:8f4637881ddc : 488 + 0xb]
[task 2017-05-06T03:25:57.407596Z] 03:25:57     INFO -     rbx = 0x00007ffc7a3914e0   rbp = 0x00007ffc7a391480
[task 2017-05-06T03:25:57.408669Z] 03:25:57     INFO -     rsp = 0x00007ffc7a3913d0   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.409649Z] 03:25:57     INFO -     r13 = 0x00007f2537669000   r14 = 0x0000000000000000
[task 2017-05-06T03:25:57.410652Z] 03:25:57     INFO -     r15 = 0x00007ffc7a391410   rip = 0x00007f253e7da941
[task 2017-05-06T03:25:57.411637Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.415075Z] 03:25:57     INFO - 39  libxul.so!js::Call [Interpreter.cpp:8f4637881ddc : 534 + 0x5]
[task 2017-05-06T03:25:57.415925Z] 03:25:57     INFO -     rbx = 0x00007ffc7a3914e0   rbp = 0x00007ffc7a3914a0
[task 2017-05-06T03:25:57.416723Z] 03:25:57     INFO -     rsp = 0x00007ffc7a391490   r12 = 0x00007ffc7a391c40
[task 2017-05-06T03:25:57.417524Z] 03:25:57     INFO -     r13 = 0x00007ffc7a391580   r14 = 0x00007ffc7a3914e0
[task 2017-05-06T03:25:57.418348Z] 03:25:57     INFO -     r15 = 0xfffdffffffffffff   rip = 0x00007f253e7dadcd
[task 2017-05-06T03:25:57.419160Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.419944Z] 03:25:57     INFO - 40  libxul.so!js::fun_apply [jsfun.cpp:8f4637881ddc : 1286 + 0xe]
[task 2017-05-06T03:25:57.420751Z] 03:25:57     INFO -     rbx = 0x00007ffc7a391c48   rbp = 0x00007ffc7a391a00
[task 2017-05-06T03:25:57.421536Z] 03:25:57     INFO -     rsp = 0x00007ffc7a3914b0   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.423096Z] 03:25:57     INFO -     r13 = 0x00007ffc7a391580   r14 = 0x00007ffc7a3914e0
[task 2017-05-06T03:25:57.423900Z] 03:25:57     INFO -     r15 = 0xfffdffffffffffff   rip = 0x00007f253ec2f9be
[task 2017-05-06T03:25:57.424684Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.425677Z] 03:25:57     INFO - 41  libxul.so!js::CallJSNative [jscntxtinlines.h:8f4637881ddc : 293 + 0x6]
[task 2017-05-06T03:25:57.426673Z] 03:25:57     INFO -     rbx = 0x00007ffc7a391bf0   rbp = 0x00007ffc7a391a60
[task 2017-05-06T03:25:57.427669Z] 03:25:57     INFO -     rsp = 0x00007ffc7a391a10   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.428659Z] 03:25:57     INFO -     r13 = 0x00007ffc7a391a20   r14 = 0x00007f253ec2f730
[task 2017-05-06T03:25:57.429640Z] 03:25:57     INFO -     r15 = 0x00007ffc7a391c60   rip = 0x00007f253e7b86f0
[task 2017-05-06T03:25:57.430621Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.431612Z] 03:25:57     INFO - 42  libxul.so!js::InternalCallOrConstruct [Interpreter.cpp:8f4637881ddc : 470 + 0x12]
[task 2017-05-06T03:25:57.432613Z] 03:25:57     INFO -     rbx = 0x00007ffc7a391bf0   rbp = 0x00007ffc7a391b20
[task 2017-05-06T03:25:57.433624Z] 03:25:57     INFO -     rsp = 0x00007ffc7a391a70   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.434624Z] 03:25:57     INFO -     r13 = 0x00007f2537669000   r14 = 0x0000000000000000
[task 2017-05-06T03:25:57.436568Z] 03:25:57     INFO -     r15 = 0x0000000000000000   rip = 0x00007f253e7da756
[task 2017-05-06T03:25:57.437388Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.438183Z] 03:25:57     INFO - 43  libxul.so!js::Call [Interpreter.cpp:8f4637881ddc : 534 + 0x5]
[task 2017-05-06T03:25:57.442905Z] 03:25:57     INFO -     rbx = 0x00007ffc7a391bf0   rbp = 0x00007ffc7a391b40
[task 2017-05-06T03:25:57.443719Z] 03:25:57     INFO -     rsp = 0x00007ffc7a391b30   r12 = 0x00007f2534102348
[task 2017-05-06T03:25:57.444524Z] 03:25:57     INFO -     r13 = 0x0000000000000002   r14 = 0x00007ffc7a391b60
[task 2017-05-06T03:25:57.445325Z] 03:25:57     INFO -     r15 = 0x00007ffc7a391bf0   rip = 0x00007f253e7dadcd
[task 2017-05-06T03:25:57.446126Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.446953Z] 03:25:57     INFO - 44  libxul.so!js::Wrapper::call [Wrapper.cpp:8f4637881ddc : 166 + 0xb]
[task 2017-05-06T03:25:57.447763Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a391cc0
[task 2017-05-06T03:25:57.448561Z] 03:25:57     INFO -     rsp = 0x00007ffc7a391b50   r12 = 0x00007ffc7a391de0
[task 2017-05-06T03:25:57.449359Z] 03:25:57     INFO -     r13 = 0x0000000000000002   r14 = 0x00007ffc7a391b60
[task 2017-05-06T03:25:57.450148Z] 03:25:57     INFO -     r15 = 0x00007ffc7a391bf0   rip = 0x00007f253ecc25c5
[task 2017-05-06T03:25:57.450960Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.451759Z] 03:25:57     INFO - 45  libxul.so!js::CrossCompartmentWrapper::call [CrossCompartmentWrapper.cpp:8f4637881ddc : 353 + 0x12]
[task 2017-05-06T03:25:57.452551Z] 03:25:57     INFO -     rbx = 0x0000000000000002   rbp = 0x00007ffc7a391d40
[task 2017-05-06T03:25:57.453331Z] 03:25:57     INFO -     rsp = 0x00007ffc7a391cd0   r12 = 0x00007ffc7a391cf0
[task 2017-05-06T03:25:57.454123Z] 03:25:57     INFO -     r13 = 0x00007ffc7a391e00   r14 = 0x00007ffc7a391de0
[task 2017-05-06T03:25:57.454912Z] 03:25:57     INFO -     r15 = 0x00007f2537662000   rip = 0x00007f253ecb0322
[task 2017-05-06T03:25:57.455891Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.456892Z] 03:25:57     INFO - 46  libxul.so!js::Proxy::call [Proxy.cpp:8f4637881ddc : 479 + 0x15]
[task 2017-05-06T03:25:57.457888Z] 03:25:57     INFO -     rbx = 0x00007ffc7a391d50   rbp = 0x00007ffc7a391dd0
[task 2017-05-06T03:25:57.463066Z] 03:25:57     INFO -     rsp = 0x00007ffc7a391d50   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.463889Z] 03:25:57     INFO -     r13 = 0x00007ffc7a391e00   r14 = 0x00007ffc7a391de0
[task 2017-05-06T03:25:57.464691Z] 03:25:57     INFO -     r15 = 0x00007f254103b710   rip = 0x00007f253ecb881d
[task 2017-05-06T03:25:57.465477Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.466272Z] 03:25:57     INFO - 47  libxul.so!js::proxy_Call [Proxy.cpp:8f4637881ddc : 739 + 0xc]
[task 2017-05-06T03:25:57.467071Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a391e20
[task 2017-05-06T03:25:57.467862Z] 03:25:57     INFO -     rsp = 0x00007ffc7a391de0   r12 = 0x00007ffc7a391df0
[task 2017-05-06T03:25:57.468651Z] 03:25:57     INFO -     r13 = 0x00007ffc7a391e40   r14 = 0x00007f253ecb8850
[task 2017-05-06T03:25:57.469428Z] 03:25:57     INFO -     r15 = 0x00007f2534102368   rip = 0x00007f253ecb88bd
[task 2017-05-06T03:25:57.470220Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.471024Z] 03:25:57     INFO - 48  libxul.so!js::CallJSNative [jscntxtinlines.h:8f4637881ddc : 293 + 0x6]
[task 2017-05-06T03:25:57.471823Z] 03:25:57     INFO -     rbx = 0x00007ffc7a392100   rbp = 0x00007ffc7a391e80
[task 2017-05-06T03:25:57.472598Z] 03:25:57     INFO -     rsp = 0x00007ffc7a391e30   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.473433Z] 03:25:57     INFO -     r13 = 0x00007ffc7a391e40   r14 = 0x00007f253ecb8850
[task 2017-05-06T03:25:57.474217Z] 03:25:57     INFO -     r15 = 0x00007f2534102368   rip = 0x00007f253e7b86f0
[task 2017-05-06T03:25:57.476443Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.477257Z] 03:25:57     INFO - 49  libxul.so!js::InternalCallOrConstruct [Interpreter.cpp:8f4637881ddc : 452 + 0xe]
[task 2017-05-06T03:25:57.478087Z] 03:25:57     INFO -     rbx = 0x00007ffc7a392100   rbp = 0x00007ffc7a391f40
[task 2017-05-06T03:25:57.478913Z] 03:25:57     INFO -     rsp = 0x00007ffc7a391e90   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.479747Z] 03:25:57     INFO -     r13 = 0x00007f2537669000   r14 = 0x0000000000000000
[task 2017-05-06T03:25:57.480550Z] 03:25:57     INFO -     r15 = 0x0000000000000003   rip = 0x00007f253e7da9e9
[task 2017-05-06T03:25:57.481337Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.482132Z] 03:25:57     INFO - 50  libxul.so!Interpret [Interpreter.cpp:8f4637881ddc : 521 + 0xf]
[task 2017-05-06T03:25:57.482929Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a392510
[task 2017-05-06T03:25:57.483742Z] 03:25:57     INFO -     rsp = 0x00007ffc7a391f50   r12 = 0x0000000000000000
[task 2017-05-06T03:25:57.484545Z] 03:25:57     INFO -     r13 = 0x00007f2540fed540   r14 = 0x00007ffc7a392670
[task 2017-05-06T03:25:57.485340Z] 03:25:57     INFO -     r15 = 0x00007f2537662020   rip = 0x00007f253e7cd2ca
[task 2017-05-06T03:25:57.486126Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.486986Z] 03:25:57     INFO - 51  libxul.so!js::RunScript [Interpreter.cpp:8f4637881ddc : 410 + 0xb]
[task 2017-05-06T03:25:57.487782Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a392620
[task 2017-05-06T03:25:57.488577Z] 03:25:57     INFO -     rsp = 0x00007ffc7a392520   r12 = 0x00007ffc7a392550
[task 2017-05-06T03:25:57.489371Z] 03:25:57     INFO -     r13 = 0x00007ffc7a392670   r14 = 0x00007ffc7a392540
[task 2017-05-06T03:25:57.490165Z] 03:25:57     INFO -     r15 = 0x00007ffc7a392530   rip = 0x00007f253e7da32b
[task 2017-05-06T03:25:57.490976Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.491792Z] 03:25:57     INFO - 52  libxul.so!js::InternalCallOrConstruct [Interpreter.cpp:8f4637881ddc : 488 + 0xb]
[task 2017-05-06T03:25:57.492590Z] 03:25:57     INFO -     rbx = 0x00007ffc7a3928a0   rbp = 0x00007ffc7a3926e0
[task 2017-05-06T03:25:57.493775Z] 03:25:57     INFO -     rsp = 0x00007ffc7a392630   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.494589Z] 03:25:57     INFO -     r13 = 0x00007f2537669000   r14 = 0x0000000000000000
[task 2017-05-06T03:25:57.495387Z] 03:25:57     INFO -     r15 = 0x00007ffc7a392670   rip = 0x00007f253e7da941
[task 2017-05-06T03:25:57.496177Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.497410Z] 03:25:57     INFO - 53  libxul.so!Interpret [Interpreter.cpp:8f4637881ddc : 521 + 0xf]
[task 2017-05-06T03:25:57.498237Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a392cb0
[task 2017-05-06T03:25:57.499039Z] 03:25:57     INFO -     rsp = 0x00007ffc7a3926f0   r12 = 0x0000000000000000
[task 2017-05-06T03:25:57.499830Z] 03:25:57     INFO -     r13 = 0x00007f2540fed540   r14 = 0x00007ffc7a392e10
[task 2017-05-06T03:25:57.500647Z] 03:25:57     INFO -     r15 = 0x00007f2537662020   rip = 0x00007f253e7cd2ca
[task 2017-05-06T03:25:57.501442Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.502228Z] 03:25:57     INFO - 54  libxul.so!js::RunScript [Interpreter.cpp:8f4637881ddc : 410 + 0xb]
[task 2017-05-06T03:25:57.503030Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a392dc0
[task 2017-05-06T03:25:57.503831Z] 03:25:57     INFO -     rsp = 0x00007ffc7a392cc0   r12 = 0x00007ffc7a392cf0
[task 2017-05-06T03:25:57.504638Z] 03:25:57     INFO -     r13 = 0x00007ffc7a392e10   r14 = 0x00007ffc7a392ce0
[task 2017-05-06T03:25:57.505434Z] 03:25:57     INFO -     r15 = 0x00007ffc7a392cd0   rip = 0x00007f253e7da32b
[task 2017-05-06T03:25:57.506234Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.507025Z] 03:25:57     INFO - 55  libxul.so!js::InternalCallOrConstruct [Interpreter.cpp:8f4637881ddc : 488 + 0xb]
[task 2017-05-06T03:25:57.507836Z] 03:25:57     INFO -     rbx = 0x00007ffc7a393040   rbp = 0x00007ffc7a392e80
[task 2017-05-06T03:25:57.508620Z] 03:25:57     INFO -     rsp = 0x00007ffc7a392dd0   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.509408Z] 03:25:57     INFO -     r13 = 0x00007f2537669000   r14 = 0x0000000000000000
[task 2017-05-06T03:25:57.510195Z] 03:25:57     INFO -     r15 = 0x00007ffc7a392e10   rip = 0x00007f253e7da941
[task 2017-05-06T03:25:57.511016Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.511810Z] 03:25:57     INFO - 56  libxul.so!Interpret [Interpreter.cpp:8f4637881ddc : 521 + 0xf]
[task 2017-05-06T03:25:57.512655Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a393450
[task 2017-05-06T03:25:57.513447Z] 03:25:57     INFO -     rsp = 0x00007ffc7a392e90   r12 = 0x0000000000000000
[task 2017-05-06T03:25:57.514243Z] 03:25:57     INFO -     r13 = 0x00007f2540fed540   r14 = 0x00007ffc7a3935b0
[task 2017-05-06T03:25:57.515045Z] 03:25:57     INFO -     r15 = 0x00007f2537662020   rip = 0x00007f253e7cd2ca
[task 2017-05-06T03:25:57.515834Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.516622Z] 03:25:57     INFO - 57  libxul.so!js::RunScript [Interpreter.cpp:8f4637881ddc : 410 + 0xb]
[task 2017-05-06T03:25:57.517479Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a393560
[task 2017-05-06T03:25:57.518282Z] 03:25:57     INFO -     rsp = 0x00007ffc7a393460   r12 = 0x00007ffc7a393490
[task 2017-05-06T03:25:57.519106Z] 03:25:57     INFO -     r13 = 0x00007ffc7a3935b0   r14 = 0x00007ffc7a393480
[task 2017-05-06T03:25:57.519892Z] 03:25:57     INFO -     r15 = 0x00007ffc7a393470   rip = 0x00007f253e7da32b
[task 2017-05-06T03:25:57.520692Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.521473Z] 03:25:57     INFO - 58  libxul.so!js::InternalCallOrConstruct [Interpreter.cpp:8f4637881ddc : 488 + 0xb]
[task 2017-05-06T03:25:57.522267Z] 03:25:57     INFO -     rbx = 0x00007ffc7a3936f0   rbp = 0x00007ffc7a393620
[task 2017-05-06T03:25:57.523077Z] 03:25:57     INFO -     rsp = 0x00007ffc7a393570   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.524839Z] 03:25:57     INFO -     r13 = 0x00007f2537669000   r14 = 0x0000000000000000
[task 2017-05-06T03:25:57.525182Z] 03:25:57     INFO -     r15 = 0x00007ffc7a3935b0   rip = 0x00007f253e7da941
[task 2017-05-06T03:25:57.526226Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.528448Z] 03:25:57     INFO - 59  libxul.so!js::Call [Interpreter.cpp:8f4637881ddc : 534 + 0x5]
[task 2017-05-06T03:25:57.528806Z] 03:25:57     INFO -     rbx = 0x00007ffc7a3936f0   rbp = 0x00007ffc7a393640
[task 2017-05-06T03:25:57.529142Z] 03:25:57     INFO -     rsp = 0x00007ffc7a393630   r12 = 0x00007f2534102090
[task 2017-05-06T03:25:57.529478Z] 03:25:57     INFO -     r13 = 0x0000000000000000   r14 = 0x00007ffc7a393660
[task 2017-05-06T03:25:57.529817Z] 03:25:57     INFO -     r15 = 0x00007ffc7a3936f0   rip = 0x00007f253e7dadcd
[task 2017-05-06T03:25:57.530134Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.530463Z] 03:25:57     INFO - 60  libxul.so!js::Wrapper::call [Wrapper.cpp:8f4637881ddc : 166 + 0xb]
[task 2017-05-06T03:25:57.530788Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a3937c0
[task 2017-05-06T03:25:57.532553Z] 03:25:57     INFO -     rsp = 0x00007ffc7a393650   r12 = 0x00007ffc7a3938e0
[task 2017-05-06T03:25:57.533382Z] 03:25:57     INFO -     r13 = 0x0000000000000000   r14 = 0x00007ffc7a393660
[task 2017-05-06T03:25:57.534170Z] 03:25:57     INFO -     r15 = 0x00007ffc7a3936f0   rip = 0x00007f253ecc25c5
[task 2017-05-06T03:25:57.534968Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.535788Z] 03:25:57     INFO - 61  libxul.so!js::CrossCompartmentWrapper::call [CrossCompartmentWrapper.cpp:8f4637881ddc : 353 + 0x12]
[task 2017-05-06T03:25:57.536608Z] 03:25:57     INFO -     rbx = 0x00007ffc7a393850   rbp = 0x00007ffc7a393840
[task 2017-05-06T03:25:57.537435Z] 03:25:57     INFO -     rsp = 0x00007ffc7a3937d0   r12 = 0x00007ffc7a3937f0
[task 2017-05-06T03:25:57.538215Z] 03:25:57     INFO -     r13 = 0x00007ffc7a393900   r14 = 0x00007ffc7a3938e0
[task 2017-05-06T03:25:57.539074Z] 03:25:57     INFO -     r15 = 0x00007f2537662000   rip = 0x00007f253ecb0322
[task 2017-05-06T03:25:57.539858Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.540634Z] 03:25:57     INFO - 62  libxul.so!js::Proxy::call [Proxy.cpp:8f4637881ddc : 479 + 0x15]
[task 2017-05-06T03:25:57.547267Z] 03:25:57     INFO -     rbx = 0x00007ffc7a393850   rbp = 0x00007ffc7a3938d0
[task 2017-05-06T03:25:57.549220Z] 03:25:57     INFO -     rsp = 0x00007ffc7a393850   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.550817Z] 03:25:57     INFO -     r13 = 0x00007ffc7a393900   r14 = 0x00007ffc7a3938e0
[task 2017-05-06T03:25:57.554555Z] 03:25:57     INFO -     r15 = 0x00007f254103b710   rip = 0x00007f253ecb881d
[task 2017-05-06T03:25:57.554993Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.555444Z] 03:25:57     INFO - 63  libxul.so!js::proxy_Call [Proxy.cpp:8f4637881ddc : 739 + 0xc]
[task 2017-05-06T03:25:57.556814Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a393920
[task 2017-05-06T03:25:57.558067Z] 03:25:57     INFO -     rsp = 0x00007ffc7a3938e0   r12 = 0x00007ffc7a3938f0
[task 2017-05-06T03:25:57.559855Z] 03:25:57     INFO -     r13 = 0x00007ffc7a393940   r14 = 0x00007f253ecb8850
[task 2017-05-06T03:25:57.560670Z] 03:25:57     INFO -     r15 = 0x00007f25341020a0   rip = 0x00007f253ecb88bd
[task 2017-05-06T03:25:57.561467Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.562322Z] 03:25:57     INFO - 64  libxul.so!js::CallJSNative [jscntxtinlines.h:8f4637881ddc : 293 + 0x6]
[task 2017-05-06T03:25:57.563166Z] 03:25:57     INFO -     rbx = 0x00007ffc7a393c00   rbp = 0x00007ffc7a393980
[task 2017-05-06T03:25:57.563931Z] 03:25:57     INFO -     rsp = 0x00007ffc7a393930   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.564678Z] 03:25:57     INFO -     r13 = 0x00007ffc7a393940   r14 = 0x00007f253ecb8850
[task 2017-05-06T03:25:57.565451Z] 03:25:57     INFO -     r15 = 0x00007f25341020a0   rip = 0x00007f253e7b86f0
[task 2017-05-06T03:25:57.566200Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.566996Z] 03:25:57     INFO - 65  libxul.so!js::InternalCallOrConstruct [Interpreter.cpp:8f4637881ddc : 452 + 0xe]
[task 2017-05-06T03:25:57.567770Z] 03:25:57     INFO -     rbx = 0x00007ffc7a393c00   rbp = 0x00007ffc7a393a40
[task 2017-05-06T03:25:57.568543Z] 03:25:57     INFO -     rsp = 0x00007ffc7a393990   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.569325Z] 03:25:57     INFO -     r13 = 0x00007f2537669000   r14 = 0x0000000000000000
[task 2017-05-06T03:25:57.570122Z] 03:25:57     INFO -     r15 = 0x0000000000000001   rip = 0x00007f253e7da9e9
[task 2017-05-06T03:25:57.570902Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.571700Z] 03:25:57     INFO - 66  libxul.so!Interpret [Interpreter.cpp:8f4637881ddc : 521 + 0xf]
[task 2017-05-06T03:25:57.572478Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a394010
[task 2017-05-06T03:25:57.573280Z] 03:25:57     INFO -     rsp = 0x00007ffc7a393a50   r12 = 0x0000000000000000
[task 2017-05-06T03:25:57.574063Z] 03:25:57     INFO -     r13 = 0x00007f2540fed540   r14 = 0x00007ffc7a394170
[task 2017-05-06T03:25:57.574977Z] 03:25:57     INFO -     r15 = 0x00007f2537662020   rip = 0x00007f253e7cd2ca
[task 2017-05-06T03:25:57.575756Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.576539Z] 03:25:57     INFO - 67  libxul.so!js::RunScript [Interpreter.cpp:8f4637881ddc : 410 + 0xb]
[task 2017-05-06T03:25:57.577316Z] 03:25:57     INFO -     rbx = 0x00007f2537662000   rbp = 0x00007ffc7a394120
[task 2017-05-06T03:25:57.578193Z] 03:25:57     INFO -     rsp = 0x00007ffc7a394020   r12 = 0x00007ffc7a394050
[task 2017-05-06T03:25:57.579028Z] 03:25:57     INFO -     r13 = 0x00007ffc7a394170   r14 = 0x00007ffc7a394040
[task 2017-05-06T03:25:57.579814Z] 03:25:57     INFO -     r15 = 0x00007ffc7a394030   rip = 0x00007f253e7da32b
[task 2017-05-06T03:25:57.580572Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.581426Z] 03:25:57     INFO - 68  libxul.so!js::InternalCallOrConstruct [Interpreter.cpp:8f4637881ddc : 488 + 0xb]
[task 2017-05-06T03:25:57.582222Z] 03:25:57     INFO -     rbx = 0x00007ffc7a394250   rbp = 0x00007ffc7a3941e0
[task 2017-05-06T03:25:57.583062Z] 03:25:57     INFO -     rsp = 0x00007ffc7a394130   r12 = 0x00007f2537662000
[task 2017-05-06T03:25:57.583859Z] 03:25:57     INFO -     r13 = 0x00007f2537669000   r14 = 0x0000000000000000
[task 2017-05-06T03:25:57.584652Z] 03:25:57     INFO -     r15 = 0x00007ffc7a394170   rip = 0x00007f253e7da941
[task 2017-05-06T03:25:57.591086Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.591902Z] 03:25:57     INFO - 69  libxul.so!js::Call [Interpreter.cpp:8f4637881ddc : 534 + 0x5]
[task 2017-05-06T03:25:57.592691Z] 03:25:57     INFO -     rbx = 0x00007ffc7a394250   rbp = 0x00007ffc7a394200
[task 2017-05-06T03:25:57.593505Z] 03:25:57     INFO -     rsp = 0x00007ffc7a3941f0   r12 = 0x00007ffc7a394470
[task 2017-05-06T03:25:57.594629Z] 03:25:57     INFO -     r13 = 0x0000000000000001   r14 = 0x00007f2537662000
[task 2017-05-06T03:25:57.595422Z] 03:25:57     INFO -     r15 = 0x00007ffc7a394230   rip = 0x00007f253e7dadcd
[task 2017-05-06T03:25:57.596188Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.597035Z] 03:25:57     INFO - 70  libxul.so!JS_CallFunctionValue [jsapi.cpp:8f4637881ddc : 2832 + 0x5]
[task 2017-05-06T03:25:57.597812Z] 03:25:57     INFO -     rbx = 0x00007ffc7a394250   rbp = 0x00007ffc7a394320
[task 2017-05-06T03:25:57.598657Z] 03:25:57     INFO -     rsp = 0x00007ffc7a394210   r12 = 0x00007ffc7a394220
[task 2017-05-06T03:25:57.599449Z] 03:25:57     INFO -     r13 = 0x0000000000000001   r14 = 0x00007f2537662000
[task 2017-05-06T03:25:57.600539Z] 03:25:57     INFO -     r15 = 0x00007ffc7a394230   rip = 0x00007f253ebd9256
[task 2017-05-06T03:25:57.601695Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.602498Z] 03:25:57     INFO - 71  libxul.so!nsXPCWrappedJSClass::CallMethod [XPCWrappedJSClass.cpp:8f4637881ddc : 1214 + 0x5]
[task 2017-05-06T03:25:57.603299Z] 03:25:57     INFO -     rbx = 0x00007ffc7a394460   rbp = 0x00007ffc7a394740
[task 2017-05-06T03:25:57.604100Z] 03:25:57     INFO -     rsp = 0x00007ffc7a394330   r12 = 0x00007ffc7a3943d8
[task 2017-05-06T03:25:57.604873Z] 03:25:57     INFO -     r13 = 0x0000000000000003   r14 = 0x00007ffc7a394570
[task 2017-05-06T03:25:57.605683Z] 03:25:57     INFO -     r15 = 0x00007f2531b6aab0   rip = 0x00007f253c553114
[task 2017-05-06T03:25:57.606474Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.607282Z] 03:25:57     INFO - 72  libxul.so!PrepareAndDispatch [xptcstubs_x86_64_linux.cpp:8f4637881ddc : 120 + 0x16]
[task 2017-05-06T03:25:57.608052Z] 03:25:57     INFO -     rbx = 0x00007ffc7a3947b8   rbp = 0x00007ffc7a394850
[task 2017-05-06T03:25:57.608853Z] 03:25:57     INFO -     rsp = 0x00007ffc7a394750   r12 = 0x00007ffc7a3948e0
[task 2017-05-06T03:25:57.609628Z] 03:25:57     INFO -     r13 = 0x00007ffc7a3947a0   r14 = 0x00007f2531164cc0
[task 2017-05-06T03:25:57.610424Z] 03:25:57     INFO -     r15 = 0x00007ffc7a394890   rip = 0x00007f253be62edb
[task 2017-05-06T03:25:57.611198Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.611986Z] 03:25:57     INFO - 73  libxul.so!SharedStub + 0x5b
[task 2017-05-06T03:25:57.612768Z] 03:25:57     INFO -     rbx = 0x00007ffc7a394908   rbp = 0x00007ffc7a3948d0
[task 2017-05-06T03:25:57.613566Z] 03:25:57     INFO -     rsp = 0x00007ffc7a394860   r12 = 0x00007ffc7a394948
[task 2017-05-06T03:25:57.614356Z] 03:25:57     INFO -     r13 = 0x00007ffc7a394910   r14 = 0x00007ffc7a394c50
[task 2017-05-06T03:25:57.615162Z] 03:25:57     INFO -     r15 = 0x00007ffc7a3949dc   rip = 0x00007f253be6235b
[task 2017-05-06T03:25:57.617115Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.617947Z] 03:25:57     INFO - 74  libxul.so!nsXREDirProvider::DoStartup [nsXREDirProvider.cpp:8f4637881ddc : 1159 + 0x11]
[task 2017-05-06T03:25:57.618803Z] 03:25:57     INFO -     rdx = 0x00007ffc7a393498   rcx = 0x00007f2537662060
[task 2017-05-06T03:25:57.619683Z] 03:25:57     INFO -     rbx = 0x00007ffc7a394908   rsi = 0xfff9000000000000
[task 2017-05-06T03:25:57.620464Z] 03:25:57     INFO -     rdi = 0x00007ffc7a392c50   rbp = 0x00007ffc7a394980
[task 2017-05-06T03:25:57.621255Z] 03:25:57     INFO -     rsp = 0x00007ffc7a3948e0    r8 = 0x151aa5e1e1a5f594
[task 2017-05-06T03:25:57.622054Z] 03:25:57     INFO -      r9 = 0x3feccccccccccccd   r12 = 0x00007ffc7a394948
[task 2017-05-06T03:25:57.622871Z] 03:25:57     INFO -     r13 = 0x00007ffc7a394910   r14 = 0x00007ffc7a394c50
[task 2017-05-06T03:25:57.623654Z] 03:25:57     INFO -     r15 = 0x00007ffc7a3949dc   rip = 0x00007f253e65e005
[task 2017-05-06T03:25:57.624444Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.625253Z] 03:25:57     INFO - 75  libxul.so!XREMain::XRE_mainRun [nsAppRunner.cpp:8f4637881ddc : 4381 + 0xc]
[task 2017-05-06T03:25:57.626072Z] 03:25:57     INFO -     rbx = 0x00007ffc7a394a70   rbp = 0x00007ffc7a394b00
[task 2017-05-06T03:25:57.626879Z] 03:25:57     INFO -     rsp = 0x00007ffc7a394990   r12 = 0x00007ffc7a394a30
[task 2017-05-06T03:25:57.627672Z] 03:25:57     INFO -     r13 = 0x00007ffc7a394bd0   r14 = 0x00007ffc7a3949e8
[task 2017-05-06T03:25:57.628504Z] 03:25:57     INFO -     r15 = 0x00007ffc7a3949dc   rip = 0x00007f253e654e2e
[task 2017-05-06T03:25:57.629312Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.630092Z] 03:25:57     INFO - 76  libxul.so!XREMain::XRE_main [nsAppRunner.cpp:8f4637881ddc : 4726 + 0x5]
[task 2017-05-06T03:25:57.630907Z] 03:25:57     INFO -     rbx = 0x00007ffc7a394bd0   rbp = 0x00007ffc7a394bb0
[task 2017-05-06T03:25:57.631691Z] 03:25:57     INFO -     rsp = 0x00007ffc7a394b10   r12 = 0x0000000000000000
[task 2017-05-06T03:25:57.632491Z] 03:25:57     INFO -     r13 = 0x00007ffc7a394c48   r14 = 0x0000000000000001
[task 2017-05-06T03:25:57.634159Z] 03:25:57     INFO -     r15 = 0x00007ffc7a394b58   rip = 0x00007f253e655ca1
[task 2017-05-06T03:25:57.634989Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.635777Z] 03:25:57     INFO - 77  libxul.so!XRE_main [nsAppRunner.cpp:8f4637881ddc : 4819 + 0x5]
[task 2017-05-06T03:25:57.638760Z] 03:25:57     INFO -     rbx = 0x00007ffc7a394bd0   rbp = 0x00007ffc7a394da0
[task 2017-05-06T03:25:57.639620Z] 03:25:57     INFO -     rsp = 0x00007ffc7a394bc0   r12 = 0x0000000000000001
[task 2017-05-06T03:25:57.640454Z] 03:25:57     INFO -     r13 = 0x00007ffc7a395ee8   r14 = 0x00007ffc7a394db0
[task 2017-05-06T03:25:57.641236Z] 03:25:57     INFO -     r15 = 0x0000000000000000   rip = 0x00007f253e655f33
[task 2017-05-06T03:25:57.642030Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.642865Z] 03:25:57     INFO - 78  firefox!do_main [nsBrowserApp.cpp:8f4637881ddc : 236 + 0x22]
[task 2017-05-06T03:25:57.643668Z] 03:25:57     INFO -     rbx = 0x0000000000000001   rbp = 0x00007ffc7a395dd0
[task 2017-05-06T03:25:57.646733Z] 03:25:57     INFO -     rsp = 0x00007ffc7a394db0   r12 = 0x00007ffc7a395ee8
[task 2017-05-06T03:25:57.647580Z] 03:25:57     INFO -     r13 = 0x00007ffc7a397f8a   r14 = 0x00007ffc7a395ef8
[task 2017-05-06T03:25:57.648365Z] 03:25:57     INFO -     r15 = 0x0000000000000000   rip = 0x0000000000406466
[task 2017-05-06T03:25:57.649182Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.649966Z] 03:25:57     INFO - 79  firefox!main [nsBrowserApp.cpp:8f4637881ddc : 307 + 0xe]
[task 2017-05-06T03:25:57.650768Z] 03:25:57     INFO -     rbx = 0x00007ffc7a395ee8   rbp = 0x00007ffc7a395e00
[task 2017-05-06T03:25:57.651593Z] 03:25:57     INFO -     rsp = 0x00007ffc7a395de0   r12 = 0x0000000000000001
[task 2017-05-06T03:25:57.654927Z] 03:25:57     INFO -     r13 = 0x00007ffc7a395ef8   r14 = 0x0000018fc81c8a01
[task 2017-05-06T03:25:57.655733Z] 03:25:57     INFO -     r15 = 0x0000000000000000   rip = 0x0000000000405c2e
[task 2017-05-06T03:25:57.656534Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.657310Z] 03:25:57     INFO - 80  libc-2.23.so + 0x20830
[task 2017-05-06T03:25:57.658105Z] 03:25:57     INFO -     rbx = 0x0000000000000000   rbp = 0x000000000041da90
[task 2017-05-06T03:25:57.658970Z] 03:25:57     INFO -     rsp = 0x00007ffc7a395e10   r12 = 0x0000000000405e58
[task 2017-05-06T03:25:57.659770Z] 03:25:57     INFO -     r13 = 0x00007ffc7a395ee0   r14 = 0x0000000000000000
[task 2017-05-06T03:25:57.660581Z] 03:25:57     INFO -     r15 = 0x0000000000000000   rip = 0x00007f254bb02830
[task 2017-05-06T03:25:57.661560Z] 03:25:57     INFO -     Found by: call frame info
[task 2017-05-06T03:25:57.665233Z] 03:25:57     INFO - 81  firefox!MOZ_ReportAssertionFailure [Assertions.h:8f4637881ddc : 164 + 0x5]
[task 2017-05-06T03:25:57.665741Z] 03:25:57     INFO -     rsp = 0x00007ffc7a395e30   rip = 0x0000000000405ba3
[task 2017-05-06T03:25:57.666311Z] 03:25:57     INFO -     Found by: stack scanning
Flags: needinfo?(kmaglione+bmo)
https://hg.mozilla.org/integration/mozilla-inbound/rev/2055a8ced8c5266cb2e8fa6f4e1f524f7a9f4415
Bug 1359653: Part 1 - Use a const Range rather than a Vector for XDR decoding. r=shu

https://hg.mozilla.org/integration/mozilla-inbound/rev/4303fccdaea09a9acf0d72d03e1d3060e20d43ca
Bug 1359653: Part 2 - Allow CloneAndExecuteScript with non-lexical scripts. r=shu

https://hg.mozilla.org/integration/mozilla-inbound/rev/9ddbf855c3d64baf3eb7de327088e99fd345e586
Bug 1359653: Part 3 - Add a clear() method and move asssignment operator to AutoCleanLinkedList. r=waldo

https://hg.mozilla.org/integration/mozilla-inbound/rev/6dcce95e536b33505ebf0cb2be0e175066e522f2
Bug 1359653: Part 4 - Fallback to the default JS version when decoding regexps off-thread. r=shu

https://hg.mozilla.org/integration/mozilla-inbound/rev/61ceee706442205c0bef2139080825aeaffb5e84
Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background thread. r=shu,erahm

https://hg.mozilla.org/integration/mozilla-inbound/rev/9f7558cb95f3a44e09794422e72c8e485ea45748
Bug 1359653: Part 6 - Use the script precompiler in the JS component loader and subscript loader. r=mccr8,shu

https://hg.mozilla.org/integration/mozilla-inbound/rev/f7156290b4c1ddb28317c771ab4fd35882748e93
Bug 1359653: Part 7 - Use the script preloader for loading frame scripts. r=billm

https://hg.mozilla.org/integration/mozilla-inbound/rev/bdb720cdac7148703a70eec2dfafd75c0f21c142
Bug 1359653: Part 8 - Ignore script cache when loading scripts in gcd script breakpoint tests. r=jimb

https://hg.mozilla.org/integration/mozilla-inbound/rev/b658ca8e2aed84bbc9cbeb52b341e7d40588a8bd
Bug 1359653: Part 9 - Observe "startupcache-invalidate" and flush the cache when received. r=erahm
I'm pretty sure the hazard analysis is just being overly cautious about PLDHashTable matchEntry, but I switched to a HandleScript anyway.
Flags: needinfo?(kmaglione+bmo)
https://hg.mozilla.org/integration/mozilla-inbound/rev/c5d7a36298e4160f9b9fda161902337a0112888b
Bug 1359653: Follow-up: Don't cache mochikit scripts as a temporary bustage workaround.
(In reply to Kris Maglione [:kmag] (busy; behind on reviews) from comment #81)
> Comment on attachment 8861706 [details]
> Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background
> thread.
> 
> https://reviewboard.mozilla.org/r/133686/#review138714
> 
> > Hm, gut reaction here is I'd rather see Vector than nsTArray. Up to you.
> 
> I started out with a Vector but Eric asked me to switch it to a nsTArray :)

There was some stuff for manually managing growth and memory measurement I think? nsTArray does that, maybe Vector does to but that's not how the code was written.

> > Whoa what is this syntax? Does this mean for any constructors that don't explicitly initialize error\_ to a value, it'll be false?
> 
> Yeah, it's a C++11 thing.

We should probably do a dev-platform post about whether we're cool with this style, I didn't ding it because we don't say *not* to use it anywhere.

> > The 2 linked list + hashtable + moving scripts from one set to the other seems unwieldy to me. I don't feel too strongly about it, but would like more documentation about the relationship between the 2 lists of scripts.
> 
> Yeah, I agree. I didn't want the hashtable in the first place, but Eric
> asked for it. In bug 1361792, I added timestamps to the hash elements, and
> got rid of the linked lists.

To be clear, I'd prefer no lists at all. We have 200 or so scripts so we needed a faster lookup than linear string search on a linked list.
(In reply to Eric Rahm [:erahm] (PTO May 4 - 8) from comment #89)
> (In reply to Kris Maglione [:kmag] (busy; behind on reviews) from comment
> #81)
> > Comment on attachment 8861706 [details]
> > Bug 1359653: Part 5 - Pre-load scripts needed during startup in a background
> > thread.
> > 
> > https://reviewboard.mozilla.org/r/133686/#review138714
> > 
> > > Hm, gut reaction here is I'd rather see Vector than nsTArray. Up to you.
> > 
> > I started out with a Vector but Eric asked me to switch it to a nsTArray :)
> 
> There was some stuff for manually managing growth and memory measurement I
> think? nsTArray does that, maybe Vector does to but that's not how the code
> was written.

It does to some extent. I think I was doing slightly more explicit memory management than necessary. But the code is still much simpler with nsTArray, especially since it has infallible variants of most operations.

> > > Whoa what is this syntax? Does this mean for any constructors that don't explicitly initialize error\_ to a value, it'll be false?
> > 
> > Yeah, it's a C++11 thing.
> 
> We should probably do a dev-platform post about whether we're cool with this
> style, I didn't ding it because we don't say *not* to use it anywhere.

[1] says we can.

[1]: https://developer.mozilla.org/en-US/docs/Using_CXX_in_Mozilla_code
Is it possible this caused bug 1362837?

[task 2017-05-07T00:34:10.600177Z] 00:34:10     INFO -  PID 7226 | \x07[7226] ###!!! ASSERTION: Using observer service after XPCOM shutdown!: 'Error', file /home/worker/workspace/build/src/xpcom/ds/nsObserverService.cpp, line 201
[task 2017-05-07T00:34:45.689918Z] 00:34:45     INFO -  PID 7226 | #01: mozilla::ScriptPreloader::ScriptPreloader [xpcom/base/nsCOMPtr.h:762]
Blocks: 1362837
No longer blocks: 1362837
Depends on: 1362837
Depends on: 1363301
== Change summary for alert #6439 (as of May 06 2017 02:27 UTC) ==

Regressions:

  1%  ts_paint osx-10-10 opt      1,152.58 -> 1,168.33
  1%  ts_paint osx-10-10 opt e10s 1,178.83 -> 1,190.50

Improvements:

 10%  sessionrestore_no_auto_restore linux64 opt      932.50 -> 842.83
  9%  sessionrestore linux64 opt                      898.75 -> 817.42
  8%  sessionrestore linux64 pgo                      713.75 -> 660.17
  7%  ts_paint linux64 opt                            1,369.38 -> 1,276.33
  6%  sessionrestore linux64 pgo e10s                 590.79 -> 554.25
  6%  ts_paint linux64 pgo                            1,127.38 -> 1,058.17
  6%  ts_paint linux64 pgo e10s                       1,026.04 -> 969.17

For up to date results, see: https://treeherder.mozilla.org/perf.html#/alerts?id=6439
Blocks: 1363482
Blocks: webext-perf
See Also: → 1364974
Depends on: 1368701
Depends on: 1375704
No longer depends on: 1362837
Depends on: 1385822
Depends on: 1387719
Depends on: 1382329
Depends on: 1544034
Regressions: 1540035
Performance Impact: --- → P1
Whiteboard: [qf:p1]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: