Opened 11 years ago

Last modified 7 years ago

#1886 closed enhancement

Upgrade Spidermonkey — at Version 38

Reported by: Yves Owned by: Yves
Priority: Must Have Milestone: Alpha 16
Component: Core engine Keywords: spidermonkey javascript debugger
Cc: javierjc1982@… Patch:

Description (last modified by Yves)

Tickets related to the Spidermonkey upgrade:

#2126
#2137
#2140
#2172
#2212
#2213
#2241
#2267
#2322
#2348
#2372
#2416

Related bugs in Spidermonkey:


Meta-Bug for performance bugs affecting 0 A.D.: Bug 897962

Overview

We are currently using Spidermonkey 1.8.5. That's a very old version and we need to upgrade to a newer version for various reasons. Unfortunately that's not very easy because the API changes quite often.

Also check the forum thread for the current status.

Reasons for upgrading:

  • Switching earlier avoids writing too much code for the older API that has to be changed later
  • Only when using a supported version it's possible to fix Spidermonkey security issues (I know that 0 A.D. itself most likely has more security issues at the moment)
  • Learning how the new API works with multi-threading is important for our AI multi-threading design.
  • Performance: During the work on upgrading we figured out that performance currently isn't much better in the new version compared to v1.8.5. The huge improvements from benchmarks don't translate to most real world applications. Loading random maps is a lot faster, but that's the only thing at the moment. It's still possible that the performance will improve once the most important bugs in Ion Monkey and Baseline are fixed.
  • If we find bugs in v1.8.5 we will never get support from Mozilla. If we use the current version or if the same bug also affects the current version, getting help is much more likely.
  • Getting new features into the official version of Spidermonkey is also only possible when we use the current version.
  • Many Linux distributions will use the new ESR versions of the standalone library. It's better to use that library provided by the system instead of bundling our own version. v1.8.5 won't be supported by Linux distributions forever.

Version

Mozilla plans to release standalone versions of Spidermonkey for each ESR-release. Currently we don't know which version of Spidermonkey we will use because some performance bugs need to be fixed in the current version of Spidermonkey.

JIT

The Just In Time compiler creates optimized bytecode or even native assembler code for functions or loops that are called often. That's something different than the compiling which translates the scripts to bytecode in the first step.

It's currently not possible to JIT-compile the scripts before they are executed or even store them in JIT-compiled form on the disc.

Using js::NotifyAnimationActivity it's possible to prevent the garbage collection from collecting generated JIT-code (and forcing recompilation). Unfortunately this only works if js::NotifyAnimationActivity is called at least once a second. With big lag-spikes, especially in debug mode, this can't be guaranteed at the moment. At the moment I'm working around this by modifying Spidermonkey's Runtime.cpp directly. I'll have to find a better solution.

Garbage collection

Garbage collection and memory allocation is a major bottleneck for certain parts of JS code that update a lot of data very often. I made some measurements here: http://www.wildfiregames.com/forum/index.php?showtopic=16721&#entry262183

Garbage collection could be improved by improving the way we handle compartments, especially related to the AI. That's a bit vague but I'm still trying to figure out more about that. An interesting article: http://andreasgal.com/2010/10/13/compartments/ . That article is quite old, but I think the basic concepts explained there are still valid.

Garbage collection can now even be done in a separate thread or we could run it more often (each frame for example) to avoid lag-spikes when it happens. For the AI that problem would probably be solved anyway when we move it to a separate thread.

Change History (43)

comment:1 by Yves, 11 years ago

Status: newassigned

comment:2 by Yves, 11 years ago

I asked about the JIT topic and Ion-Monkey in the jsapi IRC channel. Logs here.

Summary: JIT compiled code can't be saved on the harddisk and used later because it contains memory addresses. However, a function should be compiled with Ion-Monkey when it has been run 1000 times, so everything that runs once per frame should be compiled after about 30 seconds with 30-35 fps, which should be fine for the moment.

Garbage collection occasionally throws away the JIT-ed code. To make sure this doesn't happen, calling "js::NotifyAnimationActivity" should be enough. Check Bug 753630 for more background information about that.

by Yves, 11 years ago

just for reference and discussion in the associate thread

