Bug 888338 - 7 - add post barriers to workers r=smaug

This commit is contained in:
Jon Coppeard 2013-07-23 10:58:27 +01:00
parent c561caee58
commit f9660af75a
5 changed files with 57 additions and 24 deletions

View File

@ -60,7 +60,7 @@ private:
struct ListenerData : LinkedListElement<ListenerData>
{
JSObject* mListener;
JS::Heap<JSObject*> mListener;
EventListenerManager::Phase mPhase;
bool mWantsUntrusted;
@ -184,9 +184,9 @@ EventListenerManager::TraceInternal(JSTracer* aTrc) const
for (const ListenerData* listenerElem = collection->mListeners.getFirst();
listenerElem;
listenerElem = listenerElem->getNext()) {
JS_CallObjectTracer(aTrc,
&const_cast<ListenerData*>(listenerElem)->mListener,
"EventListenerManager listener object");
JS_CallHeapObjectTracer(aTrc,
&const_cast<ListenerData*>(listenerElem)->mListener,
"EventListenerManager listener object");
}
}
}

View File

@ -1763,8 +1763,8 @@ struct WorkerPrivate::TimeoutInfo
return mTargetTime < aOther.mTargetTime;
}
JS::Value mTimeoutVal;
nsTArray<jsval> mExtraArgVals;
JS::Heap<JS::Value> mTimeoutVal;
nsTArray<JS::Heap<JS::Value> > mExtraArgVals;
mozilla::TimeStamp mTargetTime;
mozilla::TimeDuration mInterval;
nsCString mFilename;
@ -3398,11 +3398,11 @@ WorkerPrivate::TraceInternal(JSTracer* aTrc)
for (uint32_t index = 0; index < mTimeouts.Length(); index++) {
TimeoutInfo* info = mTimeouts[index];
JS_CallValueTracer(aTrc, &info->mTimeoutVal,
"WorkerPrivate timeout value");
JS_CallHeapValueTracer(aTrc, &info->mTimeoutVal,
"WorkerPrivate timeout value");
for (uint32_t index2 = 0; index2 < info->mExtraArgVals.Length(); index2++) {
JS_CallValueTracer(aTrc, &info->mExtraArgVals[index2],
"WorkerPrivate timeout extra argument value");
JS_CallHeapValueTracer(aTrc, &info->mExtraArgVals[index2],
"WorkerPrivate timeout extra argument value");
}
}
}
@ -3952,7 +3952,7 @@ WorkerPrivate::SetTimeout(JSContext* aCx, unsigned aArgc, jsval* aVp,
newInfo->mInterval = TimeDuration::FromMilliseconds(intervalMS);
if (aArgc > 2 && newInfo->mTimeoutVal.isObject()) {
nsTArray<jsval> extraArgVals(aArgc - 2);
nsTArray<JS::Heap<JS::Value> > extraArgVals(aArgc - 2);
for (unsigned index = 2; index < aArgc; index++) {
extraArgVals.AppendElement(argv[index]);
}
@ -4104,9 +4104,14 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
}
else {
JS::Rooted<JS::Value> rval(aCx);
/*
* unsafeGet() is needed below because the argument is a not a const
* pointer, even though values are not modified.
*/
if (!JS_CallFunctionValue(aCx, global, info->mTimeoutVal,
info->mExtraArgVals.Length(),
info->mExtraArgVals.Elements(), rval.address()) &&
info->mExtraArgVals.Elements()->unsafeGet(),
rval.address()) &&
!JS_ReportPendingException(aCx)) {
retval = false;
break;

View File

@ -77,7 +77,7 @@ class WorkerGlobalScope : public workers::EventTarget
};
// Must be traced!
jsval mSlots[SLOT_COUNT];
JS::Heap<JS::Value> mSlots[SLOT_COUNT];
enum
{
@ -128,7 +128,7 @@ protected:
_trace(JSTracer* aTrc) MOZ_OVERRIDE
{
for (int32_t i = 0; i < SLOT_COUNT; i++) {
JS_CallValueTracer(aTrc, &mSlots[i], "WorkerGlobalScope instance slot");
JS_CallHeapValueTracer(aTrc, &mSlots[i], "WorkerGlobalScope instance slot");
}
mWorker->TraceInternal(aTrc);
EventTarget::_trace(aTrc);

View File

@ -520,7 +520,7 @@ class EventRunnable : public MainThreadProxyRunnable
nsString mResponseType;
JSAutoStructuredCloneBuffer mResponseBuffer;
nsTArray<nsCOMPtr<nsISupports> > mClonedObjects;
jsval mResponse;
JS::Heap<JS::Value> mResponse;
nsString mResponseText;
nsCString mStatusText;
uint64_t mLoaded;
@ -607,6 +607,28 @@ public:
return true;
}
class StateDataAutoRooter : private JS::CustomAutoRooter
{
public:
explicit StateDataAutoRooter(JSContext* aCx, XMLHttpRequest::StateData* aData
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: CustomAutoRooter(aCx), mStateData(aData), mSkip(aCx, mStateData)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
private:
virtual void trace(JSTracer* aTrc)
{
JS_CallHeapValueTracer(aTrc, &mStateData->mResponse,
"XMLHttpRequest::StateData::mResponse");
}
XMLHttpRequest::StateData* mStateData;
js::SkipRoot mSkip;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
{
@ -665,8 +687,7 @@ public:
}
XMLHttpRequest::StateData state;
// XXXbz there is no AutoValueRooter anymore?
JS::AutoArrayRooter rooter(aCx, 1, &state.mResponse);
StateDataAutoRooter rooter(aCx, &state);
state.mResponseTextResult = mResponseTextResult;
state.mResponseText = mResponseText;
@ -1423,9 +1444,9 @@ void
XMLHttpRequest::_trace(JSTracer* aTrc)
{
if (mUpload) {
mUpload->TraceJSObject(aTrc, "mUpload");
mUpload->TraceJSObject(aTrc, "XMLHttpRequest::mUpload");
}
JS_CallValueTracer(aTrc, &mStateData.mResponse, "mResponse");
JS_CallHeapValueTracer(aTrc, &mStateData.mResponse, "XMLHttpRequest::mResponse");
XMLHttpRequestEventTarget::_trace(aTrc);
}
@ -1510,13 +1531,19 @@ XMLHttpRequest::MaybePin(ErrorResult& aRv)
JSContext* cx = GetJSContext();
if (!JS_AddNamedObjectRoot(cx, &mJSObject, "XMLHttpRequest mJSObject")) {
/*
* It's safe to use unsafeGet() here: the unsafeness comes from the
* possibility of updating the value of mJSObject without triggering the post
* barriers. However if the value will always be marked, post barriers are
* unnecessary.
*/
if (!JS_AddNamedObjectRoot(cx, mJSObject.unsafeGet(), "XMLHttpRequest::mJSObjectRooted")) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
if (!mWorkerPrivate->AddFeature(cx, this)) {
JS_RemoveObjectRoot(cx, &mJSObject);
JS_RemoveObjectRoot(cx, mJSObject.unsafeGet());
aRv.Throw(NS_ERROR_FAILURE);
return;
}
@ -1635,7 +1662,8 @@ XMLHttpRequest::Unpin()
JSContext* cx = GetJSContext();
JS_RemoveObjectRoot(cx, &mJSObject);
/* See the comment in MaybePin() for why this is safe. */
JS_RemoveObjectRoot(cx, mJSObject.unsafeGet());
mWorkerPrivate->RemoveFeature(cx, this);

View File

@ -31,7 +31,7 @@ public:
uint32_t mStatus;
nsCString mStatusText;
uint16_t mReadyState;
jsval mResponse;
JS::Heap<JS::Value> mResponse;
nsresult mResponseTextResult;
nsresult mStatusResult;
nsresult mResponseResult;
@ -44,7 +44,7 @@ public:
};
private:
JSObject* mJSObject;
JS::Heap<JSObject*> mJSObject;
XMLHttpRequestUpload* mUpload;
WorkerPrivate* mWorkerPrivate;
nsRefPtr<Proxy> mProxy;