Any more specific work that is happening in these methods will have its own
specific category labeling in that specific code. The instances touched in this
patch are more on the outside and don't really know what kind of code is going
to be running inside.
MozReview-Commit-ID: 47NO1DZzkdH
--HG--
extra : rebase_source : 344c380ddaaf42a1fd820a26b762c61ee9e2d524
Any more specific work that is happening in these methods will have its own
specific category labeling in that specific code. The instances touched in this
patch are more on the outside and don't really know what kind of code is going
to be running inside.
MozReview-Commit-ID: 47NO1DZzkdH
--HG--
extra : rebase_source : f807c14bf6a592e0c651e15b63d1e7d63e4b0159
Any more specific work that is happening in these methods will have its own
specific category labeling in that specific code. The instances touched in this
patch are more on the outside and don't really know what kind of code is going
to be running inside.
MozReview-Commit-ID: 47NO1DZzkdH
--HG--
extra : rebase_source : 35362bc94068103367f46b23a14cb3831cd86990
The ScriptPreloader stopped recording before browser-delayed-startup-finished before, but there
are other scripts (both in the parent and content processes) that might run soon after that we
also want to cache. This increases the probability that those scripts are noted by the
ScriptPreloader cache.
MozReview-Commit-ID: KiBEVvuqQkA
--HG--
extra : rebase_source : 4c1bffa882b0641f93260867ac8a4334b1269e99
Some of the less trivial changes:
* When we allocated a symbol, we used the atom realm's RNG to create a hash code [0]. Instead of this I added a RNG for this to the runtime.
* IsCompilingWasm returned true if the JitContext's realm is nullptr, but that's now also true when we initialize the trampolines stored in the atoms zone. To fix that I added a CompileZone* to JitContext, in addition to the CompileRuntime and CompileRealm, and we now check the zone instead of the realm in IsCompilingWasm.
* JSContext::hasEnteredRealm is only called in DEBUG builds so I made hasEnteredRealm and enterRealmDepth_ #ifdef DEBUG.
Tracing the script members held alive by PrecompiledScript objects can be
expensive, especially for large scripts. It would be nice if we could avoid
tracing them when possible.
Most of the time, when PrecompiledScripts are alive, they're held alive by
black roots, and have black JS wrappers. In those cases, there's no chance of
them creating garbage cycles, and we can just mark their script children
black.
MozReview-Commit-ID: KnkJfznJZBx
--HG--
extra : rebase_source : da0da30265c3f752c9aba177bf510937a743e49e
This implements a new kind of lazy getter in XPCOMUtils that creates an object (implemented as a JS Proxy) that is resilient to be passed around as references to other functions, and will only evaluate the getter when it really needs to be used
This one sucks. I found out when running tests that we exploit some edge
case behaviour in our tests where passing an invalid value to an xpidl
array parameter will be passed as an empty array...
I figured that just respecting this behaviour for now is the easiest
approach, but we will probably want to fix it in the future.
Current XPIDL native arrays currently also require a custom entry point. With
the new arraylen parameter we can handle them in JSData2Native/NativeData2JS. As
these methods are more complex and don't share logic with an existing codepath,
I keep them in external helper methods.
XPIDL supports explicitly sized string types. These types currently have to be
handled by a separate entry point into XPCConvert, and don't share any logic
with the implicitly sized string types.
If we just add an array length parameter to the basic JSData2Native and
NativeData2JS methods we can handle them in the same place as every other type.
This also allows us to share a lot of code with non-sized string types, which is
nice :-).
When a jsval passed from JS code it needs to be stored in a nsXPTCVariant
object. This object is not rooted by default, as it is stored in some
C++-allocated memory. Currently, we root the values by adding a custom root
using the `js::AddRawValueRoot` API, which is deprecated, and only used by this
code and ErrorResult.
This also has the unfortunate effect that we cannot support XPCOM arrays of
jsvals, as we cannot root all of the values in the array using this API.
Fortunately, the JS engine has a better rooting API which we can use here
instead. I make the call context a custom rooter, like the SequenceRooter type
from WebIDL, and make sure to note every jsval when tracing, both in arrays and
as direct values.
This should allow us to avoid some hashtable operations with roots when
performing XPConnect calls, and remove a consumer of this gross legacy API.
In addition it allows us to support arrays. This will be even more useful in the
future when I add support for sequence<T> (which is a nsTArray<T>) to xpidl and
xpconnect.
In XPConnect, native values are passed around within nsXPTCMiniVariant objects.
an [nsXPTCMiniVariant] contains 64-bits of data in a union type.
nsXPTCMiniVariant values are created by the platform-specific glue code and
passed into XPConnect proper when calling from C++ into JS.
When calling from JS into C++, we instead create nsXPTCVariant objects and pass
them into the glue code. These objects have extra information in addition to the
nsXPTCMiniVariant: namely they also have a `type` field with the type stored in
the variant, space for flags, and a `ptr` field which is passed over IPC instead
of the inner nsXPTCMiniVariant when a flag (`PTR_IS_DATA`) is set.
The JSValue type in XPConnect is always passed as a pointer to a JSValue object,
both for in parameters and out parameters. This is handled by making the JSValue
type be unconditionally flagged as [`IsIndirect()`] This flag is also used for
all types of outparameters.
When the `IsIndirect()` flag is set, it means that the actual data is stored in
the nsXPTCVariant's val field, and it sets the flag to tell the glue code to
instead pass the `ptr` field (which is always pointing to the `val` field for
[legacy reasons]) into the C++ code.
In contrast "dipper" is a different and super weird flag. Currently only the
string class types (nsACString & nsAString) are marked as "dipper". A "dipper"
type is always passed as an "in" type (and thus always passed "directly"), even
when it's actually an out parameter.
XPConnect treats these types as though they are pointer types (nsAString*). This
means that there is no space in the nsXPTCVariant to store the actual nsAString
types when passing from JS into C++, so these values have to be allocated by a
different mechanism (in the current code, there is a size 2 buffer for each
string type in the context and once that buffer is exceeded, we heap allocate
the nsString values).
In effect, the current state looks something like this:
+------------+---------------------+---------------------+
| type | out (xpt/native) | in (xpt/native) |
+------------+---------------------+---------------------+
| TD_INT32 | indirect (int32_t*) | direct (int32_t) |
+------------+---------------------+---------------------+
| TD_JSVAL | indirect (JSValue*) | indirect (JSValue*) |
+------------+---------------------+---------------------+
| TD_ASTRING | direct (nsAString*) | direct (nsAString*) |
+------------+---------------------+---------------------+
This patch ensures there is enough space in the nsXPTCVariant to fit the
nsString value, and switches string class types to being unconditionally
indirect instead of using the dipper system. This allows us to delete a ton of
dipper-specific code, and unify the indirect and string class codepaths.
This only affects the size of nsXPTCVariant objects, and does not affect
nsXPTCMiniVariant objects. nsXPTCVariant objects are never allocated by the
platform-specific binding code, rather, they are allocated in an AutoTArray on
the stack as part of the CallMethodHelper object.
The size increase is a total of 1 word, so 4 bytes in 32-bit builds, and 8 bytes
in 64-bit builds, which is ignorable for stack allocated objects.
[nsXPTCMiniVariant]: https://searchfox.org/mozilla-central/rev/eb6c5214a63e20a3fff455e92c876287a8d2e188/xpcom/reflect/xptcall/xptcall.h#20-47
[`IsIndirect()`]: https://searchfox.org/mozilla-central/rev/c0d81882c7941c4ff13a50603e37095cdab0d1ea/xpcom/reflect/xptinfo/xptinfo.h#371
[legacy reasons]: https://searchfox.org/mozilla-central/rev/eb6c5214a63e20a3fff455e92c876287a8d2e188/xpcom/reflect/xptcall/xptcall.h#66-79
It used to be that in XPConnect there were many different pieces of code for
each place where we may need to clean up some untyped values based on their
nsXPTType information. This was a mess, and meant that every time you needed to
add a new data type you'd have to find every one of these places and add support
for your new type to them.
In fact, this was bad enough that it appears that I missed some places when
adding my webidl support! Which means that in some edge cases we may clean up
one of these values incorrectly D:!
This patch adds a new unified method which performs the cleanup by looking at a
nsXPTType object. The idea is that this function takes a void* which is actually
a T* where T is a value of the nsXPTType parmaeter. It clears the value behind
the pointer to a valid state such that free-ing the memory would not cause any
leaks. e.g. it free(...)s owned pointers and sets the pointer to `nullptr`, and
truncates nsA[C]String values such that they reference the static empty string.
I also modify every one of these custom cleanup codepaths to instead call into
this unified cleanup method.
This also involved some simplification of helper methods in order to make the
implementation cleaner.