This commit is contained in:
Wes Kocher 2014-05-08 19:17:20 -07:00
Родитель a58ca99144 7e3c640525
Коммит d8189ee58f
59 изменённых файлов: 776 добавлений и 160 удалений

Просмотреть файл

@ -120,6 +120,16 @@ this.FxAccountsMgmtService = {
}
).then(null, Components.utils.reportError);
break;
case "resendVerificationEmail":
FxAccountsManager.resendVerificationEmail().then(
() => {
self._onFulfill(msg.id);
},
reason => {
self._onReject(msg.id, reason);
}
).then(null, Components.utils.reportError);
break;
case "signIn":
case "signUp":
case "refreshAuthentication":

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="ca283b9db2b151d465cfd2e19346cf58fe89e413"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3691614d0045f7968addce45d4140fb360c3ceaf"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="65fba428f8d76336b33ddd9e15900357953600ba">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="ca283b9db2b151d465cfd2e19346cf58fe89e413"/>

Просмотреть файл

@ -18,7 +18,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3691614d0045f7968addce45d4140fb360c3ceaf"/>
@ -119,7 +119,7 @@
<!-- Flame specific things -->
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="e8a318f7690092e639ba88891606f4183e846d3f"/>
<project name="device/qcom/common" path="device/qcom/common" revision="234ed34543345f58c0d4dcb1aa012de68802b9dc"/>
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="2a3f4c782daad9740f1b78766b636e0e00a0ff30"/>
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="ecc08b2f0efea93c778e3525553bcd4bd5f2cf49"/>
<project name="kernel/msm" path="kernel" revision="1f47f3a180ed8b070f3cf3c4d11ff2523cca6c8a"/>
<project name="platform/bootable/recovery" path="bootable/recovery" revision="f2914eacee9120680a41463708bb6ee8291749fc"/>
<project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="fa892235a9bd8983f8b591129fc1a9398f64e514"/>

Просмотреть файл

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "18441d7d35b6a96732575fb5c28cedfed8269fb2",
"revision": "5476e49adf00cafde6cb68e876f0514dac4b993d",
"repo_path": "/integration/gaia-central"
}

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

Просмотреть файл

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3691614d0045f7968addce45d4140fb360c3ceaf"/>

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

Просмотреть файл

@ -250,17 +250,6 @@ class B2GRemoteAutomation(Automation):
if 'b2g' not in session:
raise Exception("bad session value %s returned by start_session" % session)
if self._is_emulator:
# Disable offline status management (bug 777145), otherwise the network
# will be 'offline' when the mochitests start. Presumably, the network
# won't be offline on a real device, so we only do this for emulators.
self.marionette.set_context(self.marionette.CONTEXT_CHROME)
self.marionette.execute_script("""
Components.utils.import("resource://gre/modules/Services.jsm");
Services.io.manageOfflineStatus = false;
Services.io.offline = false;
""")
if self.context_chrome:
self.marionette.set_context(self.marionette.CONTEXT_CHROME)
else:

Просмотреть файл

