Closed
Bug 902506
Opened 11 years ago
Closed 11 years ago
OdinMonkey: make "use asm" compatible with off-thread compilation
Categories
(Core :: JavaScript Engine, defect)
Core
JavaScript Engine
Tracking
()
RESOLVED
FIXED
mozilla26
People
(Reporter: luke, Assigned: luke)
References
(Blocks 1 open bug)
Details
(Whiteboard: [games])
Attachments
(5 files, 3 obsolete files)
(deleted),
patch
|
sstangl
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
n.nethercote
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
bhackett1024
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
terrence
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
mjrosenb
:
review+
|
Details | Diff | Splinter Review |
Bug 897655 will use off-thread compilation for startup code. The next step is to use off-thread compilation for <script> tags. However, "use asm" currently fails:
js> offThreadCompileScript("function f() { 'use asm' }")
js> Assertion failure: isJSContext(), at ../jscntxt.h:177
because CompileAsmJS currently must be run on the JSRuntime's main thread. From a quick look at AsmJS.cpp, this is a pretty simple task, esp. once bug 902095 gives ExclusiveContext a compartment().
Assignee | ||
Comment 1•11 years ago
|
||
Following patches apply on top of the two in bug 864220 and 902096.
Assignee | ||
Comment 2•11 years ago
|
||
This patch hoists cx->options from JSContext to ExclusiveContext so that options may be accessed during off-thread compilation. In the off-thread case, this works by having ExclusiveContext takes a snapshot of the options in the JSContext when the ExclusiveContext is created.
Attachment #788200 -
Flags: review?(bhackett1024)
Assignee | ||
Comment 3•11 years ago
|
||
This patch cuts all dependency of Odin compilation on IonCompartment/IonRuntime/ExecutableAllocator by simply mmap'ing/VirtualAlloc'ing the memory itself. Normally I'd like to avoid duplicating OS-specific calls but these calls are very simple and overall the code is simpler (e.g., we can now rely on page-alignment). The next patch will remove JSC::ASMJS_CODE and deal with about:memory reporting.
Attachment #788204 -
Flags: review?(sstangl)
Assignee | ||
Comment 4•11 years ago
|
||
The last patch stopped using ExecutableAllocator which means that asm.js code isn't reported. This code adds it back but improves things: asm.js code is now reported per-compartment along with the size of the AsmJSModule itself (which can be large due to exits and heap-access bookkeeping). Lastly, the patch makes a proper JSObject subclass for AsmJSModuleObject so that is<>/as<> work.
Attachment #788207 -
Flags: review?(n.nethercote)
Assignee | ||
Comment 5•11 years ago
|
||
RelocatablePtr asserts it is only used on the main thread and AsmJSModule (which contains several) is now build off the main thread. Ultimately, the PropertyName* fields are pretty simple (initialized, read-only) so I think I can just use MarkStringUnbarriered on them and store raw PropertyName*. Is that right terrence or am I forgetting a barrier?
Attachment #788210 -
Flags: review?(terrence)
Assignee | ||
Comment 6•11 years ago
|
||
This final patch makes all of AsmJS.cpp use an ExclusiveContext, which is pretty simple. With this, I can compile all the asm.js unit tests with offThreadCompileScript(). There is one unrelated assert that fires (in AutoLockForExclusiveAccess) involving numExclusiveThreads, but I'm pretty sure this is fixed by bug 897655 (since numExclusiveThreads isn't incremented anywhere on trunk, but is by bug 897655).
Attachment #788213 -
Flags: review?(bhackett1024)
Assignee | ||
Comment 7•11 years ago
|
||
This version asserts that the given string is tenured and thus no writeBarrierPost is needed on initialization.
Attachment #788210 -
Attachment is obsolete: true
Attachment #788210 -
Flags: review?(terrence)
Attachment #788264 -
Flags: review?(terrence)
Comment 8•11 years ago
|
||
Comment on attachment 788264 [details] [diff] [review]
no-relocatable
Review of attachment 788264 [details] [diff] [review]:
-----------------------------------------------------------------
Nice! r=me
Attachment #788264 -
Flags: review?(terrence) → review+
Comment 9•11 years ago
|
||
Comment on attachment 788207 [details] [diff] [review]
fix/enhance asm.js memory reporting
Review of attachment 788207 [details] [diff] [review]:
-----------------------------------------------------------------
Looks good! Just a couple of nits.
::: js/src/jit/AsmJSModule.cpp
@@ +94,5 @@
> js_delete(functionCounts(i));
> }
> +
> +void
> +AsmJSModule::sizeOfMisc(mozilla::MallocSizeOf mallocSizeOf, JS::ObjectsExtraSizes *sizes)
I'm ambivalent about passing in ObjectsExtraSizes here, when you only modify two fields. You could instead have two outparams, one for code and one for data -- that would be less concise, but expose less data unnecessarily. I'll let you decide whether to change.
@@ +96,5 @@
> +
> +void
> +AsmJSModule::sizeOfMisc(mozilla::MallocSizeOf mallocSizeOf, JS::ObjectsExtraSizes *sizes)
> +{
> + sizes->asmJSModuleData = sizeof(AsmJSModule) +
First, this method should be in AsmJSModuleObject. See PropertyIteratorObject and RegExpStaticsObject for comparison.
Second, we avoid sizeof(T) in memory reporters for things allocated on the heap, because (a) it doesn't measure slop bytes, and (b) it doesn't let DMD know that we've measured the heap block. Use |mallocSizeOf(module())| instead.
::: js/src/jsobj.cpp
@@ +5625,5 @@
> sizes->regExpStatics = as<RegExpStaticsObject>().sizeOfData(mallocSizeOf);
> } else if (is<PropertyIteratorObject>()) {
> sizes->propertyIteratorData = as<PropertyIteratorObject>().sizeOfMisc(mallocSizeOf);
> + } else if (is<AsmJSModuleObject>()) {
> + as<AsmJSModuleObject>().module().sizeOfMisc(mallocSizeOf, sizes);
Once you've moved sizeOfMisc() into AsmJSModuleObject, you won't need the module() call here and this case will look just like the three above it.
::: js/xpconnect/src/XPCJSRuntime.cpp
@@ +1989,5 @@
> + "Memory used by AOT-compiled asm.js code.");
> +
> + ZCREPORT_BYTES(cJSPathPrefix + NS_LITERAL_CSTRING("objects/malloc-heap/asm.js-module-data"),
> + cStats.objectsExtra.asmJSModuleData,
> + "Memory allocated for an asm.js module not including executable code.");
Change "not including executable code" to just "data"?
Attachment #788207 -
Flags: review?(n.nethercote) → review+
Comment 10•11 years ago
|
||
I forgot to say: reporting the additional data is great, as is the creation of AsmJSModuleObject so that is<> and as<> can be used. Thanks!
Assignee | ||
Comment 11•11 years ago
|
||
(In reply to Nicholas Nethercote [:njn] from comment #9)
Thanks!
> You could instead have two outparams, one for code and one for
> data -- that would be less concise, but expose less data unnecessarily.
> I'll let you decide whether to change.
I had the same internal debate. Since it bugged you too, I'll go with the two-outparam form.
Comment 12•11 years ago
|
||
Comment on attachment 788200 [details] [diff] [review]
hoist cx->options from JSContext to ExclusiveContext
Review of attachment 788200 [details] [diff] [review]:
-----------------------------------------------------------------
Which options do you need from the cx to compile asm.js code? Just JSOPTION_ASMJS? I'm worried about this patch as it seems to make cx->options even less meaningful than before as it doesn't really even reflect the current state of things. Ideally these options should just be bits set on the runtime (or better yet, not exist at all) but they couldn't be read from off thread without racing.
CompileOptions already has an asmJSOption member which is propagated from its initial JSContext, and these options are around when parsing off thread. Could those options be passed in to CompileAsmJS?
Attachment #788200 -
Flags: review?(bhackett1024)
Comment 13•11 years ago
|
||
Comment on attachment 788213 [details] [diff] [review]
make CompileAsmJS take an ExclusiveContext
Review of attachment 788213 [details] [diff] [review]:
-----------------------------------------------------------------
::: js/src/jit/AsmJS.cpp
@@ +4817,5 @@
> + // If 'cx' isn't a JSContext, then we are already off the main thread so
> + // off-thread compilation must be enabled.
> + if (!cx->isJSContext())
> + return true;
> + return OffThreadCompilationEnabled(cx->asJSContext());
I think this method should also check the number of available threads. If there is only one worker thread then any jobs it triggers won't get done until the original parse finishes, and CheckFunctionsParallelImpl will iiuc block forever.
::: js/src/jsworkers.cpp
@@ +34,5 @@
> + // If 'cx' is not a JSContext, we are already off the main thread and the
> + // worker threads would have already been initialized.
> + if (!cx->isJSContext()) {
> + JS_ASSERT(cx->workerThreadState() != NULL);
> + return false;
return true
Attachment #788213 -
Flags: review?(bhackett1024) → review+
Assignee | ||
Comment 14•11 years ago
|
||
Comment on attachment 788200 [details] [diff] [review]
hoist cx->options from JSContext to ExclusiveContext
(In reply to Brian Hackett (:bhackett) from comment #12)
> CompileOptions already has an asmJSOption member which is propagated from
> its initial JSContext, and these options are around when parsing off thread.
> Could those options be passed in to CompileAsmJS?
Hah, I hadn't noticed you had added that. Yes, that that would work perfectly; indeed JSOPTION_ASMJS is all I need and I have the Parser object.
Attachment #788200 -
Attachment is obsolete: true
Assignee | ||
Comment 15•11 years ago
|
||
(In reply to Brian Hackett (:bhackett) from comment #13)
> I think this method should also check the number of available threads. If
> there is only one worker thread then any jobs it triggers won't get done
> until the original parse finishes, and CheckFunctionsParallelImpl will iiuc
> block forever.
Good point. IIRC, there can be only one off-main-thread parsing task? If so, then it seems like heperThreadCount() >= 2 would be sufficient. If we ever wanted to be able to use N threads for parsing (which seems reasonable if we can avoid the atoms lock by not creating real atoms-compartment att=oms as you suggested (which I think could help general parsing perf if we LifoAlloc'd them instead of using real GC allocation), though, we'd have to do something more (maintain some "numActiveParseTasks" and compare that against helperThreadCount). Do you think it makes sense to do the more general guard now?
Comment 16•11 years ago
|
||
(In reply to Luke Wagner [:luke] from comment #15)
> (In reply to Brian Hackett (:bhackett) from comment #13)
> > I think this method should also check the number of available threads. If
> > there is only one worker thread then any jobs it triggers won't get done
> > until the original parse finishes, and CheckFunctionsParallelImpl will iiuc
> > block forever.
>
> Good point. IIRC, there can be only one off-main-thread parsing task? If
> so, then it seems like heperThreadCount() >= 2 would be sufficient. If we
> ever wanted to be able to use N threads for parsing (which seems reasonable
> if we can avoid the atoms lock by not creating real atoms-compartment
> att=oms as you suggested (which I think could help general parsing perf if
> we LifoAlloc'd them instead of using real GC allocation), though, we'd have
> to do something more (maintain some "numActiveParseTasks" and compare that
> against helperThreadCount). Do you think it makes sense to do the more
> general guard now?
I don't think the general guard is necessary right now, though I'll make sure to add a note in WorkerThreadState::canStartParseTask when landing bug 897655 this week so we don't end up with bad behavior should this be relaxed.
Assignee | ||
Comment 17•11 years ago
|
||
Landing RelocatablePtr patch ahead of time to help another bug:
https://hg.mozilla.org/integration/mozilla-inbound/rev/91babde1804d
Whiteboard: [leave open]
Comment 18•11 years ago
|
||
Flags: in-testsuite-
Updated•11 years ago
|
Attachment #788204 -
Flags: review?(sstangl) → review+
Assignee | ||
Comment 19•11 years ago
|
||
What bug 900669 comment 8 said.
Attachment #791101 -
Flags: review?(mrosenberg)
Assignee | ||
Comment 20•11 years ago
|
||
Oops, forgot to remove AutoFlushCache from ModuleCompiler.
Attachment #791101 -
Attachment is obsolete: true
Attachment #791101 -
Flags: review?(mrosenberg)
Attachment #791105 -
Flags: review?(mrosenberg)
Updated•11 years ago
|
Attachment #791105 -
Flags: review?(mrosenberg) → review+
Assignee | ||
Comment 21•11 years ago
|
||
Comment 22•11 years ago
|
||
Assignee | ||
Updated•11 years ago
|
Status: ASSIGNED → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Whiteboard: [leave open]
Assignee | ||
Updated•11 years ago
|
Whiteboard: [games]
Updated•11 years ago
|
Target Milestone: --- → mozilla26
Updated•11 years ago
|
Blocks: gecko-games
You need to log in
before you can comment on or make changes to this bug.
Description
•