by Yves, 11 years ago

just for reference and discussion in the associate thread

comment:3 by Yves, 11 years ago

Keywords: spidermonkey javascript debugger added

comment:4 by ben, 11 years ago

In 13429:

Extends binary serializer to support some standard JS classes: Number, String, Boolean. Fixes #406.
Extends binary serializer to support typed arrays.
Extends binary serializer to support custom JS prototype objects in AIs, fixes #407.
Allows full serialization of AIs (not yet implemented). Refs #1089, #1886
Increases binary serializer script backref arena from 8 MB to 16 MB, refs #1842

comment:5 by historic_bruno, 11 years ago

Keywords: spidermonkey, javascript, debugger → spidermonkey javascript debugger

r13429 ref'd this ticket because I had to use some hacks to get around AIs sharing data between script contexts. Actually the solution could be much simpler if each AI's data was in a single script context (then ScriptInterface could be used to hold the serializable prototypes, and the implementation wouldn't be AI specific).

Also a heads up since probably these changes will need merging into your local repo, feel free to ask if anything causes trouble.

Last edited 11 years ago by historic_bruno (previous) (diff)

comment:6 by Kieran P, 11 years ago

Milestone: Alpha 14Backlog

comment:7 by Yves, 11 years ago

Description: modified (diff)

comment:8 by Yves, 11 years ago

In 13826:

Changes GameView to expose global functions to scripts instead of using CJSObject.
Fixes #2126
Refs #1886

comment:9 by Yves, 11 years ago

Description: modified (diff)

comment:10 by Yves, 11 years ago

In 13877:

Changes the Renderer to expose global functions to scripts instead of using CJSObject.
Fixes #2137
Refs #1886

comment:11 by Yves, 11 years ago

Description: modified (diff)

comment:12 by Yves, 11 years ago

In 13884:

Changes the Console to expose global functions to scripts instead of properties.
Fixes #2140
Refs #1886

comment:13 by Yves, 11 years ago

Description: modified (diff)

comment:14 by Yves, 11 years ago

Description: modified (diff)

comment:15 by Yves, 11 years ago

Description: modified (diff)

comment:16 by fabio, 11 years ago

Description: modified (diff)

comment:17 by Yves, 11 years ago

Description: modified (diff)

comment:18 by Yves, 11 years ago

In 13914:

Changes the ConfigDB to expose global functions to scripts instead of properties and custom objects.
Fixes #2172
Refs #1886

comment:19 by Yves, 11 years ago

Description: modified (diff)

comment:20 by Yves, 11 years ago

In 14026:

Remove ScriptableObject/CJSObject

Since all remaining uses of ScriptableObject/CJSObject have been removed, the related files can now also be removed.
Closes #2212
Refs #2126
Refs #2137
Refs #1886

comment:21 by Yves, 11 years ago

Description: modified (diff)

comment:22 by Yves, 11 years ago

In 14036:

Unify script conversions and remove JSInterface_Vector3D.

Because it was historically grown, we have some duplicated code for converting script types to native types.
This patch removes the file JSConversions.cpp and moves some code to ScriptConversions.cpp.
The places using JSConversions.cpp are changed to use the ScriptInterface's conversion functions in ScriptConversions.cpp.
I also removed JSInterface_Vector3D because it had additional requirements to the conversion code that no other code has and because it's currently not used. I think it doesn't make sense to maintain code just because it could possibly be used again later.

Closes #2213
Refs #1886

comment:23 by Yves, 11 years ago

Description: modified (diff)

comment:24 by Yves, 10 years ago

Description: modified (diff)

comment:25 by Yves, 10 years ago

In 14199:

In #2241 I'm going to change the GUI to have one ScriptInterface for each GUI page because that will be required for the Spidermonkey upgrade (#1886).
The Multiplayer lobby needs some changes to avoid compartment mismatches. Instead of initializing it with a ScriptInterface and storing script values at different locations, it takes a ScriptInterface argument in the functions that really need to read or write some script values and avoids storing values as script values with an associated compartment where possible.
The scripting interface of the lobby is also adjusted to use JSInterface_Lobby.h/cpp files as other components instead of adding all functions to ScriptFunctions.cpp. This makes it a bit more clearly arranged IMO.

Fixes #2267
Refs #2241
Refs #1886

comment:26 by Yves, 10 years ago

Description: modified (diff)

comment:27 by Yves, 10 years ago

In 14441:

Moves AI players to one global using the module pattern.
This avoids wrapping overhead that would otherwise be required because multiple globals per compartment aren't supported anymore in newer versions of SpiderMonkey.

Check the ticket for a detailed explanation.

Closes #2322
Refs #2241
Refs #1886

comment:28 by Yves, 10 years ago

In 14496:

Removes g_ScriptingHost and implements global to compartment 1 to 1 relation.
Each GUI Page gets its own compartment and all ScriptInterfaces in the same thread should now use the same JS Runtime.
This is required for the SpiderMonkey upgrade.
Check the ticket for details.

Closes #2241
Refs #1886
Refs #1966

comment:29 by Yves, 10 years ago

Description: modified (diff)

comment:30 by Yves, 10 years ago

In 14506:

Disables the JS debugger.
It's completely broken since r14496 and will have to be updated for the new SpiderMonkey API.
I only uncomment it at the moment because I plan to fix/reimplement it soon after the upgrade.

Closes #2348
Refs #2241
Refs #1886

by Yves, 10 years ago

Attachment: patch_26_v0.7.diff added

Current patch with SpiderMonkey version 145669:aa9ec17cf912 (http://hg.mozilla.org/mozilla-central) and 0 A.D. version r14528 . This is still heavily WIP. There's a description how to apply it here: http://www.wildfiregames.com/forum/index.php?showtopic=17289&st=80#entry271330

comment:31 by Yves, 10 years ago

Command to find missing var statements (probably not perfect but it worked and I need a place to write it down): grep --perl-regexp -R '(for\s?\()(?!var|\svar)' --exclude=\*{~,svn-base}

comment:32 by Yves, 10 years ago

Description: modified (diff)

by Yves, 10 years ago

Attachment: SpiderMonkeyESR24_v0.8.diff added

The current WIP patch for ESR24 (download it here and copy it to libraries/source/spidermonkey: https://ftp.mozilla.org/pub/mozilla.org/js/mozjs-24.2.0.tar.bz2)

comment:33 by fabio, 10 years ago

A couple of suggestions:

  • rather than hardcoding -j5 you could use -jnproc (nproc inside back ticks which the trac is omitting here), and fall back to 2 if nproc is not available;
  • the build script could do a wget for mozjs24 tar.gz, rather than having it in the svn, reducing svn size and making easy to upgrade to, example, a .0.1 version.
Last edited 10 years ago by fabio (previous) (diff)

in reply to:  33 comment:34 by sanderd17, 10 years ago

Replying to fabio:

  • the build script could do a wget for mozjs24 tar.gz, rather than having it in the svn, reducing svn size and making easy to upgrade to, example, a .0.1 version.

I don't agree with this. I'd like to be able to build the game when being offline too.

comment:35 by Yves, 10 years ago

Milestone: BacklogAlpha 16

by Yves, 10 years ago

Attachment: SpiderMonkeyESR24_v0.9.diff added

Current WIP patch for ESR24. This version is with incremental GC. It's still WIP and there are still some known errors.

comment:36 by Yves, 10 years ago

@Fabio Thanks for the input. I'll try to set the -j option dynamically.

I agree with Sander and would rather bundle it at the moment. I remember some discussions about scripts for getting platform-specific dependencies. It could be worth developing something, but it should be a general solution for all libraries and dependencies.

Btw. sorry for answering late. E-Mail notifications still don't work for me and I didn't notice your comment in the logs.

Last edited 10 years ago by Yves (previous) (diff)

in reply to:  33 comment:37 by leper, 10 years ago

Replying to fabio:

A couple of suggestions:

  • rather than hardcoding -j5 you could use -jnproc (nproc inside back ticks which the trac is omitting here), and fall back to 2 if nproc is not available;

Just pass -jsomething to update-workspaces.sh and the spidermonkey build.sh script will use the same value. (I'd probably leave the default at -j2 though, or change it to -j1)

comment:38 by Yves, 10 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.