@ -29,6 +29,7 @@
#include "mozilla/dom/MediaStreamBinding.h"
#include "mozilla/dom/MediaStreamTrackBinding.h"
#include "mozilla/dom/GetUserMediaRequestBinding.h"
#include "mozilla/Preferences.h"
#include "MediaTrackConstraints.h"
#include "Latency.h"
@ -730,7 +731,7 @@ static SourceSet *
GetSources(MediaEngine *engine,
ConstraintsType &aConstraints,
void (MediaEngine::* aEnumerate)(nsTArray<nsRefPtr<SourceType> >*),
char* media_device_name = nullptr)
const char* media_device_name = nullptr)
{
ScopedDeletePtr<SourceSet> result(new SourceSet);
@ -748,7 +749,6 @@ static SourceSet *
* to.
*/
for (uint32_t len = sources.Length(), i = 0; i < len; i++) {
#ifdef DEBUG
sources[i]->GetName(deviceName);
if (media_device_name && strlen(media_device_name) > 0) {
if (deviceName.EqualsASCII(media_device_name)) {
@ -756,11 +756,8 @@ static SourceSet *
break;
}
} else {
#endif
candidateSet.AppendElement(MediaDevice::Create(sources[i]));
#ifdef DEBUG
}
#endif
}
}
@ -1146,7 +1143,8 @@ public:
const MediaStreamConstraints& aConstraints,
already_AddRefed<nsIGetUserMediaDevicesSuccessCallback> aSuccess,
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
uint64_t aWindowId, char* aAudioLoopbackDev, char* aVideoLoopbackDev)
uint64_t aWindowId, nsACString& aAudioLoopbackDev,
nsACString& aVideoLoopbackDev)
: mConstraints(aConstraints)
, mSuccess(aSuccess)
, mError(aError)
@ -1171,14 +1169,14 @@ public:
VideoTrackConstraintsN constraints(GetInvariant(mConstraints.mVideo));
ScopedDeletePtr<SourceSet> s(GetSources(backend, constraints,
&MediaEngine::EnumerateVideoDevices,
mLoopbackVideoDevice));
mLoopbackVideoDevice.get()));
final->MoveElementsFrom(*s);
}
if (IsOn(mConstraints.mAudio)) {
AudioTrackConstraintsN constraints(GetInvariant(mConstraints.mAudio));
ScopedDeletePtr<SourceSet> s (GetSources(backend, constraints,
&MediaEngine::EnumerateAudioDevices,
mLoopbackAudioDevice));
mLoopbackAudioDevice.get()));
final->MoveElementsFrom(*s);
}
NS_DispatchToMainThread(new DeviceSuccessCallbackRunnable(mWindowId,
@ -1199,8 +1197,8 @@ private:
// Audio & Video loopback devices to be used based on
// the preference settings. This is currently used for
// automated media tests only.
char* mLoopbackAudioDevice;
char* mLoopbackVideoDevice;
nsCString mLoopbackAudioDevice;
nsCString mLoopbackVideoDevice;
};
MediaManager::MediaManager()
@ -1584,22 +1582,12 @@ MediaManager::GetUserMediaDevices(nsPIDOMWindow* aWindow,
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> onSuccess(aOnSuccess);
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onError(aOnError);
char* loopbackAudioDevice = nullptr;
char* loopbackVideoDevice = nullptr;
#ifdef DEBUG
nsresult rv;
// Check if the preference for using loopback devices is enabled.
nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
if (branch) {
branch->GetCharPref("media.audio_loopback_dev", &loopbackAudioDevice);
branch->GetCharPref("media.video_loopback_dev", &loopbackVideoDevice);
}
}
#endif
nsAdoptingCString loopbackAudioDevice =
Preferences::GetCString("media.audio_loopback_dev");
nsAdoptingCString loopbackVideoDevice =
Preferences::GetCString("media.video_loopback_dev");
nsCOMPtr<nsIRunnable> gUMDRunnable = new GetUserMediaDevicesRunnable(
aConstraints, onSuccess.forget(), onError.forget(),

Просмотреть файл

@ -8,6 +8,16 @@ var Cr = SpecialPowers.Cr;
// Specifies whether we are using fake streams to run this automation
var FAKE_ENABLED = true;
try {
var audioDevice = SpecialPowers.getCharPref('media.audio_loopback_dev');
var videoDevice = SpecialPowers.getCharPref('media.video_loopback_dev');
dump('TEST DEVICES: Using media devices:\n');
dump('audio: ' + audioDevice + '\nvideo: ' + videoDevice + '\n');
FAKE_ENABLED = false;
} catch (e) {
dump('TEST DEVICES: No test devices found (in media.{audio,video}_loopback_dev, using fake streams.\n');
FAKE_ENABLED = true;
}
/**
@ -97,7 +107,7 @@ function createMediaElement(type, label) {
* The error callback if the stream fails to be retrieved
*/
function getUserMedia(constraints, onSuccess, onError) {
if (!("fake" in constraints)) {
if (!("fake" in constraints) && FAKE_ENABLED) {
constraints["fake"] = FAKE_ENABLED;
}

Просмотреть файл

@ -737,6 +737,7 @@ static const dom::ConstantSpec gWinProperties[] =
INT_CONSTANT(DACL_SECURITY_INFORMATION),
// Errors
INT_CONSTANT(ERROR_SUCCESS),
INT_CONSTANT(ERROR_INVALID_HANDLE),
INT_CONSTANT(ERROR_ACCESS_DENIED),
INT_CONSTANT(ERROR_DIR_NOT_EMPTY),
@ -746,6 +747,7 @@ static const dom::ConstantSpec gWinProperties[] =
INT_CONSTANT(ERROR_NO_MORE_FILES),
INT_CONSTANT(ERROR_PATH_NOT_FOUND),
INT_CONSTANT(ERROR_BAD_ARGUMENTS),
INT_CONSTANT(ERROR_SHARING_VIOLATION),
INT_CONSTANT(ERROR_NOT_SUPPORTED),
PROP_END

Просмотреть файл

@ -3,7 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/telephony/TelephonyChild.h"
#include "TelephonyChild.h"
#include "TelephonyIPCProvider.h"
USING_TELEPHONY_NAMESPACE
@ -11,16 +12,23 @@ USING_TELEPHONY_NAMESPACE
* TelephonyChild
******************************************************************************/
TelephonyChild::TelephonyChild(nsITelephonyListener* aListener)
: mListener(aListener)
TelephonyChild::TelephonyChild(TelephonyIPCProvider* aProvider)
: mProvider(aProvider)
{
MOZ_ASSERT(aProvider);
}
TelephonyChild::~TelephonyChild()
{
MOZ_ASSERT(aListener);
}
void
TelephonyChild::ActorDestroy(ActorDestroyReason aWhy)
{
mListener = nullptr;
if (mProvider) {
mProvider->NoteActorDestroyed();
mProvider = nullptr;
}
}
PTelephonyRequestChild*
@ -41,9 +49,9 @@ TelephonyChild::RecvNotifyCallError(const uint32_t& aClientId,
const int32_t& aCallIndex,
const nsString& aError)
{
MOZ_ASSERT(mListener);
MOZ_ASSERT(mProvider);
mListener->NotifyError(aClientId, aCallIndex, aError);
mProvider->NotifyError(aClientId, aCallIndex, aError);
return true;
}
@ -51,9 +59,9 @@ bool
TelephonyChild::RecvNotifyCallStateChanged(const uint32_t& aClientId,
const IPCCallStateData& aData)
{
MOZ_ASSERT(mListener);
MOZ_ASSERT(mProvider);
mListener->CallStateChanged(aClientId,
mProvider->CallStateChanged(aClientId,
aData.callIndex(),
aData.callState(),
aData.number(),
@ -70,18 +78,18 @@ bool
TelephonyChild::RecvNotifyCdmaCallWaiting(const uint32_t& aClientId,
const nsString& aNumber)
{
MOZ_ASSERT(mListener);
MOZ_ASSERT(mProvider);
mListener->NotifyCdmaCallWaiting(aClientId, aNumber);
mProvider->NotifyCdmaCallWaiting(aClientId, aNumber);
return true;
}
bool
TelephonyChild::RecvNotifyConferenceCallStateChanged(const uint16_t& aCallState)
{
MOZ_ASSERT(mListener);
MOZ_ASSERT(mProvider);
mListener->ConferenceCallStateChanged(aCallState);
mProvider->ConferenceCallStateChanged(aCallState);
return true;
}
@ -89,9 +97,9 @@ bool
TelephonyChild::RecvNotifyConferenceError(const nsString& aName,
const nsString& aMessage)
{
MOZ_ASSERT(mListener);
MOZ_ASSERT(mProvider);
mListener->NotifyConferenceError(aName, aMessage);
mProvider->NotifyConferenceError(aName, aMessage);
return true;
}
@ -100,9 +108,9 @@ TelephonyChild::RecvNotifySupplementaryService(const uint32_t& aClientId,
const int32_t& aCallIndex,
const uint16_t& aNotification)
{
MOZ_ASSERT(mListener);
MOZ_ASSERT(mProvider);
mListener->SupplementaryServiceNotification(aClientId, aCallIndex,
mProvider->SupplementaryServiceNotification(aClientId, aCallIndex,
aNotification);
return true;
}

Просмотреть файл

@ -13,13 +13,15 @@
BEGIN_TELEPHONY_NAMESPACE
class TelephonyIPCProvider;
class TelephonyChild : public PTelephonyChild
{
public:
TelephonyChild(nsITelephonyListener* aListener);
TelephonyChild(TelephonyIPCProvider* aProvider);
protected:
virtual ~TelephonyChild() {}
virtual ~TelephonyChild();
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
@ -55,7 +57,7 @@ protected:
const uint16_t& aNotification) MOZ_OVERRIDE;
private:
nsCOMPtr<nsITelephonyListener> mListener;
nsRefPtr<TelephonyIPCProvider> mProvider;
};
class TelephonyRequestChild : public PTelephonyRequestChild

Просмотреть файл

@ -3,7 +3,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ipc/TelephonyIPCProvider.h"
#include "TelephonyIPCProvider.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/telephony/TelephonyChild.h"
@ -53,7 +53,17 @@ TelephonyIPCProvider::TelephonyIPCProvider()
TelephonyIPCProvider::~TelephonyIPCProvider()
{
mPTelephonyChild->Send__delete__(mPTelephonyChild);
if (mPTelephonyChild) {
mPTelephonyChild->Send__delete__(mPTelephonyChild);
mPTelephonyChild = nullptr;
}
}
void
TelephonyIPCProvider::NoteActorDestroyed()
{
MOZ_ASSERT(mPTelephonyChild);
mPTelephonyChild = nullptr;
}
@ -94,6 +104,11 @@ TelephonyIPCProvider::RegisterListener(nsITelephonyListener *aListener)
{
MOZ_ASSERT(!mListeners.Contains(aListener));
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
// nsTArray doesn't fail.
mListeners.AppendElement(aListener);
@ -108,6 +123,11 @@ TelephonyIPCProvider::UnregisterListener(nsITelephonyListener *aListener)
{
MOZ_ASSERT(mListeners.Contains(aListener));
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
// We always have the element here, so it can't fail.
mListeners.RemoveElement(aListener);
@ -122,6 +142,11 @@ TelephonyIPCProvider::SendRequest(nsITelephonyListener *aListener,
nsITelephonyCallback *aCallback,
const IPCTelephonyRequest& aRequest)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
// Life time of newly allocated TelephonyRequestChild instance is managed by
// IPDL itself.
TelephonyRequestChild* actor = new TelephonyRequestChild(aListener, aCallback);
@ -146,6 +171,11 @@ TelephonyIPCProvider::Dial(uint32_t aClientId, const nsAString& aNumber,
NS_IMETHODIMP
TelephonyIPCProvider::HangUp(uint32_t aClientId, uint32_t aCallIndex)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendHangUpCall(aClientId, aCallIndex);
return NS_OK;
}
@ -153,6 +183,11 @@ TelephonyIPCProvider::HangUp(uint32_t aClientId, uint32_t aCallIndex)
NS_IMETHODIMP
TelephonyIPCProvider::AnswerCall(uint32_t aClientId, uint32_t aCallIndex)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendAnswerCall(aClientId, aCallIndex);
return NS_OK;
}
@ -160,6 +195,11 @@ TelephonyIPCProvider::AnswerCall(uint32_t aClientId, uint32_t aCallIndex)
NS_IMETHODIMP
TelephonyIPCProvider::RejectCall(uint32_t aClientId, uint32_t aCallIndex)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendRejectCall(aClientId, aCallIndex);
return NS_OK;
}
@ -167,6 +207,11 @@ TelephonyIPCProvider::RejectCall(uint32_t aClientId, uint32_t aCallIndex)
NS_IMETHODIMP
TelephonyIPCProvider::HoldCall(uint32_t aClientId, uint32_t aCallIndex)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendHoldCall(aClientId, aCallIndex);
return NS_OK;
}
@ -174,6 +219,11 @@ TelephonyIPCProvider::HoldCall(uint32_t aClientId, uint32_t aCallIndex)
NS_IMETHODIMP
TelephonyIPCProvider::ResumeCall(uint32_t aClientId, uint32_t aCallIndex)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendResumeCall(aClientId, aCallIndex);
return NS_OK;
}
@ -181,6 +231,11 @@ TelephonyIPCProvider::ResumeCall(uint32_t aClientId, uint32_t aCallIndex)
NS_IMETHODIMP
TelephonyIPCProvider::ConferenceCall(uint32_t aClientId)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendConferenceCall(aClientId);
return NS_OK;
}
@ -188,6 +243,11 @@ TelephonyIPCProvider::ConferenceCall(uint32_t aClientId)
NS_IMETHODIMP
TelephonyIPCProvider::SeparateCall(uint32_t aClientId, uint32_t aCallIndex)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendSeparateCall(aClientId, aCallIndex);
return NS_OK;
}
@ -195,6 +255,11 @@ TelephonyIPCProvider::SeparateCall(uint32_t aClientId, uint32_t aCallIndex)
NS_IMETHODIMP
TelephonyIPCProvider::HoldConference(uint32_t aClientId)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendHoldConference(aClientId);
return NS_OK;
}
@ -202,6 +267,11 @@ TelephonyIPCProvider::HoldConference(uint32_t aClientId)
NS_IMETHODIMP
TelephonyIPCProvider::ResumeConference(uint32_t aClientId)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendResumeConference(aClientId);
return NS_OK;
}
@ -209,6 +279,11 @@ TelephonyIPCProvider::ResumeConference(uint32_t aClientId)
NS_IMETHODIMP
TelephonyIPCProvider::StartTone(uint32_t aClientId, const nsAString& aDtmfChar)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendStartTone(aClientId, nsString(aDtmfChar));
return NS_OK;
}
@ -216,6 +291,11 @@ TelephonyIPCProvider::StartTone(uint32_t aClientId, const nsAString& aDtmfChar)
NS_IMETHODIMP
TelephonyIPCProvider::StopTone(uint32_t aClientId)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendStopTone(aClientId);
return NS_OK;
}
@ -223,6 +303,11 @@ TelephonyIPCProvider::StopTone(uint32_t aClientId)
NS_IMETHODIMP
TelephonyIPCProvider::GetMicrophoneMuted(bool* aMuted)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendGetMicrophoneMuted(aMuted);
return NS_OK;
}
@ -230,6 +315,11 @@ TelephonyIPCProvider::GetMicrophoneMuted(bool* aMuted)
NS_IMETHODIMP
TelephonyIPCProvider::SetMicrophoneMuted(bool aMuted)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendSetMicrophoneMuted(aMuted);
return NS_OK;
}
@ -237,6 +327,11 @@ TelephonyIPCProvider::SetMicrophoneMuted(bool aMuted)
NS_IMETHODIMP
TelephonyIPCProvider::GetSpeakerEnabled(bool* aEnabled)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendGetSpeakerEnabled(aEnabled);
return NS_OK;
}
@ -244,6 +339,11 @@ TelephonyIPCProvider::GetSpeakerEnabled(bool* aEnabled)
NS_IMETHODIMP
TelephonyIPCProvider::SetSpeakerEnabled(bool aEnabled)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyProvider used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendSetSpeakerEnabled(aEnabled);
return NS_OK;
}

