Updates:
Status: WorkingAsIntended
Cc: [email protected]
Comment #8 on issue 2473 by [email protected]:
http://www.chaostoperfection.com/ crashes in V8 initialization on 64-bit
platforms
http://code.google.com/p/v8/issues/detail?id=2473
First of all let me explain why we do this two-step allocation on x64: To
keep the generated code size small, we use 32bit relative addressing in our
JITed code, avoiding 64bit addresses as much as possible. To make this
work, we need a way to guarantee that all our future memory allocations for
blocks where we keep the JITed code will be in a 4GB range. Therefore we
reserve a chunk (512MB) at Isolate initialization time, but do not commit
it yet. Later when we need space for code, we will commit sub-chunks of
that large chunk, being sure that our relative addressing will "fit". There
is not much we can do about this, because using 64bit addressing modes all
over the place is out of the question for space/performance reasons. Note
that we can't bump up the initial reservation size (512MB) during runtime
somehow, so every Isolate, including the main thread, is limited forever
with that maximum code size. So lowering the 512MB is no option, either.
Regarding the idea that 512MB is too much for web workers: This reminds me
of "640kB ought to be enough for anybody." and "JavaScript is only for
mouseover effects." :-) Seriously. I don't think that introducing
a "2nd-class Isolate" is a good idea, because we don't know how people will
really use web workers. And more technically, v8 doesn't even know when
initializing an Isolate if it's going to be used for the main thread or for
a web worker. Currently an Isolate (and even the rest of v8 if it's the
first Isolate) gets implcitly initialized via a v8::Integer::New(int32_t)
call from WebKit! :-P This is a totally different story though, and we have
already plans for Q1 to make v8's API much more explicit about Isolates and
initialization in general.
To summarize: Things on x64 are basically broken since r163410
(2012-10-22), where an artificial address space limit of 8GB was introduced
via the sandbox, and it has gotten much worse since r171546 (2012-12-06)
where this was even lowered to 4GB. The really funny part is a comment in
the CL for the last change: "Limiting the address space is a bit more risky
because in theory a memory allocator could map a huge chunk of memory as
then use it as needed, relying on Linux' on-demand paging. I didn't see
this happen so far, except with ASAN (which as you can see is excluded)."
Famous last words. :-) IMHO artificially limiting the address space via
setrlimit is a bad idea on x64. The problem is really that this naive
approach can't distinguish between reserved and committed memory, and this
is the root cause of all this evil.
So what can be done? My preferred solutions (in descending order):
a) Find a way to distinguish between reserved and committed memory in
the sandbox.
b) Totally nuke LimitAddressSpace and happily use many web workers.
c) Keep LimitAddressSpace and live with the (IMHO severe) restriction of
allowing only a small handful of web workers.
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev