Bug 1631970 - Delay converting uint64 results to JSVals. r=sg

The rooting hazard analysis is getting upset because of the usage where
a non-GCThing JSVal is declared on the stack and AcquireTransaction() is
called.  The analysis doesn't know that it's guaranteed that the value is
NaN-boxed and can't be a GC thing.  It also doesn't know that the SafeRefPtr
can't already have a value so a release is impossible.

Arguably the hazard analysis doesn't need to know these things though.

This fix delays the point at which we convert the uint64 into a JS::Value.
The [call to GetResult](https://searchfox.org/mozilla-central/rev/446160560bf32ebf4cb7c4e25d7386ee22667255/dom/indexedDB/IDBRequest.cpp#300)
already has a rooted result and the (Auto)JSAPI initialized, so this is
arguably cleaner and less scary in terms of holding raw pointers in the
ResultHelper that aren't necessary.

This fix doesn't correct the ResultTypeJSValHandle which is a similar
situation, except it's a reference to
[UndefinedHandleValue](https://searchfox.org/mozilla-central/rev/446160560bf32ebf4cb7c4e25d7386ee22667255/js/src/vm/Value.cpp#23)
which is I suppose more fine from a GC perspective.  Still somewhat ugly
as used in ResultHelper, but I'm presuming we'll clean ResultHelper up
in the future to use a Variant, at which point we can explicitly indicate
we want `undefined`.

Differential Revision: https://phabricator.services.mozilla.com/D74800
This commit is contained in:
Andrew Sutherland 2020-05-12 10:39:00 +00:00
parent ccaf2b2dac
commit 06937e8b14

View File

@ -207,7 +207,7 @@ class MOZ_STACK_CLASS ResultHelper final : public IDBRequest::ResultCallback {
nsTArray<StructuredCloneReadInfoChild>* mStructuredCloneArray;
const Key* mKey;
const nsTArray<Key>* mKeyArray;
const JS::Value* mJSVal;
uint64_t mUInt64Value;
const JS::Handle<JS::Value>* mJSValHandle;
} mResult;
@ -219,7 +219,7 @@ class MOZ_STACK_CLASS ResultHelper final : public IDBRequest::ResultCallback {
ResultTypeStructuredCloneArray,
ResultTypeKey,
ResultTypeKeyArray,
ResultTypeJSVal,
ResultTypeUInt64,
ResultTypeJSValHandle,
} mResultType;
@ -307,15 +307,14 @@ class MOZ_STACK_CLASS ResultHelper final : public IDBRequest::ResultCallback {
}
ResultHelper(IDBRequest* aRequest, SafeRefPtr<IDBTransaction> aTransaction,
const JS::Value* aResult)
const uint64_t aResult)
: mRequest(aRequest),
mAutoTransaction(aTransaction ? SomeRef(*aTransaction) : Nothing()),
mTransaction(std::move(aTransaction)),
mResultType(ResultTypeJSVal) {
mResultType(ResultTypeUInt64) {
MOZ_ASSERT(aRequest);
MOZ_ASSERT(!aResult->isGCThing());
mResult.mJSVal = aResult;
mResult.mUInt64Value = aResult;
}
ResultHelper(IDBRequest* aRequest, SafeRefPtr<IDBTransaction> aTransaction,
@ -357,8 +356,8 @@ class MOZ_STACK_CLASS ResultHelper final : public IDBRequest::ResultCallback {
case ResultTypeKeyArray:
return GetResult(aCx, mResult.mKeyArray, aResult);
case ResultTypeJSVal:
aResult.set(*mResult.mJSVal);
case ResultTypeUInt64:
aResult.set(JS::NumberValue(mResult.mUInt64Value));
return NS_OK;
case ResultTypeJSValHandle:
@ -2681,9 +2680,7 @@ void BackgroundRequestChild::HandleResponse(JS::Handle<JS::Value> aResponse) {
void BackgroundRequestChild::HandleResponse(uint64_t aResponse) {
AssertIsOnOwningThread();
JS::Value response(JS::NumberValue(aResponse));
ResultHelper helper(mRequest, AcquireTransaction(), &response);
ResultHelper helper(mRequest, AcquireTransaction(), aResponse);
helper.DispatchSuccessEvent();
}