Просмотреть файл

@ -28,10 +28,11 @@ public:
TelephonyIPCProvider();
protected:
virtual ~TelephonyIPCProvider();
void NoteActorDestroyed();
private:
~TelephonyIPCProvider();
nsTArray<nsCOMPtr<nsITelephonyListener> > mListeners;
PTelephonyChild* mPTelephonyChild;
uint32_t mDefaultServiceId;

Просмотреть файл

@ -6,6 +6,8 @@
#include "nsMimeTypes.h"
#include "Image.h"
#include "nsRefreshDriver.h"
#include "mozilla/TimeStamp.h"
namespace mozilla {
namespace image {
@ -128,6 +130,26 @@ ImageResource::SetAnimationModeInternal(uint16_t aAnimationMode)
return NS_OK;
}
bool
ImageResource::HadRecentRefresh(const TimeStamp& aTime)
{
// Our threshold for "recent" is 1/2 of the default refresh-driver interval.
// This ensures that we allow for frame rates at least as fast as the
// refresh driver's default rate.
static TimeDuration recentThreshold =
TimeDuration::FromMilliseconds(nsRefreshDriver::DefaultInterval() / 2.0);
if (!mLastRefreshTime.IsNull() &&
aTime - mLastRefreshTime < recentThreshold) {
return true;
}
// else, we can proceed with a refresh.
// But first, update our last refresh time:
mLastRefreshTime = aTime;
return false;
}
void
ImageResource::EvaluateAnimation()
{

Просмотреть файл

@ -186,6 +186,17 @@ protected:
nsresult GetAnimationModeInternal(uint16_t *aAnimationMode);
nsresult SetAnimationModeInternal(uint16_t aAnimationMode);
/**
* Helper for RequestRefresh.
*
* If we've had a "recent" refresh (i.e. if this image is being used in
* multiple documents & some other document *just* called RequestRefresh() on
* this image with a timestamp close to aTime), this method returns true.
*
* Otherwise, this method updates mLastRefreshTime to aTime & returns false.
*/
bool HadRecentRefresh(const mozilla::TimeStamp& aTime);
/**
* Decides whether animation should or should not be happening,
* and makes sure the right thing is being done.
@ -206,6 +217,7 @@ protected:
// Member data shared by all implementations of this abstract class
nsRefPtr<imgStatusTracker> mStatusTracker;
nsRefPtr<ImageURL> mURI;
TimeStamp mLastRefreshTime;
uint64_t mInnerWindowId;
uint32_t mAnimationConsumers;
uint16_t mAnimationMode; // Enum values in imgIContainer

Просмотреть файл

@ -543,6 +543,10 @@ RasterImage::Init(const char* aMimeType,
NS_IMETHODIMP_(void)
RasterImage::RequestRefresh(const mozilla::TimeStamp& aTime)
{
if (HadRecentRefresh(aTime)) {
return;
}
EvaluateAnimation();
if (!mAnimating) {

Просмотреть файл

@ -527,6 +527,10 @@ VectorImage::GetWidth(int32_t* aWidth)
NS_IMETHODIMP_(void)
VectorImage::RequestRefresh(const mozilla::TimeStamp& aTime)
{
if (HadRecentRefresh(aTime)) {
return;
}
EvaluateAnimation();
mSVGDocumentWrapper->TickRefreshDriver();

Просмотреть файл

@ -47,6 +47,8 @@ class TestActorPunningPunnedParent :
public:
TestActorPunningPunnedParent() {}
virtual ~TestActorPunningPunnedParent() {}
protected:
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
};
class TestActorPunningSubParent :
@ -55,6 +57,8 @@ class TestActorPunningSubParent :
public:
TestActorPunningSubParent() {}
virtual ~TestActorPunningSubParent() {}
protected:
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
};

Просмотреть файл

@ -51,6 +51,7 @@ public:
virtual ~TestBadActorSubParent() { }
protected:
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
virtual bool RecvPing();
};

Просмотреть файл

@ -80,8 +80,8 @@ public:
virtual ~TestDescSubParent() { }
protected:
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
virtual PTestDescSubsubParent* AllocPTestDescSubsubParent() MOZ_OVERRIDE;
virtual bool DeallocPTestDescSubsubParent(PTestDescSubsubParent* actor) MOZ_OVERRIDE;
};
@ -108,6 +108,9 @@ class TestDescSubsubParent :
public:
TestDescSubsubParent() { }
virtual ~TestDescSubsubParent() { }
protected:
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
};
class TestDescSubsubChild :

Просмотреть файл

@ -18,6 +18,9 @@ class TestHandleParent :
public:
TestHandleParent() { }
virtual ~TestHandleParent() { }
protected:
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
};
class TestJSONParent :

Просмотреть файл

@ -72,6 +72,7 @@ public:
virtual ~TestManyChildAllocsSubParent() { }
protected:
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
virtual bool RecvHello() MOZ_OVERRIDE { return true; }
};

Просмотреть файл

@ -25,6 +25,9 @@ class TestMultiMgrsBottomParent :
public:
TestMultiMgrsBottomParent() { }
virtual ~TestMultiMgrsBottomParent() { }
protected:
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
};
class TestMultiMgrsLeftParent :
@ -40,6 +43,8 @@ public:
}
protected:
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
virtual PTestMultiMgrsBottomParent* AllocPTestMultiMgrsBottomParent() MOZ_OVERRIDE
{
return new TestMultiMgrsBottomParent();
@ -65,6 +70,8 @@ public:
}
protected:
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
virtual PTestMultiMgrsBottomParent* AllocPTestMultiMgrsBottomParent() MOZ_OVERRIDE
{
return new TestMultiMgrsBottomParent();

Просмотреть файл

@ -9,6 +9,7 @@
#include "mozilla/DebugOnly.h"
#include "jit/IonLinker.h"
#include "jit/PerfSpewer.h"
#include "jit/IonFrames-inl.h"
#include "vm/Stack-inl.h"

Просмотреть файл

@ -5688,6 +5688,9 @@ TryAttachGlobalNameStub(JSContext *cx, HandleScript script, jsbytecode *pc,
return true;
}
// Try to add a getter stub. We don't handle scripted getters yet; if this
// changes we need to make sure IonBuilder::getPropTryCommonGetter (which
// requires a Baseline stub) handles non-outerized this objects correctly.
bool isScripted;
if (IsCacheableGetPropCall(cx, global, global, shape, &isScripted) && !isScripted)
{
@ -5741,6 +5744,10 @@ TryAttachScopeNameStub(JSContext *cx, HandleScript script, ICGetName_Fallback *s
scopeChain = scopeChain->enclosingScope();
}
// We don't handle getters here. When this changes, we need to make sure
// IonBuilder::getPropTryCommonGetter (which requires a Baseline stub to
// work) handles non-outerized this objects correctly.
if (!IsCacheableGetPropReadSlot(scopeChain, scopeChain, shape))
return true;

Просмотреть файл

@ -8605,6 +8605,10 @@ IonBuilder::jsop_getprop(PropertyName *name)
if (!getPropTryInlineAccess(&emitted, obj, name, barrier, types) || emitted)
return emitted;
// Try to optimize accesses on outer window proxies, for example window.foo.
if (!getPropTryInnerize(&emitted, obj, name, types) || emitted)
return emitted;
// Try to emit a polymorphic cache.
if (!getPropTryCache(&emitted, obj, name, barrier, types) || emitted)
return emitted;
@ -9074,6 +9078,79 @@ IonBuilder::getPropTryCache(bool *emitted, MDefinition *obj, PropertyName *name,
return true;
}
MDefinition *
IonBuilder::tryInnerizeWindow(MDefinition *obj)
{
// Try to optimize accesses on outer window proxies (window.foo, for
// example) to go directly to the inner window, the global.
//
// Callers should be careful not to pass the inner object to getters or
// setters that require outerization.
if (obj->type() != MIRType_Object)
return obj;
types::TemporaryTypeSet *types = obj->resultTypeSet();
if (!types)
return obj;
JSObject *singleton = types->getSingleton();
if (!singleton)
return obj;
JSObject *inner = GetInnerObject(singleton);
if (inner == singleton || inner != &script()->global())
return obj;
// When we navigate, the outer object is brain transplanted and we'll mark
// its TypeObject as having unknown properties. The type constraint we add
// here will invalidate JIT code when this happens.
types::TypeObjectKey *objType = types::TypeObjectKey::get(singleton);
if (objType->hasFlags(constraints(), types::OBJECT_FLAG_UNKNOWN_PROPERTIES))
return obj;
obj->setImplicitlyUsedUnchecked();
return constant(ObjectValue(script()->global()));
}
bool
IonBuilder::getPropTryInnerize(bool *emitted, MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *types)
{
// See the comment in tryInnerizeWindow for how this works.
MOZ_ASSERT(*emitted == false);
MDefinition *inner = tryInnerizeWindow(obj);
if (inner == obj)
return true;
// Note: the Baseline ICs don't know about this optimization, so it's
// possible the global property's HeapTypeSet has not been initialized
// yet. In this case we'll fall back to getPropTryCache for now.
//
// Also note that we don't call getPropTryCommonGetter below, because
// (a) it requires a Baseline getter stub, which we don't have for outer
// window proxies and (b) we have to be careful not to pass the inner
// object to scripted getters etc. See bug 1007631.
if (!getPropTryConstant(emitted, inner, name, types) || *emitted)
return *emitted;
if (!getStaticName(&script()->global(), name, emitted) || *emitted)
return *emitted;
// Passing the inner object to GetProperty IC is safe, see the
// needsOuterizedThisObject check in IsCacheableGetPropCallNative.
BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
inner, name, types);
if (!getPropTryCache(emitted, inner, name, barrier, types) || *emitted)
return *emitted;
MOZ_ASSERT(*emitted == false);
return true;
}
bool
IonBuilder::needsToMonitorMissingProperties(types::TemporaryTypeSet *types)
{

Просмотреть файл

@ -397,6 +397,8 @@ class IonBuilder : public MIRGenerator
bool storeSlot(MDefinition *obj, Shape *shape, MDefinition *value, bool needsBarrier,
MIRType slotType = MIRType_None);
MDefinition *tryInnerizeWindow(MDefinition *obj);
// jsop_getprop() helpers.
bool getPropTryArgumentsLength(bool *emitted, MDefinition *obj);
bool getPropTryConstant(bool *emitted, MDefinition *obj, PropertyName *name,
@ -418,6 +420,8 @@ class IonBuilder : public MIRGenerator
TypeDescrSet fieldTypeReprs,
size_t fieldIndex,
types::TemporaryTypeSet *resultTypes);
bool getPropTryInnerize(bool *emitted, MDefinition *obj, PropertyName *name,
types::TemporaryTypeSet *types);
bool getPropTryCache(bool *emitted, MDefinition *obj, PropertyName *name,
BarrierKind barrier, types::TemporaryTypeSet *types);
bool needsToMonitorMissingProperties(types::TemporaryTypeSet *types);

Просмотреть файл

@ -1161,6 +1161,12 @@ CanAttachNativeGetProp(typename GetPropCache::Context cx, const GetPropCache &ca
// IonBuilder guarantees that it's impossible to generate a GetPropertyIC with
// allowGetters() true and cache.output().hasValue() false. If this isn't true,
// we will quickly assert during stub generation.
//
// Be careful when adding support for other getters here: for outer window
// proxies, IonBuilder can innerize and pass us the inner window (the global),
// see IonBuilder::getPropTryInnerize. This is fine for native getters because
// IsCacheableGetPropCallNative checks they can handle both the inner and
// outer object, but scripted getters would need a similar mechanism.
if (cache.allowGetters() &&
(IsCacheableGetPropCallNative(obj, holder, shape) ||
IsCacheableGetPropCallPropertyOp(obj, holder, shape)))

Просмотреть файл

@ -1238,6 +1238,18 @@ MarkJitActivations(JSRuntime *rt, JSTracer *trc)
MarkJitActivation(trc, activations);
}
JSCompartment *
TopmostIonActivationCompartment(JSRuntime *rt)
{
for (JitActivationIterator activations(rt); !activations.done(); ++activations) {
for (JitFrameIterator frames(activations); !frames.done(); ++frames) {
if (frames.type() == JitFrame_IonJS)
return activations.activation()->compartment();
}
}
return nullptr;
}
#ifdef JSGC_GENERATIONAL
void
UpdateJitActivationsForMinorGC(JSRuntime *rt, JSTracer *trc)

Просмотреть файл

@ -268,6 +268,9 @@ void EnsureExitFrame(IonCommonFrameLayout *frame);
void MarkJitActivations(JSRuntime *rt, JSTracer *trc);
void MarkIonCompilerRoots(JSTracer *trc);
JSCompartment *
TopmostIonActivationCompartment(JSRuntime *rt);
#ifdef JSGC_GENERATIONAL
void UpdateJitActivationsForMinorGC(JSRuntime *rt, JSTracer *trc);
#endif

Просмотреть файл

@ -292,6 +292,11 @@ MDefinition::dump(FILE *fp) const
fprintf(fp, " = ");
printOpcode(fp);
fprintf(fp, "\n");
if (isInstruction()) {
if (MResumePoint *resume = toInstruction()->resumePoint())
resume->dump(fp);
}
}
void
@ -2306,6 +2311,41 @@ MResumePoint::inherit(MBasicBlock *block)
}
}
void MResumePoint::dump(FILE *fp) const
{
fprintf(fp, "resumepoint mode=");
switch (mode()) {
case MResumePoint::ResumeAt:
fprintf(fp, "At");
break;
case MResumePoint::ResumeAfter:
fprintf(fp, "After");
break;
case MResumePoint::Outer:
fprintf(fp, "Outer");
break;
}
if (MResumePoint *c = caller())
fprintf(fp, " (caller in block%u)", c->block()->id());
for (size_t i = 0; i < numOperands(); i++) {
fprintf(fp, " ");
if (operands_[i].hasProducer())
getOperand(i)->printName(fp);
else
fprintf(fp, "(null)");
}
fprintf(fp, "\n");
}
void
MResumePoint::dump() const
{
dump(stderr);
}
MDefinition *
MToInt32::foldsTo(TempAllocator &alloc, bool useValueNumbers)
{

Просмотреть файл

@ -217,6 +217,9 @@ class MNode : public TempObject
virtual bool writeRecoverData(CompactBufferWriter &writer) const;
virtual void dump(FILE *fp) const = 0;
virtual void dump() const = 0;
protected:
// Sets an unset operand, updating use information.
virtual void setOperand(size_t index, MDefinition *operand) = 0;
@ -613,6 +616,7 @@ class MDefinition : public MNode
# undef OPCODE_CASTS
inline MInstruction *toInstruction();
inline const MInstruction *toInstruction() const;
bool isInstruction() const {
return !isPhi();
}
@ -9669,7 +9673,7 @@ class MResumePoint MOZ_FINAL : public MNode, public InlineForwardListNode<MResum
uint32_t stackDepth() const {
return stackDepth_;
}
MResumePoint *caller() {
MResumePoint *caller() const {
return caller_;
}
void setCaller(MResumePoint *caller) {
@ -9699,6 +9703,9 @@ class MResumePoint MOZ_FINAL : public MNode, public InlineForwardListNode<MResum
}
bool writeRecoverData(CompactBufferWriter &writer) const;
virtual void dump(FILE *fp) const;
virtual void dump() const;
};
class MIsCallable
@ -10206,6 +10213,12 @@ MInstruction *MDefinition::toInstruction()
return (MInstruction *)this;
}
const MInstruction *MDefinition::toInstruction() const
{
JS_ASSERT(!isPhi());
return (const MInstruction *)this;
}
typedef Vector<MDefinition *, 8, IonAllocPolicy> MDefinitionVector;
// Helper functions used to decide how to build MIR.

Просмотреть файл

@ -1278,6 +1278,9 @@ void
MBasicBlock::dump(FILE *fp)
{
#ifdef DEBUG
if (MResumePoint *resume = entryResumePoint()) {
resume->dump();
}
for (MPhiIterator iter(phisBegin()); iter != phisEnd(); iter++) {
iter->dump(fp);
}

Просмотреть файл

@ -2828,6 +2828,13 @@ BeginMarkPhase(JSRuntime *rt)
c->zone()->setPreservingCode(true);
}
if (!rt->gc.shouldCleanUpEverything) {
#ifdef JS_ION
if (JSCompartment *comp = jit::TopmostIonActivationCompartment(rt))
comp->zone()->setPreservingCode(true);
#endif
}
/*
* Atoms are not in the cross-compartment map. So if there are any
* zones that are not being collected, we are not allowed to collect

Просмотреть файл

@ -1394,7 +1394,7 @@ nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup,
// Otherwise, always show the transition.
if (!animate.EqualsLiteral("false") &&
(!animate.EqualsLiteral("cancel") || aIsRollup)) {
nsCOMPtr<TransitionEnder> ender = new TransitionEnder(aPopup, aDeselectMenu);
nsRefPtr<TransitionEnder> ender = new TransitionEnder(aPopup, aDeselectMenu);
aPopup->AddSystemEventListener(NS_LITERAL_STRING("transitionend"),
ender, false, false);
return;

Просмотреть файл

@ -4123,4 +4123,4 @@ pref("beacon.enabled", true);
// Camera prefs
pref("camera.control.autofocus_moving_callback.enabled", false);
pref("camera.control.face_detection.enabled", false);
pref("camera.control.face_detection.enabled", true);

Просмотреть файл

@ -377,8 +377,7 @@ nsAsyncStreamCopier::AsyncCopy(nsIRequestObserver *observer, nsISupports *ctx)
if (NS_IsMainThread()) {
// Don't perform buffer sniffing on the main thread
nsCOMPtr<AsyncApplyBufferingPolicyEvent> event
= new AsyncApplyBufferingPolicyEvent(this);
nsCOMPtr<nsIRunnable> event = new AsyncApplyBufferingPolicyEvent(this);
rv = mTarget->Dispatch(event, NS_DISPATCH_NORMAL);
if (NS_FAILED(rv)) {
Cancel(rv);

Просмотреть файл

@ -171,7 +171,7 @@ nsAboutCache::VisitNextStorage()
// from visitor callback. The cache v1 service doesn't like it.
// TODO - mayhemer, bug 913828, remove this dispatch and call
// directly.
nsCOMPtr<nsRunnableMethod<nsAboutCache> > event =
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethod(this, &nsAboutCache::FireVisitStorage);
return NS_DispatchToMainThread(event);
}

Просмотреть файл

@ -322,7 +322,7 @@ main(int32_t argc, char *argv[])
if (NS_WARN_IF(!timer)) {
return -1;
}
nsCOMPtr<MulticastTimerCallback> timerCb = new MulticastTimerCallback();
nsRefPtr<MulticastTimerCallback> timerCb = new MulticastTimerCallback();
// The following multicast tests using multiple sockets require a firewall
// exception on Windows XP before they pass. For now, we'll skip them here.

Просмотреть файл

@ -250,6 +250,17 @@ this.FxAccountsManager = {
return this._signOut();
},
resendVerificationEmail: function() {
return this._fxAccounts.resendVerificationEmail().then(
(result) => {
return result;
},
(error) => {
return this._error(ERROR_SERVER_ERROR, error);
}
);
},
getAccount: function() {
// We check first if we have session details cached.
if (this._activeSession) {

Просмотреть файл

@ -122,6 +122,15 @@ FxAccountsManager._fxAccounts = {
return deferred.promise;
},
resendVerificationEmail: function() {
return this.getSignedInUser().then(data => {
if (data) {
return Promise.resolve(true);
}
throw new Error("Cannot resend verification email; no signed-in user");
});
},
setSignedInUser: function(user) {
this._setSignedInUserCalled = true;
let deferred = Promise.defer();
@ -580,6 +589,33 @@ add_test(function(test_signIn_already_signed_user) {
);
});
add_test(function(test_resendVerificationEmail_error_handling) {
do_print("= resendVerificationEmail smoke test =");
let user = FxAccountsManager._fxAccounts._signedInUser;
FxAccountsManager._fxAccounts._signedInUser.verified = false;
FxAccountsManager.resendVerificationEmail().then(
(success) => {
do_check_true(success);
},
(error) => {
do_throw("Unexpected failure");
}
);
// Here we verify that when FxAccounts.resendVerificationEmail
// throws an error, we gracefully handle it in the reject() channel.
FxAccountsManager._fxAccounts._signedInUser = null;
FxAccountsManager.resendVerificationEmail().then(
(success) => {
do_throw("Unexpected success");
},
(error) => {
do_check_eq(error.error, ERROR_SERVER_ERROR);
}
);
FxAccountsManager._fxAccounts._signedInUser = user;
run_next_test();
});
add_test(function(test_verificationStatus_unverified_session_unverified_user) {
do_print("= verificationStatus unverified session and user =");
FakeFxAccountsClient._verified = false;

Просмотреть файл

@ -190,7 +190,8 @@ class MochitestRunner(MozbuildObject):
jsdebugger=False, debug_on_failure=False, start_at=None, end_at=None,
e10s=False, dmd=False, dump_output_directory=None,
dump_about_memory_after_test=False, dump_dmd_after_test=False,
install_extension=None, quiet=False, environment=[], app_override=None, **kwargs):
install_extension=None, quiet=False, environment=[], app_override=None,
useTestMediaDevices=False, **kwargs):
"""Runs a mochitest.
test_paths are path to tests. They can be a relative path from the
@ -315,6 +316,7 @@ class MochitestRunner(MozbuildObject):
options.dumpOutputDirectory = dump_output_directory
options.quiet = quiet
options.environment = environment
options.useTestMediaDevices = useTestMediaDevices
options.failureFile = failure_file_path
if install_extension != None:
@ -526,6 +528,12 @@ def MochitestCommand(func):
help="Sets the given variable in the application's environment")
func = setenv(func)
test_media = CommandArgument('--use-test-media-devices', default=False,
action='store_true',
dest='useTestMediaDevices',
help='Use test media device drivers for media testing.')
func = test_media(func)
app_override = CommandArgument('--app-override', default=None, action='store',
help="Override the default binary used to run tests with the path you provide, e.g. " \
" --app-override /usr/bin/firefox . " \

Просмотреть файл

@ -416,6 +416,12 @@ class MochitestOptions(optparse.OptionParser):
"help": "name of the pidfile to generate",
"default": "",
}],
[["--use-test-media-devices"],
{ "action": "store_true",
"default": False,
"dest": "useTestMediaDevices",
"help": "Use test media device drivers for media testing.",
}],
]
def __init__(self, **kwargs):
@ -574,6 +580,13 @@ class MochitestOptions(optparse.OptionParser):
self.error('--dump-output-directory not a directory: %s' %
options.dumpOutputDirectory)
if options.useTestMediaDevices:
if not mozinfo.isLinux:
self.error('--use-test-media-devices is only supported on Linux currently')
for f in ['/usr/bin/gst-launch-0.10', '/usr/bin/pactl']:
if not os.path.isfile(f):
self.error('Missing binary %s required for --use-test-media-devices')
return options

Просмотреть файл

@ -12,6 +12,7 @@ import sys
SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
sys.path.insert(0, SCRIPT_DIR);
import ctypes
import glob
import json
import mozcrash
@ -754,11 +755,123 @@ class SSLTunnel:
if os.path.exists(self.configFile):
os.remove(self.configFile)
def checkAndConfigureV4l2loopback(device):
'''
Determine if a given device path is a v4l2loopback device, and if so
toggle a few settings on it via fcntl. Very linux-specific.
Returns (status, device name) where status is a boolean.
'''
if not mozinfo.isLinux:
return False, ''
libc = ctypes.cdll.LoadLibrary('libc.so.6')
O_RDWR = 2
# These are from linux/videodev2.h
class v4l2_capability(ctypes.Structure):
_fields_ = [
('driver', ctypes.c_char * 16),
('card', ctypes.c_char * 32),
('bus_info', ctypes.c_char * 32),
('version', ctypes.c_uint32),
('capabilities', ctypes.c_uint32),
('device_caps', ctypes.c_uint32),
('reserved', ctypes.c_uint32 * 3)
]
VIDIOC_QUERYCAP = 0x80685600
fd = libc.open(device, O_RDWR)
if fd < 0:
return False, ''
vcap = v4l2_capability()
if libc.ioctl(fd, VIDIOC_QUERYCAP, ctypes.byref(vcap)) != 0:
return False, ''
if vcap.driver != 'v4l2 loopback':
return False, ''
class v4l2_control(ctypes.Structure):
_fields_ = [
('id', ctypes.c_uint32),
('value', ctypes.c_int32)
]
# These are private v4l2 control IDs, see:
# https://github.com/umlaeute/v4l2loopback/blob/fd822cf0faaccdf5f548cddd9a5a3dcebb6d584d/v4l2loopback.c#L131
KEEP_FORMAT = 0x8000000
SUSTAIN_FRAMERATE = 0x8000001
VIDIOC_S_CTRL = 0xc008561c
control = v4l2_control()
control.id = KEEP_FORMAT
control.value = 1
libc.ioctl(fd, VIDIOC_S_CTRL, ctypes.byref(control))
control.id = SUSTAIN_FRAMERATE
control.value = 1
libc.ioctl(fd, VIDIOC_S_CTRL, ctypes.byref(control))
libc.close(fd)
return True, vcap.card
def findTestMediaDevices():
'''
Find the test media devices configured on this system, and return a dict
containing information about them. The dict will have keys for 'audio'
and 'video', each containing the name of the media device to use.
If audio and video devices could not be found, return None.
This method is only currently implemented for Linux.
'''
if not mozinfo.isLinux:
return None
info = {}
# Look for a v4l2loopback device.
name = None
device = None
for dev in sorted(glob.glob('/dev/video*')):
result, name_ = checkAndConfigureV4l2loopback(dev)
if result:
name = name_
device = dev
break
if not (name and device):
log.error('Couldn\'t find a v4l2loopback video device')
return None
# Feed it a frame of output so it has something to display
subprocess.check_call(['/usr/bin/gst-launch-0.10', 'videotestsrc',
'pattern=green', 'num-buffers=1', '!',
'v4l2sink', 'device=%s' % device])
info['video'] = name
# Use pactl to see if the PulseAudio module-sine-source module is loaded.
def sine_source_loaded():
o = subprocess.check_output(['/usr/bin/pactl', 'list', 'short', 'modules'])
return filter(lambda x: 'module-sine-source' in x, o.splitlines())
if not sine_source_loaded():
# Load module-sine-source
subprocess.check_call(['/usr/bin/pactl', 'load-module',
'module-sine-source'])
if not sine_source_loaded():
log.error('Couldn\'t load module-sine-source')
return None
# Hardcode the name since it's always the same.
info['audio'] = 'Sine source at 440 Hz'
return info
class Mochitest(MochitestUtilsMixin):
certdbNew = False
sslTunnel = None
vmwareHelper = None
DEFAULT_TIMEOUT = 60.0
mediaDevices = None
# XXX use automation.py for test name to avoid breaking legacy
# TODO: replace this with 'runtests.py' or 'mochitest' or the like
@ -877,6 +990,11 @@ class Mochitest(MochitestUtilsMixin):
'ws': options.sslPort
}
# See if we should use fake media devices.
if options.useTestMediaDevices:
prefs['media.audio_loopback_dev'] = self.mediaDevices['audio']
prefs['media.video_loopback_dev'] = self.mediaDevices['video']
# create a profile
self.profile = Profile(profile=options.profilePath,
@ -1225,6 +1343,13 @@ class Mochitest(MochitestUtilsMixin):
options.debuggerArgs,
options.debuggerInteractive)
if options.useTestMediaDevices:
devices = findTestMediaDevices()
if not devices:
log.error("Could not find test media devices to use")
return 1
self.mediaDevices = devices
self.leak_report_file = os.path.join(options.profilePath, "runtests_leaks.log")
browserEnv = self.buildBrowserEnv(options, debuggerInfo is not None)

Просмотреть файл

@ -117,10 +117,22 @@ if (LINUX) {
yield OS.File.removeDir(profileDir.parent.parent.path, { ignoreAbsent: true });
}
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
let removed = false;
do {
try {
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
removed = true;
} catch (ex if ex instanceof OS.File.Error &&
(ex.winLastError == OS.Constants.Win.ERROR_SUCCESS ||
ex.winLastError == OS.Constants.Win.ERROR_SHARING_VIOLATION)) {
// Wait 100 ms before attempting to remove again.
yield wait(100);
}
} while (!removed);
});
};
} else if (MAC) {

Просмотреть файл

@ -117,10 +117,22 @@ if (LINUX) {
yield OS.File.removeDir(profileDir.parent.parent.path, { ignoreAbsent: true });
}
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
let removed = false;
do {
try {
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
removed = true;
} catch (ex if ex instanceof OS.File.Error &&
(ex.winLastError == OS.Constants.Win.ERROR_SUCCESS ||
ex.winLastError == OS.Constants.Win.ERROR_SHARING_VIOLATION)) {
// Wait 100 ms before attempting to remove again.
yield wait(100);
}
} while (!removed);
});
};
} else if (MAC) {

Просмотреть файл

@ -122,10 +122,22 @@ if (LINUX) {
yield OS.File.removeDir(profileDir.parent.parent.path, { ignoreAbsent: true });
}
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
let removed = false;
do {
try {
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
removed = true;
} catch (ex if ex instanceof OS.File.Error &&
(ex.winLastError == OS.Constants.Win.ERROR_SUCCESS ||
ex.winLastError == OS.Constants.Win.ERROR_SHARING_VIOLATION)) {
// Wait 100 ms before attempting to remove again.
yield wait(100);
}
} while (!removed);
});
};
} else if (MAC) {

Просмотреть файл

@ -127,10 +127,22 @@ if (LINUX) {
yield OS.File.removeDir(profileDir.parent.parent.path, { ignoreAbsent: true });
}
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
let removed = false;
do {
try {
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
removed = true;
} catch (ex if ex instanceof OS.File.Error &&
(ex.winLastError == OS.Constants.Win.ERROR_SUCCESS ||
ex.winLastError == OS.Constants.Win.ERROR_SHARING_VIOLATION)) {
// Wait 100 ms before attempting to remove again.
yield wait(100);
}
} while (!removed);
});
};
} else if (MAC) {

Просмотреть файл

@ -127,10 +127,22 @@ if (LINUX) {
yield OS.File.removeDir(profileDir.parent.parent.path, { ignoreAbsent: true });
}
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
let removed = false;
do {
try {
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
removed = true;
} catch (ex if ex instanceof OS.File.Error &&
(ex.winLastError == OS.Constants.Win.ERROR_SUCCESS ||
ex.winLastError == OS.Constants.Win.ERROR_SHARING_VIOLATION)) {
// Wait 100 ms before attempting to remove again.
yield wait(100);
}
} while (!removed);
});
};
} else if (MAC) {

Просмотреть файл

@ -135,10 +135,22 @@ if (LINUX) {
yield OS.File.removeDir(profileDir.parent.parent.path, { ignoreAbsent: true });
}
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
let removed = false;
do {
try {
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
removed = true;
} catch (ex if ex instanceof OS.File.Error &&
(ex.winLastError == OS.Constants.Win.ERROR_SUCCESS ||
ex.winLastError == OS.Constants.Win.ERROR_SHARING_VIOLATION)) {
// Wait 100 ms before attempting to remove again.
yield wait(100);
}
} while (!removed);
});
};
} else if (MAC) {

Просмотреть файл

@ -1243,6 +1243,8 @@ private:
void MarkRoots(SliceBudget &aBudget);
void ScanRoots(bool aFullySynchGraphBuild);
void ScanIncrementalRoots();
void ScanWhiteNodes(bool aFullySynchGraphBuild);
void ScanBlackNodes();
void ScanWeakMaps();
// returns whether anything was collected
@ -2680,50 +2682,6 @@ FloodBlackNode(uint32_t& aWhiteNodeCount, bool& aFailed, PtrInfo* aPi)
MOZ_ASSERT(aPi->mColor == black || !aPi->mParticipant, "FloodBlackNode should make aPi black");
}
struct scanVisitor
{
scanVisitor(uint32_t &aWhiteNodeCount, bool &aFailed, bool aWasIncremental)
: mWhiteNodeCount(aWhiteNodeCount), mFailed(aFailed),
mWasIncremental(aWasIncremental)
{
}
bool ShouldVisitNode(PtrInfo const *pi)
{
return pi->mColor == grey;
}
MOZ_NEVER_INLINE void VisitNode(PtrInfo *pi)
{
if (pi->mInternalRefs > pi->mRefCount && pi->mRefCount > 0) {
// If we found more references to an object than its ref count, then
// the object should have already been marked as an incremental
// root. Note that this is imprecise, because pi could have been
// marked black for other reasons. Always fault if we weren't
// incremental, as there were no incremental roots in that case.
if (!mWasIncremental || pi->mColor != black) {
Fault("traversed refs exceed refcount", pi);
}
}
if (pi->mInternalRefs == pi->mRefCount || pi->mRefCount == 0) {
pi->mColor = white;
++mWhiteNodeCount;
} else {
FloodBlackNode(mWhiteNodeCount, mFailed, pi);
}
}
void Failed() {
mFailed = true;
}
private:
uint32_t &mWhiteNodeCount;
bool &mFailed;
bool mWasIncremental;
};
// Iterate over the WeakMaps. If we mark anything while iterating
// over the WeakMaps, we must iterate over all of the WeakMaps again.
void
@ -2742,10 +2700,6 @@ nsCycleCollector::ScanWeakMaps()
uint32_t kdColor = wm->mKeyDelegate ? wm->mKeyDelegate->mColor : black;
uint32_t vColor = wm->mVal ? wm->mVal->mColor : black;
// All non-null weak mapping maps, keys and values are
// roots (in the sense of WalkFromRoots) in the cycle
// collector graph, and thus should have been colored
// either black or white in ScanRoots().
MOZ_ASSERT(mColor != grey, "Uncolored weak map");
MOZ_ASSERT(kColor != grey, "Uncolored weak map key");
MOZ_ASSERT(kdColor != grey, "Uncolored weak map key delegate");
@ -2895,6 +2849,68 @@ nsCycleCollector::ScanIncrementalRoots()
}
}
// Mark nodes white and make sure their refcounts are ok.
// No nodes are marked black during this pass to ensure that refcount
// checking is run on all nodes not marked black by ScanIncrementalRoots.
void
nsCycleCollector::ScanWhiteNodes(bool aFullySynchGraphBuild)
{
NodePool::Enumerator nodeEnum(mGraph.mNodes);
while (!nodeEnum.IsDone()) {
PtrInfo* pi = nodeEnum.GetNext();
if (pi->mColor == black) {
// Incremental roots can be in a nonsensical state, so don't
// check them. This will miss checking nodes that are merely
// reachable from incremental roots.
MOZ_ASSERT(!aFullySynchGraphBuild,
"In a synch CC, no nodes should be marked black early on.");
continue;
}
MOZ_ASSERT(pi->mColor == grey);
if (!pi->mParticipant) {
// This node has been deleted, so it could be in a mangled state, but
// that's okay because we're not going to look at it again.
continue;
}
if (pi->mInternalRefs == pi->mRefCount || pi->mRefCount == 0) {
pi->mColor = white;
++mWhiteNodeCount;
continue;
}
if (MOZ_LIKELY(pi->mInternalRefs < pi->mRefCount)) {
// This node will get marked black in the next pass.
continue;
}
Fault("Traversed refs exceed refcount", pi);
}
}
// Any remaining grey nodes that haven't already been deleted must be alive,
// so mark them and their children black. Any nodes that are black must have
// already had their children marked black, so there's no need to look at them
// again. This pass may turn some white nodes to black.
void
nsCycleCollector::ScanBlackNodes()
{
bool failed = false;
NodePool::Enumerator nodeEnum(mGraph.mNodes);
while (!nodeEnum.IsDone()) {
PtrInfo* pi = nodeEnum.GetNext();
if (pi->mColor == grey && pi->mParticipant) {
FloodBlackNode(mWhiteNodeCount, failed, pi);
}
}
if (failed) {
NS_ASSERTION(false, "Ran out of memory in ScanBlackNodes");
CC_TELEMETRY(_OOM, true);
}
}
void
nsCycleCollector::ScanRoots(bool aFullySynchGraphBuild)
{
@ -2909,19 +2925,11 @@ nsCycleCollector::ScanRoots(bool aFullySynchGraphBuild)
}
TimeLog timeLog;
ScanWhiteNodes(aFullySynchGraphBuild);
timeLog.Checkpoint("ScanRoots::ScanWhiteNodes");
// On the assumption that most nodes will be black, it's
// probably faster to use a GraphWalker than a
// NodePool::Enumerator.
bool failed = false;
scanVisitor sv(mWhiteNodeCount, failed, !aFullySynchGraphBuild);
GraphWalker<scanVisitor>(sv).WalkFromRoots(mGraph);
timeLog.Checkpoint("ScanRoots::WalkFromRoots");
if (failed) {
NS_ASSERTION(false, "Ran out of memory in ScanRoots");
CC_TELEMETRY(_OOM, true);
}
ScanBlackNodes();
timeLog.Checkpoint("ScanRoots::ScanBlackNodes");
// Scanning weak maps must be done last.
ScanWeakMaps();