WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
UNCONFIRMED
65768
On Windows MarkedBlock is using only 25% allocated of ram allocated for it causing JavaScriptCore to crash under moderate actual ram use.
https://bugs.webkit.org/show_bug.cgi?id=65768
Summary
On Windows MarkedBlock is using only 25% allocated of ram allocated for it ca...
michaelbraithwaite
Reported
2011-08-05 06:35:15 PDT
This is with JSC from
http://trac.webkit.org/browser/releases/WebKitGTK/webkit-1.4.2
. We are using JSC in to run complex 3D titles in a custom plugin. Some development builds of these allocate millions of objects which along with other assets can cause total memory use to grow >1GB. In some case JSC crashes due to VirtualAlloc() failing despite >1GB theoretically remaining free. In the extreme it crashes with only 650Mb in use. Using VMMap
http://technet.microsoft.com/en-us/sysinternals/dd535533.aspx
shows large amounts of ram as ‘unusable’, e.g. 600MB. Scanning through ram you see a repeated pattern of 16k used followed by 48k unused ram, which turn out to be the MarkedBlock allocations. Basically this is because VirtualAlloc() is allocating in SYSTEM_INFO.dwAllocationGranularity (64k) blocks for any allocation but the code seems to be written assuming allocations are SYSTEM_INFO.dwPageSize (4k). Since MarkedBlock calls PageAllocationAligned::allocate() with 16k and 64k is actually allocate it wastes 48k. Some possible fixes:- a) Make MarkedBlock::blockSize 64k instead of 16k for Windows. b) Update alignment in PageAllocationAligned::allocate(). For size & alignment <= SYSTEM_INFO.dwAllocationGranularity it doesn't need anything adding. Doing a & b removed ~95% of the unused space and stops the crashes we were seeing. To verify this is the case a trivial loop allocating the remaining ram with VirtualAlloc() showed ~200Mb before these changes and >1GB after. c) Change some uses of pageSize() to use system_info.dwAllocationGranularity. Its not clear to me which should be but using pageSize and which AllocationGranularity but forcing it to AllocationGranularity further lowers unused space down ~5% to 10Mb. There are other uses eg ExecutablePool and TryVirtualAlloc that looks like they have the same issue. Basically search for VirtualAlloc and put conditional break points on <64k. I tested this on Win7 64bit, Vista 64bit and XP 32bit.
Attachments
Add attachment
proposed patch, testcase, etc.
Radar WebKit Bug Importer
Comment 1
2011-08-05 12:30:45 PDT
<
rdar://problem/9905810
>
Oliver Hunt
Comment 2
2011-08-05 12:44:40 PDT
Filip can you have a look at this? Would be good to see if it's a windows specific issue, or if it's a general 32bit bug. For reference this is a gtk branch of jsc at
r90183
Oliver Hunt
Comment 3
2011-08-05 12:45:28 PDT
(In reply to
comment #0
)
> This is with JSC from
http://trac.webkit.org/browser/releases/WebKitGTK/webkit-1.4.2
. > > We are using JSC in to run complex 3D titles in a custom plugin. Some development builds of these allocate millions of objects which along with other assets can cause total memory use to grow >1GB. In some case JSC crashes due to VirtualAlloc() failing despite >1GB theoretically remaining free. In the extreme it crashes with only 650Mb in use. > > Using VMMap
http://technet.microsoft.com/en-us/sysinternals/dd535533.aspx
shows large amounts of ram as ‘unusable’, e.g. 600MB. Scanning through ram you see a repeated pattern of 16k used followed by 48k unused ram, which turn out to be the MarkedBlock allocations. > > Basically this is because VirtualAlloc() is allocating in SYSTEM_INFO.dwAllocationGranularity (64k) blocks for any allocation but the code seems to be written assuming allocations are SYSTEM_INFO.dwPageSize (4k). Since MarkedBlock calls PageAllocationAligned::allocate() with 16k and 64k is actually allocate it wastes 48k. > > Some possible fixes:- > > a) Make MarkedBlock::blockSize 64k instead of 16k for Windows. > > b) Update alignment in PageAllocationAligned::allocate(). For size & alignment <= SYSTEM_INFO.dwAllocationGranularity it doesn't need anything adding. > > Doing a & b removed ~95% of the unused space and stops the crashes we were seeing. To verify this is the case a trivial loop allocating the remaining ram with VirtualAlloc() showed ~200Mb before these changes and >1GB after. > > c) Change some uses of pageSize() to use system_info.dwAllocationGranularity. Its not clear to me which should be but using pageSize and which AllocationGranularity but forcing it to AllocationGranularity further lowers unused space down ~5% to 10Mb. > > There are other uses eg ExecutablePool and TryVirtualAlloc that looks like they have the same issue. Basically search for VirtualAlloc and put conditional break points on <64k. > > I tested this on Win7 64bit, Vista 64bit and XP 32bit.
Could you try reproducing this on tip of tree JSC? Assuming you're only using the JSC API you shouldn't see any difference in behaviour.
Filip Pizlo
Comment 4
2011-08-05 13:01:22 PDT
(In reply to
comment #2
)
> Filip can you have a look at this? Would be good to see if it's a windows specific issue, or if it's a general 32bit bug. > > For reference this is a gtk branch of jsc at
r90183
Ack. Looking into it.
michaelbraithwaite
Comment 5
2011-08-08 02:11:14 PDT
If you run the below on Safari 5.1 and attach vmmap to the WebKit2WebProcess.exe you see the same issue. In this case ~880Mb unusable. It think in actuality its worst than that as there is the unneeded 12k padding in PageAllocationAligned::allocate(). <html> <head> <title>Test</title> </head> <body> <center> <h2>Test</h2> </center> <script> var array = []; var create = function createFn() { var size = 32*1024*1024; for(var x = 0; x < size; x += 1) { array[x] = {a:"test"}; } }; window.onload = create; </script> </body> </html>
Alp Toker
Comment 6
2012-03-02 11:53:21 PST
Update: MarkedBlock::blockSize is 64KB on all platforms since
r105442
There are still several 4k page assumptions around elsewhere.
michaelbraithwaite
Comment 7
2012-06-12 10:06:25 PDT
(In reply to
comment #6
)
> Update: MarkedBlock::blockSize is 64KB on all platforms since
r105442
> > There are still several 4k page assumptions around elsewhere.
Well we pulled
http://trac.webkit.org/browser/releases/WebKitGTK/webkit-1.9.2
and debugged through. Its a slightly patched version for misc crash issues I bugged and to get it to build with vs2008 but I don't think those effect this. Some good news and some not so good looking. As you say it now asks to allocate 64k aligned to 64k. This has improved things markedly, but there looks to still be a major issue that means these allocation are effectively using 50% of the space they reserved (not committed), i.e. your cutting down on max size of the usable address space markedly (less than 50% in reality as other allocation are occurring). The issue come from PageAllocationAligned::allocate() (as mentioned originally). To walk you through PageAllocationAligned::allocate():- size_t alignmentDelta = alignment - pageSize(); // 64k - 4k = 60k size_t reservationSize = size + alignmentDelta; // 64k + 60k = 124k void* reservationBase = OSAllocator::reserveUncommitted(124k, usage, writable, executable); //reserve 128k in reality alignedBase = reservationBase ..; // no alignment of 64k blocks so just reservationBase OSAllocator::commit(alignedBase, 64k, writable, executable); //commit the first 64k So basically its reserving 128k for each 64k block you commit but don't free the other 64k reserved space, until the block is freed. You can see this with vmap as numerous 124k blocks with 64k committed. If you replace pageSize() with the actual 64k (SYSTEM_INFO.dwAllocationGranularity) then this seems to fix it, i.e. size_t allcoationSize = 0x10000; size_t alignmentDelta = alignment < allcoationSize ? 0 : alignment - allcoationSize;
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug