Consider using reserved slots for JSFunction data
Categories
(Core :: JavaScript Engine, task, P3)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox93 | --- | fixed |
People
(Reporter: jonco, Assigned: jonco)
References
Details
Attachments
(15 files)
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review |
JSFunction is one of a few JSObject classes that uses its own custom data layout:
https://searchfox.org/mozilla-central/source/js/src/vm/JSFunction.h#43-131
This adds complexity to object allocation and in the GC (and probably other places too). It would be great if this could store its data in reserved slots instead.
Updated•4 years ago
|
| Assignee | ||
Comment 1•4 years ago
|
||
There's no reason for these to be private when they all have operator=
implemented in terms of set() anyway.
Updated•4 years ago
|
| Assignee | ||
Comment 2•4 years ago
|
||
This is useful later on so we can update a function's flags with a single
expression rather than reading, updating and setting the flags separately.
Depends on D123080
| Assignee | ||
Comment 3•4 years ago
|
||
In preparation for storing this in a slot, this stores the two values together
in the same field.
Depends on D123081
| Assignee | ||
Comment 4•4 years ago
|
||
In preparation for storing them in a slot, store them in a Value. The value is
encoded as a private uint32 value.
Depends on D123082
| Assignee | ||
Comment 5•4 years ago
|
||
In preparation for storing this in a slot, store it as a Value.
The native function is stored as a private value. This requires casting it to
void* which AFAIU only conditionally supported in the C++ spec but in practice
supported everwhere. We used to do this in other places, although we have
removed them now.
Depends on D123083
| Assignee | ||
Comment 6•4 years ago
|
||
In preparation for storing this in a slot, store it as a JS::Value.
All values including JSScript pointers are stored as private values becuase the
JIT assumes it can access SelfHostedLazyScript pointers and JSScript pointers
in the same way. This means we will still need a trace hook when we store this
data in slots.
Depends on D123084
| Assignee | ||
Comment 7•4 years ago
|
||
Depends on D123085
| Assignee | ||
Comment 8•4 years ago
|
||
We will need to change this later as extended functions will have a different
class, so factor out the check.
Depends on D123086
| Assignee | ||
Comment 9•4 years ago
|
||
GetClonedSelfHostedFunctionNameOffMainThread doesn't seem to be used any more,
so the JSFunction methods it used can go too.
Depends on D123087
| Assignee | ||
Comment 10•4 years ago
|
||
Depends on D123088
| Assignee | ||
Comment 11•4 years ago
|
||
Move class fields to fixed slots. I was originally going to remove the function
alloc kinds but they are used to iterate all functions for relazification.
Another complication is that the JIT assumes that the prototype property for
function constructors is always stored in the first dynamic slot, which
requires extended functions have a special size class with six fixed slots.
Depends on D123089
| Assignee | ||
Comment 12•4 years ago
|
||
Depends on D123094
Comment 13•4 years ago
|
||
Still going through this, but do you know what the effect is on for instance "Base Content JS" (the SY(ab) task on Treeherder)?
Comment 14•4 years ago
|
||
(In reply to Jan de Mooij [:jandem] from comment #13)
Still going through this, but do you know what the effect is on for instance "Base Content JS" (the
SY(ab)task on Treeherder)?
Whoops only 32-bit, of course. That's probably acceptable.
| Assignee | ||
Comment 15•4 years ago
|
||
Functions can now have one of two classes so it's best if JSFunction::class_
doesn't exist or people may use that without thinking.
Depends on D123089
| Assignee | ||
Comment 16•4 years ago
|
||
(In reply to Jan de Mooij [:jandem] from comment #14)
I ran the awsy tests and the results don't show any conclusive regressions although Base Content JS for 32 bit Windows shows a 3.88% regression at low confidence.
Comment 17•4 years ago
|
||
Comment 18•4 years ago
|
||
Backed out for causing dt failures
Backout link: https://hg.mozilla.org/integration/autoland/rev/2b096591d6ff69e4d012214bb4f446ec2c744618
Comment 19•4 years ago
|
||
Backed out 13 changesets (Bug 1724031) for causing dt failures in js/src/gc/Cell.h
Backout link: https://hg.mozilla.org/integration/autoland/rev/f31a22da96294e7f31af4bf9a5a88c68a55c3705
Push with failures, failure log
Comment 20•4 years ago
|
||
there is also a spider monkey tsan build bustage: failure log
| Assignee | ||
Comment 21•4 years ago
|
||
Changing functions to use fixed slots creates a problem when the profiler
tries to get the script for on-stack functions. Unfortunately this can happen
during minor GC after the functions have been moved but before the profiler
data pointing to them has been updated.
The function data itself is mostly intact, but the object header (used for the
shape) is not valid. As far as I can see this only affects the debug assertions
around checking that slot numbers are valid. However the simplest fix is to
suppress the profiler during the intial part of minor GC, until the roots have
been traced (which will update the profiler data).
The patch moves the code to trace the roots in a minor GC to a separate method
and adds a guard to suppress the profiler.œ
What do you think? Alternatively we would have to add a load of 'unchecked'
methods to a buch of accessors on JSFunction, and to NativeObject to get fixed
slots without touching the shape.
Depends on D123094
Updated•4 years ago
|
Comment 22•4 years ago
|
||
| Assignee | ||
Comment 23•4 years ago
|
||
This fixes an intermittent TSAN failure due to accessing JSFunction off main thread.
Comment 24•4 years ago
|
||
Comment 25•4 years ago
|
||
Backed out for assertion failures on JSFunction.h
-
backout: https://hg.mozilla.org/integration/autoland/rev/b8ca722688efb25869d07833de94b74d35407818
-
push where tier 1 failures have occurred: https://treeherder.mozilla.org/jobs?repo=autoland&group_state=expanded&revision=10c2109adc3fc965c26c519b875ec5e73064b77c&searchStr=mochitest-chrome
-
failure log: https://treeherder.mozilla.org/logviewer?job_id=349667765&repo=autoland&lineNumber=14731
[task 2021-08-26T16:37:42.403Z] 16:37:42 INFO - GECKO(6400) | Assertion failure: getFixedSlot(AtomSlot).isUndefined(), at /builds/worker/checkouts/gecko/js/src/vm/JSFunction.h:338
[task 2021-08-26T16:37:42.415Z] 16:37:42 INFO - Initializing stack-fixing for the first stack frame, this may take a while...
[task 2021-08-26T16:37:48.091Z] 16:37:48 INFO - GECKO(6400) | #01: JSFunction::initAtom(JSAtom*) [js/src/vm/JSFunction.h:338]
[task 2021-08-26T16:37:48.092Z] 16:37:48 INFO - GECKO(6400) | #02: js::GlobalObject::getSelfHostedFunction(JSContext*, JS::Handle<js::GlobalObject*>, JS::Handle<js::PropertyName*>, JS::Handle<JSAtom*>, unsigned int, JS::MutableHandle<JS::Value>) [js/src/vm/GlobalObject.cpp:1003]
[task 2021-08-26T16:37:48.092Z] 16:37:48 INFO - GECKO(6400) | #03: JS::NewFunctionFromSpec(JSContext*, JSFunctionSpec const*, JS::Handle<JS::PropertyKey>) [js/src/jsapi.cpp:2220]
[task 2021-08-26T16:37:48.093Z] 16:37:48 INFO - GECKO(6400) | #04: js::DefineFunctions(JSContext*, JS::Handle<JSObject*>, JSFunctionSpec const*, js::DefineAsIntrinsic) [js/src/vm/JSObject.cpp:2535]
[task 2021-08-26T16:37:48.094Z] 16:37:48 INFO - GECKO(6400) | #05: JS_DefineFunctions(JSContext*, JS::Handle<JSObject*>, JSFunctionSpec const*) [js/src/vm/PropertyAndElement.cpp:951]
[task 2021-08-26T16:37:48.095Z] 16:37:48 INFO - GECKO(6400) | #06: js::GlobalObject::resolveConstructor(JSContext*, JS::Handle<js::GlobalObject*>, JSProtoKey, js::GlobalObject::IfClassIsDisabled) [js/src/vm/GlobalObject.cpp:351]
[task 2021-08-26T16:37:48.095Z] 16:37:48 INFO - GECKO(6400) | #07: JS_ResolveStandardClass(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::PropertyKey>, bool*) [js/src/jsapi.cpp:948]
[task 2021-08-26T16:37:48.096Z] 16:37:48 INFO - GECKO(6400) | #08: js::LookupProperty(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::PropertyKey>, JS::MutableHandle<JSObject*>, js::PropertyResult*) [js/src/vm/JSObject.cpp:1857]
[task 2021-08-26T16:37:48.096Z] 16:37:48 INFO - GECKO(6400) | #09: js::LookupName(JSContext*, JS::Handle<js::PropertyName*>, JS::Handle<JSObject*>, JS::MutableHandle<JSObject*>, JS::MutableHandle<JSObject*>, js::PropertyResult*) [js/src/vm/JSObject.cpp:1867]
[task 2021-08-26T16:37:48.097Z] 16:37:48 INFO - GECKO(6400) | #10: bool js::GetEnvironmentName<(js::GetNameMode)0>(JSContext*, JS::Handle<JSObject*>, JS::Handle<js::PropertyName*>, JS::MutableHandle<JS::Value>) [js/src/vm/Interpreter-inl.h:182]
[task 2021-08-26T16:37:48.098Z] 16:37:48 INFO - GECKO(6400) | #11: Interpret(JSContext*, js::RunState&) [js/src/vm/Interpreter.cpp:3386]
[task 2021-08-26T16:37:48.098Z] 16:37:48 INFO - GECKO(6400) | #12: js::RunScript(JSContext*, js::RunState&) [js/src/vm/Interpreter.cpp:370]
[task 2021-08-26T16:37:48.099Z] 16:37:48 INFO - GECKO(6400) | #13: js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) [js/src/vm/Interpreter.cpp:520]
[task 2021-08-26T16:37:48.099Z] 16:37:48 INFO - GECKO(6400) | #14: InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason) [js/src/vm/Interpreter.cpp:548]
[task 2021-08-26T16:37:48.100Z] 16:37:48 INFO - GECKO(6400) | #15: js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) [js/src/vm/Interpreter.cpp:565]
[task 2021-08-26T16:37:48.100Z] 16:37:48 INFO - GECKO(6400) | #16: js::SpreadCallOperation(JSContext*, JS::Handle<JSScript*>, unsigned char*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::MutableHandle<JS::Value>) [js/src/vm/Interpreter.cpp:4994]
[task 2021-08-26T16:37:48.100Z] 16:37:48 INFO - GECKO(6400) | #17: Interpret(JSContext*, js::RunState&) [js/src/vm/Interpreter.cpp:3192]
[task 2021-08-26T16:37:48.101Z] 16:37:48 INFO - GECKO(6400) | #18: js::RunScript(JSContext*, js::RunState&) [js/src/vm/Interpreter.cpp:370]
[task 2021-08-26T16:37:48.101Z] 16:37:48 INFO - GECKO(6400) | #19: js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) [js/src/vm/Interpreter.cpp:520]
[task 2021-08-26T16:37:48.101Z] 16:37:48 INFO - GECKO(6400) | #20: InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason) [js/src/vm/Interpreter.cpp:548]
[task 2021-08-26T16:37:48.102Z] 16:37:48 INFO - GECKO(6400) | #21: js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) [js/src/vm/Interpreter.cpp:565]
[task 2021-08-26T16:37:48.102Z] 16:37:48 INFO - GECKO(6400) | #22: JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) [js/src/vm/CallAndConstruct.cpp:117]
[task 2021-08-26T16:37:48.102Z] 16:37:48 INFO - GECKO(6400) | #23: mozilla::dom::MessageListener::ReceiveMessage(mozilla::dom::BindingCallContext&, JS::Handle<JS::Value>, mozilla::dom::ReceiveMessageArgument const&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&) [s3:gecko-generated-sources:5e0870a806400d903ec078bd402348078738a9b76a8e02612e63fa33085794714a96a39abab4a7f1def6794939e411a8edd18572a818b613371d45dc6342cc5b/dom/bindings/MessageManagerBinding.cpp::6101]
[task 2021-08-26T16:37:48.103Z] 16:37:48 INFO - GECKO(6400) | #24: mozilla::dom::MessageListener::ReceiveMessage(mozilla::dom::ReceiveMessageArgument const&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&, char const*, mozilla::dom::CallbackObject::ExceptionHandling, JS::Realm*) [s3:gecko-generated-sources:4b9f933fd91b8763e1a7ae00fb950ff7d40a1ccba0acac7d1976885142e0c018aa3880cfe4c7fa0c2986616f6e7c25b07b9793b6ff5bdeb403f6b3f2c116b16a/dist/include/mozilla/dom/MessageManagerBinding.h::783]
[task 2021-08-26T16:37:48.103Z] 16:37:48 INFO - GECKO(6400) | #25: mozilla::dom::JSActor::CallReceiveMessage(JSContext*, mozilla::dom::JSActorMessageMeta const&, JS::Handle<JS::Value>, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&) [dom/ipc/jsactor/JSActor.cpp:274]
[task 2021-08-26T16:37:48.104Z] 16:37:48 INFO - GECKO(6400) | #26: mozilla::dom::JSActor::ReceiveQuery(JSContext*, mozilla::dom::JSActorMessageMeta const&, JS::Handle<JS::Value>, mozilla::ErrorResult&) [dom/ipc/jsactor/JSActor.cpp:306]
[task 2021-08-26T16:37:48.105Z] 16:37:48 INFO - GECKO(6400) | #27: mozilla::dom::JSActorManager::ReceiveRawMessage(mozilla::dom::JSActorMessageMeta const&, mozilla::Maybe<mozilla::dom::ipc::StructuredCloneData>&&, mozilla::Maybe<mozilla::dom::ipc::StructuredCloneData>&&) [dom/ipc/jsactor/JSActorManager.cpp:198]
[task 2021-08-26T16:37:48.106Z] 16:37:48 INFO - GECKO(6400) | #28: mozilla::detail::RunnableFunction<mozilla::dom::JSActor::SendRawMessageInProcess(mozilla::dom::JSActorMessageMeta const&, mozilla::Maybe<mozilla::dom::ipc::StructuredCloneData>&&, mozilla::Maybe<mozilla::dom::ipc::StructuredCloneData>&&, std::function<already_AddRefed<mozilla::dom::JSActorManager> ()>&&)::$_0>::Run() [xpcom/threads/nsThreadUtils.h:532]
[task 2021-08-26T16:37:48.107Z] 16:37:48 INFO - GECKO(6400) | #29: mozilla::RunnableTask::Run() [xpcom/threads/TaskController.cpp:503]
[task 2021-08-26T16:37:48.107Z] 16:37:48 INFO - GECKO(6400) | #30: mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) [xpcom/threads/TaskController.cpp:805]
[task 2021-08-26T16:37:48.108Z] 16:37:48 INFO - GECKO(6400) | #31: mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) [xpcom/threads/TaskController.cpp:641]
[task 2021-08-26T16:37:48.109Z] 16:37:48 INFO - GECKO(6400) | #32: mozilla::TaskController::ProcessPendingMTTask(bool) [xpcom/threads/TaskController.cpp:425]
[task 2021-08-26T16:37:48.110Z] 16:37:48 INFO - GECKO(6400) | #33: mozilla::detail::RunnableFunction<mozilla::TaskController::InitializeInternal()::$_0>::Run() [xpcom/threads/nsThreadUtils.h:533]
[task 2021-08-26T16:37:48.110Z] 16:37:48 INFO - GECKO(6400) | #34: nsThread::ProcessNextEvent(bool, bool*) [xpcom/threads/nsThread.cpp:1152]
[task 2021-08-26T16:37:48.111Z] 16:37:48 INFO - GECKO(6400) | #35: NS_ProcessNextEvent(nsIThread*, bool) [xpcom/threads/nsThreadUtils.cpp:466]
[task 2021-08-26T16:37:48.112Z] 16:37:48 INFO - GECKO(6400) | #36: mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) [ipc/glue/MessagePump.cpp:85]
[task 2021-08-26T16:37:48.112Z] 16:37:48 INFO - GECKO(6400) | #37: MessageLoop::RunInternal() [ipc/chromium/src/base/message_loop.cc:331]
[task 2021-08-26T16:37:48.113Z] 16:37:48 INFO - GECKO(6400) | #38: MessageLoop::Run() [ipc/chromium/src/base/message_loop.cc:307]
[task 2021-08-26T16:37:48.113Z] 16:37:48 INFO - GECKO(6400) | #39: nsBaseAppShell::Run() [widget/nsBaseAppShell.cpp:139]
[task 2021-08-26T16:37:48.114Z] 16:37:48 INFO - GECKO(6400) | #40: nsAppStartup::Run() [toolkit/components/startup/nsAppStartup.cpp:285]
[task 2021-08-26T16:37:48.114Z] 16:37:48 INFO - GECKO(6400) | #41: XREMain::XRE_mainRun() [toolkit/xre/nsAppRunner.cpp:5283]
[task 2021-08-26T16:37:48.115Z] 16:37:48 INFO - GECKO(6400) | #42: XREMain::XRE_main(int, char**, mozilla::BootstrapConfig const&) [toolkit/xre/nsAppRunner.cpp:5475]
[task 2021-08-26T16:37:48.115Z] 16:37:48 INFO - GECKO(6400) | #43: XRE_main(int, char**, mozilla::BootstrapConfig const&) [toolkit/xre/nsAppRunner.cpp:5534]
[task 2021-08-26T16:37:48.116Z] 16:37:48 INFO - GECKO(6400) | #44: ??? [/builds/worker/workspace/build/application/firefox/firefox + 0x41d95]
[task 2021-08-26T16:37:48.116Z] 16:37:48 INFO - GECKO(6400) | #45: __libc_start_main [/lib/x86_64-linux-gnu/libc.so.6 + 0x21b97]
[task 2021-08-26T16:37:48.117Z] 16:37:48 INFO - GECKO(6400) | #46: ??? [/builds/worker/workspace/build/application/firefox/firefox + 0x41979]
[task 2021-08-26T16:37:48.117Z] 16:37:48 INFO - GECKO(6400) | #47: ??? (???:???)
[task 2021-08-26T16:37:48.118Z] 16:37:48 INFO - GECKO(6400) | ExceptionHandler::GenerateDump cloned child 6494
[task 2021-08-26T16:37:48.118Z] 16:37:48 INFO - GECKO(6400) | ExceptionHandler::SendContinueSignalToChild sent continue signal to child
[task 2021-08-26T16:37:48.119Z] 16:37:48 INFO - GECKO(6400) | ExceptionHandler::WaitForContinueSignal waiting for continue signal...
[task 2021-08-26T16:37:48.119Z] 16:37:48 INFO - TEST-INFO | Main app process: exit 11
[task 2021-08-26T16:37:48.120Z] 16:37:48 INFO - Buffered messages finished
Updated•4 years ago
|
Comment 26•4 years ago
|
||
Comment 27•4 years ago
|
||
| bugherder | ||
https://hg.mozilla.org/mozilla-central/rev/7ed4db9eadf8
https://hg.mozilla.org/mozilla-central/rev/8dc4e71e2a87
https://hg.mozilla.org/mozilla-central/rev/7b1d9df0326d
https://hg.mozilla.org/mozilla-central/rev/3fd30df11e67
https://hg.mozilla.org/mozilla-central/rev/01975b4520f3
https://hg.mozilla.org/mozilla-central/rev/1415c1d5b485
https://hg.mozilla.org/mozilla-central/rev/a14e1a409342
https://hg.mozilla.org/mozilla-central/rev/6f6342f5827e
https://hg.mozilla.org/mozilla-central/rev/f93209b0b5cc
https://hg.mozilla.org/mozilla-central/rev/4ce1541a6d9c
https://hg.mozilla.org/mozilla-central/rev/aae629cbe232
https://hg.mozilla.org/mozilla-central/rev/ec528ee761f8
https://hg.mozilla.org/mozilla-central/rev/3aa2aa420e24
https://hg.mozilla.org/mozilla-central/rev/907f6eeb9f3b
https://hg.mozilla.org/mozilla-central/rev/6f1eb9f44fd8
| Assignee | ||
Updated•4 years ago
|
Description
•