Closed Bug 669815 Opened 13 years ago Closed 13 years ago

Type inference uses too much memory

Categories

(Core :: JavaScript Engine, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED FIXED
Tracking Status
firefox8 - ---

People

(Reporter: gwagner, Assigned: bhackett1024)

References

Details

(Keywords: memory-footprint, regression, Whiteboard: [MemShrink:P1][see comments 17 and 18])

Attachments

(9 files)

There came a JS heap regression with the merge from JM. I just open gmail, gdocs and techcrunch and waited for 5 minutes:

current TM trunk:
261.08 MB -- resident
234.00 MB -- heap-committed
209.96 MB -- heap-used
 50.00 MB -- js-gc-heap
 24.03 MB -- heap-unused

yesterday TM trunk:
195.75 MB -- resident
161.00 MB -- heap-committed
140.68 MB -- heap-used
 39.00 MB -- js-gc-heap
 20.32 MB -- heap-unused

Even after minimizing memory usage I see almost the same numbers.

Also background sweeping seems to be disabled.
Yesterday trunk has usually 28 ms GC pause time (24ms mark and 4 ms sweep) and today 60ms (30ms mark and 30ms sweep).
Ouch!  Need to fix this.
Whiteboard: [MemShrink:P1]
Sounds like something we need to track for Fx8....
Where is documentation on each of these categories?

The only extra memory the Ti stuff allocates is all malloc'ed, and since all the numbers increased I suspect this is at least in part due to GC scheduling.
(In reply to comment #3)
> Where is documentation on each of these categories?

You mean the measurements in comment 0?  Open about:memory and hover your mouse over the names, you'll get tool-tips with explanations.

> The only extra memory the Ti stuff allocates is all malloc'ed, and since all
> the numbers increased I suspect this is at least in part due to GC
> scheduling.

The bit about background sweeping not working makes it sound like something got broken.
The GC profile looks very different. The marking phase for the splay benchmark got more expensive and the sweeping cost also increased since yesterday.
I did some more measurements and a side-by-side browsing of random websites.
I openend Gmail, gdocs, amazon, techcrunch, facebook, ebay

After minimizing memory usage I see:

before merge
380.89 MB -- resident
211.64 MB -- heap-zone0-used
169.58 MB -- heap-zone0-committed
169.57 MB -- heap-used
 76.00 MB -- js-gc-heap
 48.07 MB -- heap-unused

after
499.97 MB -- resident
311.29 MB -- heap-zone0-used
235.67 MB -- heap-zone0-committed
235.66 MB -- heap-used
100.00 MB -- js-gc-heap
 81.63 MB -- heap-unused

But more serious are the GC regressions. I see an 3x slowdown there. With only these six sites the pause time increases from 100ms to 300ms.
and the output for current trunk. I don't understand why marking and sweeping got more expensive.
Could your fragmentation fixes somehow gotten washed out in the mix?  I can't think of anything else offhand that is fairly small and yet could have such a dramatic effect.  Though I don't recall the fix improving the speed by 3x...
Depends on: 669958
Some more on GC changes pulled from JM.

- Size of all GC things is the same.
- Number of allocated GC things is the same.
- Reachability of GC things *should* be the same.

Changes in the JM branch which can affect GC behavior and timing.

- Most memory used by inference and analyses is wiped out on each GC (compartment->pool).

- We malloc TypeObjects, which have a mark bit (similar to how shapes used to work).  Marking a JSObject entails marking its type, which will at the least need to check this bit.  Unlike the old shapes, TypeObjects are malloc'ed individually so there is a lot of fragmentation and cache miss potential.  It should be straightforward to turn TypeObject into a GC thing and use the existing mark machinery.

- Each TypeObject also mallocs memory for its possible properties, and (possibly) sets of objects in the types of each of those properties.  Scripts also allocate to store the type sets of their locals/args and the results of property accesses in them.  The total amount of allocation here is small on benchmarks, which probably has no correlation at all with website behavior.  In any case, it is not being measured, and that definitely needs to get fixed quickly.  Filed bug 669958.

- If we are allocating tons of TypeObjects and lots of large type sets in those objects and in scripts, it will slow down sweeping since we need to sweep all this stuff on each GC.

- There were some changes around background finalization object kinds (adding abstraction methods).  I tried to be careful here, but may have broken something.

- Object layout changes have objects continue using fixed slots after getting a slots array malloc'ed.  This should improve memory usage, and shouldn't slow down marking.

- The number of fixed slots for 'new' objects is tuned to information retained in the types of those objects, rather than always being four.  Also doubt this has much of an effect.
Depends on: 669969
Filed bug 669969 for TypeObject-as-GC-thing.
So, the obvious question:  if TI is disabled in the browser (javascript.options.typeinference), does the memory usage return to the previous levels?  The traceJIT might need to be turned back on again for a fair comparison.

If the answer is yes, that makes me happier, because we can at least pref it off while trying to fix it.
I wonder if the GC performance regressions are related to the timeouts in Bug 669819, which apparently involves a test with many forcegcs.
I want to do some testing before/after the merge.  Here are the revisions I'm planning to use, I hope they are appropriate:

Before:

  changeset:   72105:6840fbf4dcdd
  parent:      71636:cba007ad1747
  parent:      72104:a7684eca2bb7
  user:        Chris Leary <cdleary@mozilla.com>
  date:        Tue Jul 05 17:30:35 2011 -0700
  summary:     Merge mozilla-central and tracemonkey.

After (this includes the JM->TM merge plus two minor follow-up fixes):

  changeset:   72778:462359e1347b
  user:        Brian Hackett <bhackett1024@gmail.com>
  date:        Wed Jul 06 06:30:49 2011 -0700
  summary:     Fix memory leak.
So I compared 72105:6840fbf4dcdd (pre-TI) with 72778:462359e1347b (post-TI).  My steps:

- Start browser with almost new profile
- Open about:memory?verbose in the starting tab
- Open http://v8.googlecode.com/svn/data/benchmarks/current/run.html in a new tab
- As soon as it finishes, switch back to about:memory?verbose and refresh
- Copy and paste the output

I've attached the full output.  Here's the important parts:


pre-TI
------
582,148,466 B (100.0%) -- explicit
├──552,086,249 B (94.84%) -- js
│  ├──322,748,224 B (55.44%) -- gc-heap-chunk-unused
│  ├──200,245,729 B (34.40%) -- compartment(http://v8.googlecode.com/svn/data/benchmarks/current/run.html)
│  │  ├──190,115,840 B (32.66%) -- gc-heap
│  │  │  ├──105,302,840 B (18.09%) -- objects
│  │  │  ├───62,244,608 B (10.69%) -- arena-unused
│  │  │  ├───19,910,912 B (03.42%) -- strings
│  │  │  ├────1,238,624 B (00.21%) -- arena-padding
│  │  │  ├────1,113,960 B (00.19%) -- arena-headers
│  │  │  ├──────304,896 B (00.05%) -- shapes
│  │  │  └────────────0 B (00.00%) -- xml

post-TI
-------
785,741,986 B (100.0%) -- explicit
├──740,388,613 B (94.23%) -- js
│  ├──472,924,416 B (60.19%) -- gc-heap-chunk-unused
│  ├──233,326,228 B (29.70%) -- compartment(http://v8.googlecode.com/svn/data/benchmarks/current/run
.html)
│  │  ├──231,284,736 B (29.44%) -- gc-heap
│  │  │  ├──180,081,464 B (22.92%) -- objects
│  │  │  ├───33,619,872 B (04.28%) -- strings
│  │  │  ├───14,240,672 B (01.81%) -- arena-unused
│  │  │  ├────1,535,768 B (00.20%) -- arena-padding
│  │  │  ├────1,355,184 B (00.17%) -- arena-headers
│  │  │  ├──────451,776 B (00.06%) -- shapes
│  │  │  └────────────0 B (00.00%) -- xml


AFAICT, with type inference the JS engine just thrashes the GC heap a lot harder.  Most parts of it are bigger.  With type inference disabled I got results quite similar to the pre-TI results.
I also see that disabling type inference solves the memory problem. 
The GC pause regression got better but it is still about 40%.
Similar experiment with techcrunch.com:

- Start browser with almost new profile
- Open about:memory?verbose in the starting tab
- Open http://techcrunch.com in a new tab
- Scroll down through all the stories, about 1 per second, ensuring all the buttons on each story expand
- Refresh about:memory?verbose, copy and paste the output

I tried this twice with the pre-TI version and got very similar results, so the repeatability should be good.

I switched my post-TI version to 72785:1d6b23739787, which has type inference measurements in about:memory.

Results are attached, for pre-TI, post-TI, and post-TI with TI disabled.  

Here's some of the results for the plusone.google.com tab:

pre-TI:
│  │   ├──11,919,360 B (05.61%) -- gc-heap
│  │   │  ├───6,710,176 B (03.16%) -- objects
│  │   │  ├───4,692,096 B (02.21%) -- shapes
│  │   │  ├─────184,256 B (00.09%) -- strings
│  │   │  ├─────181,344 B (00.09%) -- arena-padding
│  │   │  ├──────81,648 B (00.04%) -- arena-unused
│  │   │  ├──────69,840 B (00.03%) -- arena-headers
│  │   │  └───────────0 B (00.00%) -- xml
│  │   ├───5,788,230 B (02.72%) -- scripts

post-TI:
│  │   ├──18,038,784 B (05.95%) -- gc-heap
│  │   │  ├──10,448,192 B (03.45%) -- shapes
│  │   │  ├───6,601,568 B (02.18%) -- objects
│  │   │  ├─────483,960 B (00.16%) -- arena-unused
│  │   │  ├─────244,232 B (00.08%) -- arena-padding
│  │   │  ├─────155,136 B (00.05%) -- strings
│  │   │  ├─────105,696 B (00.03%) -- arena-headers
│  │   │  └───────────0 B (00.00%) -- xml
│  │   ├──17,759,552 B (05.86%) -- type-inference
│  │   │  ├───8,673,552 B (02.86%) -- object-main
│  │   │  ├───4,223,008 B (01.39%) -- script-main
│  │   │  ├───3,814,776 B (01.26%) -- object-typesets
│  │   │  └───1,048,216 B (00.35%) -- script-typesets
│  │   ├───7,033,820 B (02.32%) -- scripts

post-TI, with TI disabled:
│  │   ├──16,982,016 B (06.89%) -- gc-heap
│  │   │  ├───9,412,672 B (03.82%) -- shapes
│  │   │  ├───6,630,720 B (02.69%) -- objects
│  │   │  ├─────452,384 B (00.18%) -- arena-unused
│  │   │  ├─────231,600 B (00.09%) -- arena-padding
│  │   │  ├─────155,136 B (00.06%) -- strings
│  │   │  ├──────99,504 B (00.04%) -- arena-headers
│  │   │  └───────────0 B (00.00%) -- xml
│  │   ├───7,032,200 B (02.85%) -- scripts
...
│  │   ├───2,038,816 B (00.83%) -- type-inference
│  │   │   ├──2,038,816 B (00.83%) -- object-main
│  │   │   ├──────────0 B (00.00%) -- script-main
│  │   │   ├──────────0 B (00.00%) -- script-typesets
│  │   │   └──────────0 B (00.00%) -- object-typesets

Highlights:

- The type inference data is huge -- the same size as the gc-heap!  Even with TI disabled it's still taking 2MB.

- Shapes are *way* up in post-TI, 4.7MB to 10.5MB.  Even with TI disabled they're 9.4MB.  That accounts for almost all of the gc-heap difference.

- Scripts are ~20% bigger in post-TI, even with TI disabled.  Are they storing more info?

I looked carefully through various other compartments, these three differences look like they account for almost all the variation.
Similar experiment with gmail.com:

- Start browser with almost new profile
- Open about:memory?verbose in the starting tab
- Open http://gmail.com in a new tab, wait for inbox to load
- Open another folder, one with ~600 messages, wait to load
- Refresh about:memory?verbose, copy and paste the output

pre-TI:
│   ├──38,475,682 B (26.05%) -- compartment(https://mail.google.com/mail/u/0/?shva=1)
│   │  ├──15,904,768 B (10.77%) -- gc-heap                                    
│   │  │  ├───9,128,264 B (06.18%) -- objects                                 
│   │  │  ├───4,325,248 B (02.93%) -- shapes
│   │  │  ├───1,267,648 B (00.86%) -- strings                                 
│   │  │  ├─────873,488 B (00.59%) -- arena-unused                            
│   │  │  ├─────216,928 B (00.15%) -- arena-padding                           
│   │  │  ├──────93,192 B (00.06%) -- arena-headers                           
│   │  │  └───────────0 B (00.00%) -- xml
│   │  ├───8,310,784 B (05.63%) -- mjit-code                                  
│   │  ├───7,041,914 B (04.77%) -- scripts
│   │  ├───2,396,892 B (01.62%) -- string-chars                               
│   │  ├───2,272,728 B (01.54%) -- object-slots                               
│   │  ├───2,076,332 B (01.41%) -- mjit-data
│   │  ├─────341,192 B (00.23%) -- tjit-data                                  
│   │  │     ├──193,192 B (00.13%) -- allocators-main                         
│   │  │     └──148,000 B (00.10%) -- allocators-reserve                      
│   │  └─────131,072 B (00.09%) -- tjit-code

post-TI:
│   ├──43,818,344 B (27.05%) -- compartment(https://mail.google.com/mail/u/0/?shva=1)
│   │  ├──20,410,368 B (12.60%) -- gc-heap
│   │  │  ├───9,360,976 B (05.78%) -- objects
│   │  │  ├───7,998,912 B (04.94%) -- shapes
│   │  │  ├───1,715,160 B (01.06%) -- arena-unused
│   │  │  ├─────948,896 B (00.59%) -- strings
│   │  │  ├─────266,832 B (00.16%) -- arena-padding
│   │  │  ├─────119,592 B (00.07%) -- arena-headers
│   │  │  └───────────0 B (00.00%) -- xml
│   │  ├───8,412,390 B (05.19%) -- scripts
│   │  ├───6,721,536 B (04.15%) -- mjit-code
│   │  ├───2,512,582 B (01.55%) -- string-chars
│   │  ├───2,194,560 B (01.35%) -- mjit-data
│   │  ├───2,092,936 B (01.29%) -- object-slots
│   │  ├─────645,736 B (00.40%) -- type-inference
│   │  │     ├──645,736 B (00.40%) -- object-main
│   │  │     ├────────0 B (00.00%) -- script-main
│   │  │     ├────────0 B (00.00%) -- script-typesets
│   │  │     └────────0 B (00.00%) -- object-typesets
│   │  ├─────355,972 B (00.22%) -- type-inference-pools
│   │  ├─────341,192 B (00.21%) -- tjit-data
│   │  │     ├──193,192 B (00.12%) -- allocators-main
│   │  │     └──148,000 B (00.09%) -- allocators-reserve
│   │  └─────131,072 B (00.08%) -- tjit-code

The difference is less dramatic in this case, but we see a lot of the same things.  Approximate numbers:

- Shapes:       +3.7MB
- Scripts:      +1.4MB
- TI info:      +1.0MB
- arena-unused: +0.9MB
- mjit-code:    -1.6MB
                ------
- Total diff:   +5.3MB

So:  shapes, scripts, TI info again.  The arena-unused may not be meaningful.  The mjit-code is interesting.
Whiteboard: [MemShrink:P1] → [MemShrink:P1][see comments 17 and 18]
So it looks like real-world code is very different from v8bench.  The number of shapes involved differs enormously, in particular.
(In reply to comment #10)
> Some more on GC changes pulled from JM.
> 
> - Size of all GC things is the same.
> - Number of allocated GC things is the same.
> - Reachability of GC things *should* be the same.

The 2nd statement doesn't match what I saw with shapes.
(In reply to comment #20)
> (In reply to comment #10)
> > Some more on GC changes pulled from JM.
> > 
> > - Size of all GC things is the same.
> > - Number of allocated GC things is the same.
> > - Reachability of GC things *should* be the same.
> 
> The 2nd statement doesn't match what I saw with shapes.

Ah, right, forgot about this.  There are two ways we allocate new shapes:

1. Each script has a different shape hierarchy for its call objects (rather than all being rooted at the same empty shape).  This happens both whether TI is enabled or not.

2. Shapes hierarchies are rooted at the TypeObject, rather than the prototype.  If we allocate many type objects for a single prototype JS object and use them in similar ways, we would get a lot more shapes.  This is only an issue if TI is enabled, as if it is disabled type objects and prototype objects are 1-1.

There may be something else going on, as I will be extremely surprised if 1. is responsible for the huge TI-disabled difference here.  Will investigate this now.
 
Other stuff:

- Yeah, scripts store more data now.  sizeof(JSScript) increased some, but most of the increase you're seeing is probably fatter ops for property accesses --- property, name, and gname reads are tagged with a two byte index for the type set (in script-typesets) storing the values read from them.

- What do you see for GMail with TI enabled?
Depends on: 670152
Added some printfs and scraped them to see where the shapes we're finding were being allocated.  Summary: it looks like the call object shape changes are most of the problem.

Loaded up GMail with TI disabled, opened some messages, opened about:memory.

: 25435
ensure: 945
bindings: 62914
initscope: 1713
newobject: 12816
bound: 53
typeempty: 27749
typeshape: 47446
TOTAL: 179071

The 'bindings' category is the number of shapes found which were rooted at one of the per-script empty shapes.  Ignore the other categories (for now!).  35% of the shapes are in this category.

Made some changes so that with TI disabled we use a per-compartment empty shape for call objects (as we did before the TI merge), and redid the testcase.

: 26761
bound: 57
ensure: 10022
initscope: 1973
newobject: 13511
typeempty: 28909
typeshape: 53457
TOTAL: 134690

The 'ensure' category now has all shapes rooted at the per-compartment empty call shape (along with other shapes rooted at per-compartment singletons).  Making this change removed roughly 50,000 shapes on this testcase (30% of the total).

Filed bug 670152.  I think now this call object shape change wasn't necessary in the first place (didn't think the change would be a problem, so didn't give it too much thought originally), and can be easily fixed.
Depends on: 670185
> - What do you see for GMail with TI enabled?

See comment 18 (the "post-TI" numbers).

Or did you mean "TI disabled"?  If so, I took the measurements on another computer and I can't remember if I actually took them, but I expect they'll be in line with the techcrunch results in comment 17.
bhackett, why is the "type-inference/object-main" measurement non-zero with TI disabled?
Bug 670152 landed, which should help with the shapes.  I'll re-measure on Monday.
If type inference is disabled, we still allocate type objects for each prototype object, which will show up in type-inference/object-main.  I think there are a couple places where we allocate additional type objects even if inference is disabled, will investigate these while doing bug 670185.

The 'post-TI' GMail numbers have inference disabled, as you can see with the 'script-main', 'script-typesets' and 'object-typesets' being set to zero (these are always zero in compartments with inference disabled, and script-main is always non-zero in compartments with inference enabled that have ever run any code).  Remember that whether inference is enabled or not is set per compartment and depends on the option's state when the compartment was created, not the current options.  When comparing enabled/disabled it's probably best to change the option to the desired setting, then restart the browser.
(In reply to comment #26)
> 
> The 'post-TI' GMail numbers have inference disabled

Oh, you're right.  I must have forgotten to change the option.  (I have been restarting the browser each time.)  I'll remeasure on Monday.
I redid the techcrunch.com experiment with three versions:

- no TI:       tracemonkey  72792:7abfbaac0693
- disabled TI: jaegermonkey 72796:1d31362c86ce
- enabled TI:  jaegermonkey 72796:1d31362c86ce

Full results are attached.  Here are the plusone.google.com compartment resuls:

no TI:
│  ├───24,334,706 B (11.56%) -- compartment(https://plusone.google.com/...)
│  │   ├──12,013,568 B (05.71%) -- gc-heap
│  │   │  ├───6,708,096 B (03.19%) -- objects
│  │   │  ├───4,704,448 B (02.23%) -- shapes
│  │   │  ├─────185,440 B (00.09%) -- strings
│  │   │  ├─────182,600 B (00.09%) -- arena-padding
│  │   │  ├─────162,592 B (00.08%) -- arena-unused
│  │   │  ├──────70,392 B (00.03%) -- arena-headers
│  │   │  └───────────0 B (00.00%) -- xml
│  │   ├───5,788,148 B (02.75%) -- scripts
│  │   ├───4,456,448 B (02.12%) -- mjit-code
│  │   ├─────881,920 B (00.42%) -- mjit-data
│  │   ├─────786,320 B (00.37%) -- object-slots
│  │   ├─────208,136 B (00.10%) -- tjit-data
│  │   │     ├──148,000 B (00.07%) -- allocators-reserve
│  │   │     └───60,136 B (00.03%) -- allocators-main
│  │   ├─────131,072 B (00.06%) -- tjit-code
│  │   └──────69,094 B (00.03%) -- string-chars

disabled TI:
│  ├───29,282,754 B (12.59%) -- compartment(https://plusone.google.com/...)
│  │   ├──13,860,864 B (05.96%) -- gc-heap
│  │   │  ├───6,620,160 B (02.85%) -- objects
│  │   │  ├───6,354,368 B (02.73%) -- shapes
│  │   │  ├─────449,064 B (00.19%) -- arena-unused
│  │   │  ├─────200,920 B (00.09%) -- arena-padding
│  │   │  ├─────155,136 B (00.07%) -- strings
│  │   │  ├──────81,216 B (00.03%) -- arena-headers
│  │   │  └───────────0 B (00.00%) -- xml
│  │   ├───7,031,880 B (03.02%) -- scripts
│  │   ├───4,194,304 B (01.80%) -- mjit-code
│  │   ├───2,038,816 B (00.88%) -- type-inference
│  │   │   ├──2,038,816 B (00.88%) -- object-main
│  │   │   ├──────────0 B (00.00%) -- script-main
│  │   │   ├──────────0 B (00.00%) -- script-typesets
│  │   │   └──────────0 B (00.00%) -- object-typesets
│  │   ├───1,275,200 B (00.55%) -- mjit-data
│  │   ├─────645,120 B (00.28%) -- object-slots
│  │   ├─────187,976 B (00.08%) -- tjit-data
│  │   │     ├──148,000 B (00.06%) -- allocators-reserve
│  │   │     └───39,976 B (00.02%) -- allocators-main
│  │   ├──────48,562 B (00.02%) -- string-chars
│  │   ├──────────32 B (00.00%) -- type-inference-pools
│  │   └───────────0 B (00.00%) -- tjit-code

enabled TI:
│  ├───46,577,944 B (17.23%) -- compartment(https://plusone.google.com/...)
│  │   ├──17,780,896 B (06.58%) -- type-inference
│  │   │  ├───8,674,352 B (03.21%) -- object-main
│  │   │  ├───4,240,448 B (01.57%) -- script-main
│  │   │  ├───3,813,880 B (01.41%) -- object-typesets
│  │   │  └───1,052,216 B (00.39%) -- script-typesets
│  │   ├──14,938,112 B (05.53%) -- gc-heap
│  │   │  ├───7,389,888 B (02.73%) -- shapes
│  │   │  ├───6,588,608 B (02.44%) -- objects
│  │   │  ├─────503,360 B (00.19%) -- arena-unused
│  │   │  ├─────213,592 B (00.08%) -- arena-padding
│  │   │  ├─────155,136 B (00.06%) -- strings
│  │   │  ├──────87,528 B (00.03%) -- arena-headers
│  │   │  └───────────0 B (00.00%) -- xml
│  │   ├───7,033,500 B (02.60%) -- scripts
│  │   ├───5,505,024 B (02.04%) -- mjit-code
│  │   ├─────647,584 B (00.24%) -- object-slots
│  │   ├─────624,264 B (00.23%) -- mjit-data
│  │   ├──────48,532 B (00.02%) -- string-chars
│  │   ├──────────32 B (00.00%) -- type-inference-pools
│  │   ├───────────0 B (00.00%) -- tjit-code
│  │   └───────────0 B (00.00%) -- tjit-data
│  │               ├──0 B (00.00%) -- allocators-main
│  │               └──0 B (00.00%) -- allocators-reserve


Summary:
- Overall, the compartment grew 1.20x with TI disabled and 1.91x with TI enabled. 

- With bug 670152 landed, the shape increase is less.  But it's still large even with TI disabled (4.7MB / 6.4MB / 7.4MB).

- The type inference info is still very large (bug 670185 will hopefully improve this), and the scripts are still a bit bigger, of course.  Is there any chance of optimizing those fatter scripts ops?

The "object-main" numbers are surely low-hanging fruit if TI is disabled?

Gmail results coming up next.
Summary: JM merge regressions → Type inference uses too much memory
Like comment 28, but for gmail.

no TI:
│   ├──44,377,120 B (26.74%) -- compartment(https://mail.google.com/...)
│   │  ├──18,759,680 B (11.30%) -- gc-heap
│   │  │  ├──11,899,160 B (07.17%) -- objects
│   │  │  ├───4,605,248 B (02.77%) -- shapes
│   │  │  ├───1,557,632 B (00.94%) -- strings
│   │  │  ├─────326,176 B (00.20%) -- arena-unused
│   │  │  ├─────261,544 B (00.16%) -- arena-padding
│   │  │  ├─────109,920 B (00.07%) -- arena-headers
│   │  │  └───────────0 B (00.00%) -- xml
│   │  ├───8,376,320 B (05.05%) -- mjit-code
│   │  ├───7,177,912 B (04.33%) -- scripts
│   │  ├───4,504,596 B (02.71%) -- string-chars
│   │  ├───3,022,880 B (01.82%) -- object-slots
│   │  ├───2,059,436 B (01.24%) -- mjit-data
│   │  ├─────345,224 B (00.21%) -- tjit-data
│   │  │     ├──197,224 B (00.12%) -- allocators-main
│   │  │     └──148,000 B (00.09%) -- allocators-reserve
│   │  └─────131,072 B (00.08%) -- tjit-code

disabled TI:
│   ├──47,122,054 B (28.00%) -- compartment(https://mail.google.com/...)
│   │  ├──19,636,224 B (11.67%) -- gc-heap
│   │  │  ├──12,072,176 B (07.17%) -- objects
│   │  │  ├───5,366,400 B (03.19%) -- shapes
│   │  │  ├───1,535,808 B (00.91%) -- strings
│   │  │  ├─────275,744 B (00.16%) -- arena-unused
│   │  │  ├─────271,040 B (00.16%) -- arena-padding
│   │  │  ├─────115,056 B (00.07%) -- arena-headers
│   │  │  └───────────0 B (00.00%) -- xml
│   │  ├───8,539,387 B (05.07%) -- scripts
│   │  ├───7,114,752 B (04.23%) -- mjit-code
│   │  ├───4,755,338 B (02.83%) -- string-chars
│   │  ├───2,660,200 B (01.58%) -- object-slots
│   │  ├───2,274,520 B (01.35%) -- mjit-data
│   │  ├─────986,257 B (00.59%) -- type-inference-pools
│   │  ├─────681,096 B (00.40%) -- type-inference
│   │  │     ├──681,096 B (00.40%) -- object-main
│   │  │     ├────────0 B (00.00%) -- script-main
│   │  │     ├────────0 B (00.00%) -- script-typesets
│   │  │     └────────0 B (00.00%) -- object-typesets
│   │  ├─────343,208 B (00.20%) -- tjit-data
│   │  │     ├──195,208 B (00.12%) -- allocators-main
│   │  │     └──148,000 B (00.09%) -- allocators-reserve
│   │  └─────131,072 B (00.08%) -- tjit-code

enabled TI:
│  ├───79,350,500 B (34.70%) -- compartment(https://mail.google.com/...)
│  │   ├──21,893,120 B (09.57%) -- gc-heap
│  │   │  ├──11,809,432 B (05.16%) -- objects
│  │   │  ├───7,306,112 B (03.20%) -- shapes
│  │   │  ├───1,537,632 B (00.67%) -- strings
│  │   │  ├─────798,952 B (00.35%) -- arena-unused
│  │   │  ├─────312,712 B (00.14%) -- arena-padding
│  │   │  ├─────128,280 B (00.06%) -- arena-headers
│  │   │  └───────────0 B (00.00%) -- xml
│  │   ├──18,877,283 B (08.26%) -- type-inference-pools
│  │   ├──13,065,848 B (05.71%) -- type-inference
│  │   │  ├───6,411,864 B (02.80%) -- object-main
│  │   │  ├───3,513,896 B (01.54%) -- object-typesets
│  │   │  ├───2,131,552 B (00.93%) -- script-main
│  │   │  └───1,008,536 B (00.44%) -- script-typesets
│  │   ├───8,544,256 B (03.74%) -- mjit-code
│  │   ├───8,537,855 B (03.73%) -- scripts
│  │   ├───4,962,930 B (02.17%) -- string-chars
│  │   ├───2,341,328 B (01.02%) -- object-slots
│  │   ├───1,127,880 B (00.49%) -- mjit-data
│  │   ├───────────0 B (00.00%) -- tjit-code
│  │   └───────────0 B (00.00%) -- tjit-data
│  │               ├──0 B (00.00%) -- allocators-main
│  │               └──0 B (00.00%) -- allocators-reserve


Key stats:
- Shapes:  4.6MB / 5.4MB / 7.3MB
- Scripts: 7.2MB / 8.5MB / 8.5MB
- TI Info: 0.0MB / 1.7MB / 32.0MB
> - The type inference info is still very large (bug 670185 will hopefully
> improve this), and the scripts are still a bit bigger, of course.  Is there
> any chance of optimizing those fatter scripts ops?

I need to measure how much the increase in script data is from the fatter ops vs. the increase in sizeof(JSScript).  If the fatter ops are indeed to blame, we should be able to cut this cost, albeit by doing more volatile allocation (see below).

> The "object-main" numbers are surely low-hanging fruit if TI is disabled?

I think in many places (especially native functions) we allocate the same type objects with TI disabled as enabled.  Bug 670185 will fix this so that we don't allocate those objects with TI either enabled or disabled.  (Not so interested in fixes that only affect TI-disabled, as the TI-disabled memory is <= enabled and TI enabled needs to get to an acceptable level).

Also, the type-inference-pools data is the data cleared on every GC, so is super volatile --- depending on when you measure you can get 0 bytes or 19MB (as in the GMail test).  After 670185, the next stage is to change things to wipe out the great majority of data on every GC.  To that end, when measuring can you first wait a minute for a GC to kick in (or just hit the GC button on about:memory)?  This will also make things more of an apples-to-apples comparison, as GC timing differs greatly across runs (e.g. much of the difference in comment 15 is likely due to GC timing, v8bench does a ton of allocation).
Assignee: general → bhackett1024
Some new numbers, with the refactorings from bug 670185 and bug 669969 in.  These are all with TI enabled.

Load GMail, look at some messages:

│  ├───43,337,309 B (22.15%) -- compartment(https://mail.google.com/mail/?ui=2&shva=1#inbox)
│  │   ├──17,298,060 B (08.84%) -- type-inference-pools
│  │   ├──11,008,640 B (05.63%) -- gc-heap
│  │   │  ├───6,091,512 B (03.11%) -- objects
│  │   │  ├───4,116,760 B (02.10%) -- shapes
│  │   │  ├─────593,184 B (00.30%) -- strings
│  │   │  ├─────120,016 B (00.06%) -- arena-unused
│  │   │  ├──────43,840 B (00.02%) -- arena-headers
│  │   │  ├──────43,328 B (00.02%) -- arena-padding
│  │   ├───5,164,333 B (02.64%) -- scripts
│  │   ├───4,603,904 B (02.35%) -- mjit-code
│  │   ├───1,729,800 B (00.88%) -- object-slots
│  │   ├───1,613,864 B (00.82%) -- type-inference
│  │   │   ├────964,368 B (00.49%) -- script-main
│  │   │   ├────536,792 B (00.27%) -- object-main
│  │   │   ├─────90,144 B (00.05%) -- script-typesets
│  │   │   └─────22,560 B (00.01%) -- object-typesets
│  │   ├───1,060,688 B (00.54%) -- mjit-data

After a GC:

│   ├──22,127,887 B (11.90%) -- compartment(https://mail.google.com/mail/?ui=2&shva=1#inbox)
│   │  ├──11,809,640 B (06.35%) -- gc-heap
│   │  │  ├───5,679,440 B (03.05%) -- objects
│   │  │  ├───3,678,400 B (01.98%) -- shapes
│   │  │  ├───2,194,376 B (01.18%) -- arena-unused
│   │  │  ├─────161,104 B (00.09%) -- strings
│   │  │  ├──────49,680 B (00.03%) -- arena-padding
│   │  │  ├──────46,640 B (00.03%) -- arena-headers
│   │  ├───5,152,815 B (02.77%) -- scripts
│   │  ├───1,805,288 B (00.97%) -- object-slots
│   │  ├───1,551,936 B (00.83%) -- type-inference
│   │  │   ├──1,007,232 B (00.54%) -- script-main
│   │  │   ├────436,128 B (00.23%) -- object-main
│   │  │   ├─────86,336 B (00.05%) -- script-typesets
│   │  │   └─────22,240 B (00.01%) -- object-typesets
│   │  ├───1,310,720 B (00.70%) -- mjit-code
│   │  ├─────497,472 B (00.27%) -- string-chars
│   │  ├──────────16 B (00.00%) -- type-inference-pools

Main things:

- object-main/object-typesets shrank a lot vs. the rest of TI data and gc-heap.  It will be hard to shrink these further without compromising the precision of the analysis, though there are some areas we may be overly precise already to no particular purpose (unnecessarily distinguishing different object/array initializers, for example).

- script-main/script-typesets are now most of the TI-specific data being hung onto.  This data needs an end-of-life, but it is quite valuable for avoiding recompilation so I'd rather avoid purging it on every GC.  How often to purge may depend more on how much time it costs to sweep the type sets (they only hold weak references).  Are there docs on how to add new GC timer data and construct those cool timing graphs?

- While investigating the above will also look into reducing the increase in script size.

- mjit-data is zero after the GC, so everything in mjit-code is actually for regexps.

- the increase in the number of shapes is still there, I need to look more at where the increase is coming from and how-to/whether-it-can be driven down.

Not done, but I hope this looks like progress.
Depends on: 674609
Depends on: 674621
Depends on: 678029
Depends on: 678044
Depends on: 679329
bhackett has reduced type inference's memory usage drastically, see bug 678044 comment 13.  Based on that, I'm happy to close this bug.
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.