Closed Bug 445420 Opened 16 years ago Closed 15 years ago

TT_NEW_STRING code uses more memory than old string code

Categories

(Tamarin Graveyard :: Tracing Virtual Machine, defect)

defect
Not set
normal

Tracking

(Not tracked)

VERIFIED WONTFIX

People

(Reporter: rob.borcic, Unassigned)

References

Details

Attachments

(1 file)

I have marked this bug as applying to all platforms, but I have only measured the results on Symbian.

Running the same test with the same code, but turning TT_NEW_STRINGS on or off results in a large difference in the memory high water mark.

With the old code, the acceptance test case ecma3/Unicode/u3400_CJKUnifiedIdeographsExtensionA.abc
reaches a memory high water mark of 8.9MB. With the new string code, the same test reaches 12.1MB.

Similar behavior was observed with the following ecma3/Unicode test cases
u5000_CJKUnifiedIdeographs.abc
u6000_CJKUnifiedIdeographs.abc
u7000_CJKUnifiedIdeographs.abc
u8000_CJKUnifiedIdeographs.abc
u9000_CJKUnifiedIdeographs.abc
uAC00_HangulSyllables.abc
uE000_PrivateUseArea.abc

This issue was previously discussed in bug #443346 - https://bugzilla.mozilla.org/show_bug.cgi?id=443436
This is a quick and dirty hack to calculate the memory high water mark. This should not be pushed, but is offered as a reference.
Using the high water measurement hack I just created for Windows, I see the same high water mark with TT_NEW_STRINGS on and off; however, it is much higher than Symbian: 18.375MB.
Status: NEW → ASSIGNED
My previous Windows measurements were with a debug build. Using a release build I'm seeing:

* new strings code, JIT: 17.875MB (4576 pages)
* old strings code, JIT: 17.625MB (4512 pages)
* new strings code, interp: 1.875MB (480 pages)
* old strings code, interp: 1.875MB (480 pages)

So, no difference in interp mode and only a 1.4% increase with the new strings code vs. the old code with the JIT on. It would be interesting to see if my Symbian observation can be reproduced on other platforms or if it's an anomaly.

It turns out that the major cause of the discrepancy was due to how infrequently garbage collection was occurring on Symbian. GC::AllocBlock() and GC::AllocBlockIncremental() will only allow a GC if the value returned by GC::GetPerformanceCounter() is at least kMarkSweepBurstTicks larger than the value set during the last call to GC::Sweep(). 

kMarkSweepBurstTicks = 1515909

On Windows, GC::GetPerformanceCounter() calls QueryPerformanceCounter(), which means that the time value of kMarkSweepBurstTicks varies depending on CPU speed, but should be in the 200ms ballpark on a 2GHz machine (or so the comment leads us to believe).

Most platforms other than Windows are returning the time in microseconds, leaving to the time value of kMarkSweepBurstTicks equating to ~1516ms. There was a bug in the Symbian implementation, so it was returning a time in milliseconds, so a GC would only happen every 1516 seconds -- effectively never.

Increasing the GC interval to a similarly large time on Windows brings the memory usage up to the same ballpark as my earlier Symbian findings, but does not exhibit the difference in memory usage between the old and new string code that I had seen on Symbian. Changing the Symbian GC interval to 200ms results in identical memory usage as on Windows.

 

Nice, sluething!   We should change this code that the kMarkSweepBurst constant is expressed in millis and then millis are converted to ticks using the system's impl of GetPerformanceFrequency.  
Status: ASSIGNED → RESOLVED
Closed: 15 years ago
Resolution: --- → WONTFIX
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: