Bug 1590198 Comment 12 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

(In reply to Kannan Vijayan [:djvj] from comment #11)
> wouldn't it be an expensive thing to access via a shuple indirection anyway?

It's definitely a concern, but an extra dereference is hopefully easier to justify than a branch. Also, with shuples we could potentially move some of {Realm, Class, prototype} to the shuple itself so we don't have the extra indirection?

> Jan, can you describe the hot-paths that access these members of ObjectGroup (class, proto, realm)?  What proportion of them are in places where we might statically expect to already know that we have either a Function or a non-Function object?  Are we pulling them out to do more than simply guard them against a specific value?

For the JIT/IC uses, in many cases (especially guards) we know more statically. I'm worried about:
* A lot of code checks the Class, there are hundreds of `obj->is<T>()` calls [in SpiderMonkey](https://searchfox.org/mozilla-central/search?q=symbol:_ZNK8JSObject2isEv&redirect=false) and Gecko. Or things like [JSObject::isNative()](https://searchfox.org/mozilla-central/search?q=symbol:_ZNK8JSObject8isNativeEv&redirect=false). 
* Class hook checks [like here](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/vm/ObjectOperations-inl.h#113) or [in JSObject::finalize](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/vm/JSObject-inl.h#65-70). GC code operates on "any JSObject", tracing/finalization code needs to know the object layout and these branches are not well-predicted.
* Loops like [this one](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/jit/CacheIRCompiler.cpp#4496-4497) for instanceof (and the C++ equivalent), or the one in [GetNativeDataPropertyPure](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/jit/VMFunctions.cpp#1653) (this one often shows up in profiles for megamorphic sites).
* AutoRealm, obj->compartment(), obj->zone() are used often with arbitrary objects.

What if we gave all JSFunctions:
* A pointer to a very generic shuple (say, Class, Realm, prototype, empty Shape) fields, this tuple could basically be shared across all functions in the realm.
* An extra pointer in the object (where the ObjectGroup is now?) to the canonical function, if any.

Then we can shrink JSObject, but JSFunction would still have this second pointer and that's probably okay. I didn't really think this through so maybe it won't work, just wanted to mention it.
(In reply to Kannan Vijayan [:djvj] from comment #11)
> wouldn't it be an expensive thing to access via a shuple indirection anyway?

It's definitely a concern, but an extra dereference is hopefully easier to justify than a branch. Also, with shuples we could potentially move some of {Realm, Class, prototype} to the shuple itself so we don't have the extra indirection?

> Jan, can you describe the hot-paths that access these members of ObjectGroup (class, proto, realm)?  What proportion of them are in places where we might statically expect to already know that we have either a Function or a non-Function object?  Are we pulling them out to do more than simply guard them against a specific value?

For the JIT/IC uses, in many cases (especially guards) we know more statically. I'm worried about:
* A lot of code checks the Class, there are hundreds of `obj->is<T>()` calls [in SpiderMonkey](https://searchfox.org/mozilla-central/search?q=symbol:_ZNK8JSObject2isEv&redirect=false) and Gecko. Or things like [JSObject::isNative()](https://searchfox.org/mozilla-central/search?q=symbol:_ZNK8JSObject8isNativeEv&redirect=false). 
* Class hook checks [like here](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/vm/ObjectOperations-inl.h#113) or [in JSObject::finalize](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/vm/JSObject-inl.h#65-70). GC code operates on "any JSObject", tracing/finalization code needs to know the object layout and these branches are not well-predicted.
* Loops like [this one](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/jit/CacheIRCompiler.cpp#4496-4497) for instanceof (and the C++ equivalent), or the one in [GetNativeDataPropertyPure](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/jit/VMFunctions.cpp#1653) (this one often shows up in profiles for megamorphic sites).
* AutoRealm, obj->compartment(), obj->zone() are used often with arbitrary objects.
---
What if we gave all JSFunctions:
* A pointer to a very generic shuple (say, Class, Realm, prototype, empty Shape) fields, this tuple could basically be shared across all functions in the realm.
* An extra pointer in the object (where the ObjectGroup is now?) to the canonical function, if any.

Then we can shrink JSObject, but JSFunction would still have this second pointer and that's probably okay. I didn't really think this through so maybe it won't work, just wanted to mention it.
(In reply to Kannan Vijayan [:djvj] from comment #11)
> wouldn't it be an expensive thing to access via a shuple indirection anyway?

It's definitely a concern, but an extra dereference is hopefully easier to justify than a branch. Also, with shuples we could potentially move some of {Realm, Class, prototype} to the shuple itself so we don't have the extra indirection?

> Jan, can you describe the hot-paths that access these members of ObjectGroup (class, proto, realm)?  What proportion of them are in places where we might statically expect to already know that we have either a Function or a non-Function object?  Are we pulling them out to do more than simply guard them against a specific value?

For the JIT/IC uses, in many cases (especially guards) we know more statically. I'm worried about:
* A lot of code checks the Class, there are hundreds of `obj->is<T>()` calls [in SpiderMonkey](https://searchfox.org/mozilla-central/search?q=symbol:_ZNK8JSObject2isEv&redirect=false) and Gecko. Or things like [JSObject::isNative()](https://searchfox.org/mozilla-central/search?q=symbol:_ZNK8JSObject8isNativeEv&redirect=false). 
* Class hook checks [like here](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/vm/ObjectOperations-inl.h#113) or [in JSObject::finalize](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/vm/JSObject-inl.h#65-70). GC code operates on "any JSObject", tracing/finalization code needs to know the object layout and these branches are not well-predicted.
* Loops like [this one](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/jit/CacheIRCompiler.cpp#4496-4497) for instanceof (and the C++ equivalent), or the one in [GetNativeDataPropertyPure](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/jit/VMFunctions.cpp#1653) (this one often shows up in profiles for megamorphic sites).
* AutoRealm, obj->compartment(), obj->zone() are used often with arbitrary objects.
---
(edit: nevermind, this doesn't really help you)
(In reply to Kannan Vijayan [:djvj] from comment #11)
> wouldn't it be an expensive thing to access via a shuple indirection anyway?

It's definitely a concern, but an extra dereference is hopefully easier to justify than a branch. Also, with shuples we could potentially move some of {Realm, Class, prototype} to the shuple itself so we don't have the extra indirection?

> Jan, can you describe the hot-paths that access these members of ObjectGroup (class, proto, realm)?  What proportion of them are in places where we might statically expect to already know that we have either a Function or a non-Function object?  Are we pulling them out to do more than simply guard them against a specific value?

For the JIT/IC uses, in many cases (especially guards) we know more statically. I'm worried about:
* A lot of code checks the Class, there are hundreds of `obj->is<T>()` calls [in SpiderMonkey](https://searchfox.org/mozilla-central/search?q=symbol:_ZNK8JSObject2isEv&redirect=false) and Gecko. Or things like [JSObject::isNative()](https://searchfox.org/mozilla-central/search?q=symbol:_ZNK8JSObject8isNativeEv&redirect=false). 
* Class hook checks [like here](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/vm/ObjectOperations-inl.h#113) or [in JSObject::finalize](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/vm/JSObject-inl.h#65-70). GC code operates on "any JSObject", tracing/finalization code needs to know the object layout and these branches are not well-predicted.
* Loops like [this one](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/jit/CacheIRCompiler.cpp#4496-4497) for instanceof (and the C++ equivalent), or the one in [GetNativeDataPropertyPure](https://searchfox.org/mozilla-central/rev/8a63fc190b39ed6951abb4aef4a56487a43962bc/js/src/jit/VMFunctions.cpp#1653) (this one often shows up in profiles for megamorphic sites).
* AutoRealm, obj->compartment(), obj->zone() are used often with arbitrary objects.
---
(edit: never mind, this doesn't really help you)

Back to Bug 1590198 Comment 12