The rejection handling state will be required even without devtools being open once projection rejection tracking events[1] are implemented, so it should always be tracked on the Promise itself. The other debugging state will be moved into a debug-only object referenced via a slot on Promise.
MozReview-Commit-ID: LM10qruLDxz
A Promise can only have either a list of reactions, if it's pending, or a result/reason, if it's resolved.
This gets us down to 3 non-debug-info slots. If we now move the debug info into its own object and only allocate that when the debugger is open, Promise instances only need 4 slots.
MozReview-Commit-ID: FuLAwhmFTBe
Importantly, CreateResolvingFunctions, ResolvePromise, and TriggerPromiseReactions have been ported.
This reduces memory usage because before, the `resolve` and `reject` functions stored on a pending Promise kept track of each other and the Promise they belong to using a closure. Now, that state is stored in the functions' extended slots - which they have anyway.
It should also improve performance, as fewer switches between JS and C++ code occur during processing of Promise reaction job lists.
MozReview-Commit-ID: 9Wp0sDFayTy
Saves 96 bytes on reaction-less promises. It also saves 32 bytes on promises that have up to two reactions: empty arrays are initialized with an allocated length of 8, whereas providing an initial element initializes to 2.
MozReview-Commit-ID: 3PtT7LDwL3k
This saves a slot on Promise instances, an Array allocation, and a rejection record per dependent promise.
While the first doesn't in itself save anything (going from 12 to 11 slots doesn't do anything), the second saves 96 bytes per Promise, and the third 64 bytes per dependent Promise.
MozReview-Commit-ID: BglU9tx89rD
If we are inserting an XPCNativeSet into a NativeSetMap, and we failed
to find it, then the insertion should not have found some other set
there already.
Additionally in this case, the hash value of a XPCNativeSetKey for the
set we are inserting should be the same as the key we used to insert
the set into the map. If this property does not hold, then we can't
use Remove() to remove the set from the map. This condition would have
caught the error that part 1 fixes.
MozReview-Commit-ID: 23v37GzA4XV
--HG--
extra : rebase_source : 4dca7ffc436f53214eb2927bc1ff2f71927f7ac3
The current hash function fails to take into account that all
XPCNativeSets have nsISupports as their first element.
MozReview-Commit-ID: 7B8TPVnaM7I
--HG--
extra : rebase_source : a357f88a7d54aa1c9f58b6d429d4a5bbaaa13e80
We crash sometimes if we fail to add. We should always crash, because
we don't properly attempt to handle failure, and it would be nice to
get proper OOM-annotated crash reports.
MozReview-Commit-ID: EGgYxPdUSky
--HG--
extra : rebase_source : 92faf09c52452089b32cc430c04568b81e677f74
Some background first. For names that must be looked up dynamically, TDZ
checks are built in to the various NAME ops. For an assignment |x = 42|,
we emit:
BINDNAME "x"
INT8 42
SETNAME "x"
where the order of operations is:
1) BINDNAME first looks up the env where "x" is bound,
2) The RHS is evaluated,
3) The resulting value is assigned to "x" in the env from step 1)
That is, spec requires it that 3) is what throws any TDZ violations,
meaning we must evaluate RHS first. However, the implementation of
SETNAME is ultimately a call into SetProperty. Slowing down SetProperty
calls with TDZ checks was a non-starter. What we do instead is that if
BINDNAME sees a TDZ poison value when looking up the environment,
instead of pushing the actual environment, it pushes a magical
LexicalRuntimeErrorObject, which throws TDZ errors if it's touched in
any way (sets, gets, has-own-property, etc).
The code that created the LexicalRuntimeErrorObject did not understand
how to unwrap DebugScopeObjects, thus it considered that
DebugScopeObjects could never generate TDZ errors, leading to this bug.