Closed Bug 670185 Opened 8 years ago Closed 8 years ago
TI: Lazily create type objects for singleton JS objects
On a GMail testcase, 84% of the type objects in use after a minute (36655 out of 43564) are for singleton JS objects (i.e. only one JS object can have that type). Breakdown: 21190 (58%) look like they are natives for standard class and XPCOM functions. 13875 (38%) are scripted functions defined at the top level of global and eval scripts 2427 (7%, the balance) are prototypes created through 'foo.prototype = new bar()' We eagerly allocate these type objects and keep track of the possible types of their properties. This is chewing up a lot of memory, and it should not be hard to be lazier here: the information the types are tracking is concisely represented in the properties of the JS object themselves. Instead of making the type object immediately, make it only when necessary --- analysis of a script is trying to put constraints on a property of the object. Type sets should be rejiggered so that they can contain JS objects directly.
WIP, compiles but doesn't do anything else, still lots of missing functionality. This is rolling in other memory-reduction changes to release more data on each GC (this is all touching the same stuff, so I'd like to do it together rather than write-stabilize-rewrite each piece). For objects with lazily constructed types, even if an analyzed/compiled script ends up forcing construction of that type we want to remove the type as soon as nothing needs it anymore. Condensed constraints computed this sort of thing on each GC, but these eat memory and are I think expensive to compute (hashtable lookup for every single constraint generated since the last GC), and are probably the source of much of the GC slowdown with TI enabled. This patch removes condensed constraints entirely. These were around so that we could continue to use mjit code after destroying the analysis information it depended on, so this patch wipes out mjit code at the same time as analysis information. Will work even if that mjit code is on the stack, a nice benefit to being able to throw JIT frames into the interpreter anytime we're in C++. For now this wipes out the analysis info and jitcode on every GC (silly exception for GCs that happen during analysis/compilation). That may need tweaking with heuristics, but I don't think will hurt much (will need measuring). The half-life mechanic we currently use was designed back when we method JIT'ed all code, not just warm code. To my knowledge, websites where we take a big compilation cost are because of doing lots of recompilation, and if we hang onto observed types in scripts longer (not much longer, a few minutes tops) we won't be subsequently starting from square one and can get back up to speed more quickly.
Assignee: general → bhackett1024
Mostly done, passes jit-tests. This rolls in a fix for bug 656727 --- add an ANYOBJECT flag to type sets, which both simplifies handling of mutable __proto__ (don't need to think about interchangeability of objects with unknown properties in type sets) and will also help reduce time/memory in tracking sets of objects we won't be able to do useful optimizations with anyways.
Attachment #545446 - Attachment is obsolete: true
Patch landed on JM. This mostly adds some tweaks so that when the browser mutates object prototypes we aren't forced to crawl the compartment looking for type sets containing the old/new type. http://hg.mozilla.org/projects/jaegermonkey/rev/b769a2b79e6b This is the 'tests pass' push (at least in the shell), not the 'works as advertised' one. I still need to look at browser memory, and haven't done much perf testing. This shouldn't affect perf except for improvements in tests that have bad type info (JSLint).
Attachment #545985 - Attachment is obsolete: true
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.