Merge pull request #7 from classilla/master

merge from head
This commit is contained in:
Riccardo 2018-03-01 16:51:17 +01:00 committed by GitHub
commit 8413c728bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 3852 additions and 1540 deletions

View File

@ -1013,7 +1013,7 @@ pref("browser.sessionstore.resume_from_crash", true);
pref("browser.sessionstore.resume_session_once", false); pref("browser.sessionstore.resume_session_once", false);
// minimal interval between two save operations in milliseconds // minimal interval between two save operations in milliseconds
pref("browser.sessionstore.interval", 30000); pref("browser.sessionstore.interval", 60000);
// on which sites to save text data, POSTDATA and cookies // on which sites to save text data, POSTDATA and cookies
// 0 = everywhere, 1 = unencrypted sites, 2 = nowhere // 0 = everywhere, 1 = unencrypted sites, 2 = nowhere
pref("browser.sessionstore.privacy_level", 0); pref("browser.sessionstore.privacy_level", 0);

View File

@ -693,7 +693,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
if (mIsTenFourFoxAdBlockEnabled && if (mIsTenFourFoxAdBlockEnabled &&
(targetScheme.EqualsLiteral("http") || targetScheme.EqualsLiteral("https"))) { (targetScheme.EqualsLiteral("http") || targetScheme.EqualsLiteral("https"))) {
nsAutoCString hostname; nsAutoCString hostname;
if (NS_SUCCEEDED(targetBaseURI->GetHost(hostname))) { if (MOZ_LIKELY(NS_SUCCEEDED(targetBaseURI->GetHost(hostname)))) {
ToLowerCase(hostname); ToLowerCase(hostname);
#define BLOK(q) hostname.EqualsLiteral(q) #define BLOK(q) hostname.EqualsLiteral(q)
if (0 || if (0 ||
@ -786,6 +786,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
BLOK("cdn.viglink.com") || BLOK("cdn.viglink.com") ||
BLOK("xcp.go.sonobi.com") || BLOK("xcp.go.sonobi.com") ||
BLOK("apex.go.sonobi.com") ||
BLOK("s.ntv.io") || BLOK("s.ntv.io") ||
@ -826,6 +827,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
BLOK("cdn.engine.4dsply.com") || BLOK("cdn.engine.4dsply.com") ||
BLOK("as.casalemedia.com") ||
BLOK("as-sec.casalemedia.com") || BLOK("as-sec.casalemedia.com") ||
BLOK("loadm.exelator.com") || BLOK("loadm.exelator.com") ||
@ -899,6 +901,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
BLOK("sb.monetate.net") || BLOK("sb.monetate.net") ||
BLOK("se.monetate.net") || BLOK("se.monetate.net") ||
BLOK("ad.crwdcntrl.net") ||
BLOK("tags.crwdcntrl.net") || BLOK("tags.crwdcntrl.net") ||
BLOK("cdn.nsstatic.net") || BLOK("cdn.nsstatic.net") ||
@ -972,6 +975,28 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
BLOK("tags.mathtag.com") || BLOK("tags.mathtag.com") ||
BLOK("pixel.mathtag.com") || BLOK("pixel.mathtag.com") ||
BLOK("a.teads.tv") ||
BLOK("cdn.teads.tv") ||
BLOK("cdata.carambo.la") ||
BLOK("route.carambo.la") ||
BLOK("us-ads.openx.net") ||
BLOK("s-static.innovid.com") ||
// This is controversial, but I'm pretty sure we
// don't want this.
BLOK("coinhive.com") ||
BLOK("ustatik.com") ||
BLOK("cdn.ustatik.com") ||
BLOK("adx.adform.net") ||
BLOK("s.spoutable.com") ||
BLOK("cdn.spoutable.com") ||
0) { 0) {
#undef BLOK #undef BLOK
// Yup. // Yup.

View File

@ -4109,9 +4109,10 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent,
// content associated with our subdocument. // content associated with our subdocument.
EnsureDocument(mPresContext); EnsureDocument(mPresContext);
if (nsIDocument *parentDoc = mDocument->GetParentDocument()) { if (nsIDocument *parentDoc = mDocument->GetParentDocument()) {
if (nsIContent *docContent = parentDoc->FindContentForSubDocument(mDocument)) { if (nsCOMPtr<nsIContent> docContent =
parentDoc->FindContentForSubDocument(mDocument)) {
if (nsIPresShell *parentShell = parentDoc->GetShell()) { if (nsIPresShell *parentShell = parentDoc->GetShell()) {
EventStateManager* parentESM = RefPtr<EventStateManager> parentESM =
parentShell->GetPresContext()->EventStateManager(); parentShell->GetPresContext()->EventStateManager();
parentESM->NotifyMouseOver(aMouseEvent, docContent); parentESM->NotifyMouseOver(aMouseEvent, docContent);
} }

View File

@ -178,8 +178,8 @@ static int64_t DurationToUsecs(TimeDuration aDuration) {
return static_cast<int64_t>(aDuration.ToSeconds() * USECS_PER_S); return static_cast<int64_t>(aDuration.ToSeconds() * USECS_PER_S);
} }
static const uint32_t MIN_VIDEO_QUEUE_SIZE = 500; static const uint32_t MIN_VIDEO_QUEUE_SIZE = 600;
static const uint32_t MAX_VIDEO_QUEUE_SIZE = 500; static const uint32_t MAX_VIDEO_QUEUE_SIZE = 600;
static const uint32_t VIDEO_QUEUE_SEND_TO_COMPOSITOR_SIZE = 45; static const uint32_t VIDEO_QUEUE_SEND_TO_COMPOSITOR_SIZE = 45;
static uint32_t sVideoQueueDefaultSize = MAX_VIDEO_QUEUE_SIZE; static uint32_t sVideoQueueDefaultSize = MAX_VIDEO_QUEUE_SIZE;
@ -1185,7 +1185,7 @@ void MediaDecoderStateMachine::MaybeStartPlayback()
MOZ_ASSERT(mState == DECODER_STATE_DECODING || MOZ_ASSERT(mState == DECODER_STATE_DECODING ||
mState == DECODER_STATE_COMPLETED); mState == DECODER_STATE_COMPLETED);
if (IsPlaying()) { if (MOZ_LIKELY(IsPlaying())) {
// Logging this case is really spammy - don't do it. // Logging this case is really spammy - don't do it.
return; return;
} }
@ -2443,7 +2443,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
} }
case DECODER_STATE_DECODING: { case DECODER_STATE_DECODING: {
if (IsDecodingFirstFrame()) { if (MOZ_UNLIKELY(IsDecodingFirstFrame())) {
// We haven't completed decoding our first frames, we can't start // We haven't completed decoding our first frames, we can't start
// playback yet. // playback yet.
return NS_OK; return NS_OK;
@ -2623,7 +2623,7 @@ MediaDecoderStateMachine::CheckFrameValidity(VideoData* aData)
MOZ_ASSERT(OnTaskQueue()); MOZ_ASSERT(OnTaskQueue());
// Update corrupt-frames statistics // Update corrupt-frames statistics
if (aData->mImage && !aData->mImage->IsValid()) { if (aData->mImage && MOZ_UNLIKELY(!aData->mImage->IsValid())) {
FrameStatistics& frameStats = *mFrameStats; FrameStatistics& frameStats = *mFrameStats;
frameStats.NotifyCorruptFrame(); frameStats.NotifyCorruptFrame();
// If more than 10% of the last 30 frames have been corrupted, then try disabling // If more than 10% of the last 30 frames have been corrupted, then try disabling
@ -2792,7 +2792,7 @@ MediaDecoderStateMachine::DropAudioUpToSeekTarget(MediaData* aSample)
audio->mAudioData.get() + (framesToPrune.value() * channels), audio->mAudioData.get() + (framesToPrune.value() * channels),
frames * channels * sizeof(AudioDataValue)); frames * channels * sizeof(AudioDataValue));
CheckedInt64 duration = FramesToUsecs(frames, mInfo.mAudio.mRate); CheckedInt64 duration = FramesToUsecs(frames, mInfo.mAudio.mRate);
if (!duration.isValid()) { if (MOZ_UNLIKELY(!duration.isValid())) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
RefPtr<AudioData> data(new AudioData(audio->mOffset, RefPtr<AudioData> data(new AudioData(audio->mOffset,

View File

@ -88,24 +88,24 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip,
AbstractMediaDecoder::AutoNotifyDecoded a(mReader->GetDecoder()); AbstractMediaDecoder::AutoNotifyDecoded a(mReader->GetDecoder());
RefPtr<NesteggPacketHolder> holder(mReader->NextPacket(WebMReader::VIDEO)); RefPtr<NesteggPacketHolder> holder(mReader->NextPacket(WebMReader::VIDEO));
if (!holder) { if (MOZ_UNLIKELY(!holder)) {
return false; return false;
} }
nestegg_packet* packet = holder->Packet(); nestegg_packet* packet = holder->Packet();
unsigned int track = 0; unsigned int track = 0;
int r = nestegg_packet_track(packet, &track); int r = nestegg_packet_track(packet, &track);
if (r == -1) { if (MOZ_UNLIKELY(r == -1)) {
return false; return false;
} }
unsigned int count = 0; unsigned int count = 0;
r = nestegg_packet_count(packet, &count); r = nestegg_packet_count(packet, &count);
if (r == -1) { if (MOZ_UNLIKELY(r == -1)) {
return false; return false;
} }
if (count > 1) { if (MOZ_UNLIKELY(count > 1)) {
NS_WARNING("Packet contains more than one video frame"); NS_WARNING("Packet contains more than one video frame");
return false; return false;
} }
@ -130,7 +130,7 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip,
unsigned char* data; unsigned char* data;
size_t length; size_t length;
r = nestegg_packet_data(packet, 0, &data, &length); r = nestegg_packet_data(packet, 0, &data, &length);
if (r == -1) { if (MOZ_UNLIKELY(r == -1)) {
return false; return false;
} }
@ -153,7 +153,7 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip,
aKeyframeSkip = false; aKeyframeSkip = false;
} }
if (vpx_codec_decode(&mVPX, data, length, nullptr, 0)) { if (MOZ_UNLIKELY(vpx_codec_decode(&mVPX, data, length, nullptr, 0))) {
return false; return false;
} }
@ -217,7 +217,7 @@ SoftwareWebMVideoDecoder::DecodeVideoFrame(bool &aKeyframeSkip,
si.is_kf, si.is_kf,
-1, -1,
picture); picture);
if (!v) { if (MOZ_UNLIKELY(!v)) {
return false; return false;
} }
a.mParsed++; a.mParsed++;

View File

@ -417,7 +417,7 @@ bool WebMReader::DecodeAudioPacket(NesteggPacketHolder* aHolder)
int r = 0; int r = 0;
unsigned int count = 0; unsigned int count = 0;
r = nestegg_packet_count(aHolder->Packet(), &count); r = nestegg_packet_count(aHolder->Packet(), &count);
if (r == -1) { if (MOZ_UNLIKELY(r == -1)) {
return false; return false;
} }
@ -439,7 +439,7 @@ bool WebMReader::DecodeAudioPacket(NesteggPacketHolder* aHolder)
return false; return false;
} }
decoded_frames += mAudioFrames; decoded_frames += mAudioFrames;
if (!decoded_frames.isValid()) { if (MOZ_UNLIKELY(!decoded_frames.isValid())) {
NS_WARNING("Int overflow adding decoded_frames"); NS_WARNING("Int overflow adding decoded_frames");
return false; return false;
} }
@ -460,7 +460,7 @@ bool WebMReader::DecodeAudioPacket(NesteggPacketHolder* aHolder)
unsigned char* data; unsigned char* data;
size_t length; size_t length;
r = nestegg_packet_data(aHolder->Packet(), i, &data, &length); r = nestegg_packet_data(aHolder->Packet(), i, &data, &length);
if (r == -1) { if (MOZ_UNLIKELY(r == -1)) {
return false; return false;
} }
int64_t discardPadding = 0; int64_t discardPadding = 0;
@ -508,7 +508,7 @@ RefPtr<NesteggPacketHolder> WebMReader::NextPacket(TrackType aTrackType)
do { do {
RefPtr<NesteggPacketHolder> holder = DemuxPacket(); RefPtr<NesteggPacketHolder> holder = DemuxPacket();
if (!holder) { if (MOZ_UNLIKELY(!holder)) {
return nullptr; return nullptr;
} }
@ -530,13 +530,13 @@ WebMReader::DemuxPacket()
{ {
nestegg_packet* packet; nestegg_packet* packet;
int r = nestegg_read_packet(mContext, &packet); int r = nestegg_read_packet(mContext, &packet);
if (r <= 0) { if (MOZ_UNLIKELY(r <= 0)) {
return nullptr; return nullptr;
} }
unsigned int track = 0; unsigned int track = 0;
r = nestegg_packet_track(packet, &track); r = nestegg_packet_track(packet, &track);
if (r == -1) { if (MOZ_UNLIKELY(r == -1)) {
return nullptr; return nullptr;
} }
@ -548,7 +548,7 @@ WebMReader::DemuxPacket()
unsigned char* data; unsigned char* data;
size_t length; size_t length;
r = nestegg_packet_data(packet, 0, &data, &length); r = nestegg_packet_data(packet, 0, &data, &length);
if (r == -1) { if (MOZ_UNLIKELY(r == -1)) {
return nullptr; return nullptr;
} }
vpx_codec_stream_info_t si; vpx_codec_stream_info_t si;
@ -576,7 +576,7 @@ bool WebMReader::DecodeAudioData()
MOZ_ASSERT(OnTaskQueue()); MOZ_ASSERT(OnTaskQueue());
RefPtr<NesteggPacketHolder> holder(NextPacket(AUDIO)); RefPtr<NesteggPacketHolder> holder(NextPacket(AUDIO));
if (!holder) { if (MOZ_UNLIKELY(!holder)) {
return false; return false;
} }
@ -589,7 +589,7 @@ bool WebMReader::FilterPacketByTime(int64_t aEndTime, WebMPacketQueue& aOutput)
// than aEndTime. // than aEndTime.
while (true) { while (true) {
RefPtr<NesteggPacketHolder> holder(NextPacket(VIDEO)); RefPtr<NesteggPacketHolder> holder(NextPacket(VIDEO));
if (!holder) { if (MOZ_UNLIKELY(!holder)) {
break; break;
} }
int64_t tstamp = holder->Timestamp(); int64_t tstamp = holder->Timestamp();
@ -622,7 +622,7 @@ int64_t WebMReader::GetNextKeyframeTime(int64_t aTimeThreshold)
int64_t keyframeTime = -1; int64_t keyframeTime = -1;
while (!foundKeyframe) { while (!foundKeyframe) {
RefPtr<NesteggPacketHolder> holder(NextPacket(VIDEO)); RefPtr<NesteggPacketHolder> holder(NextPacket(VIDEO));
if (!holder) { if (MOZ_UNLIKELY(!holder)) {
break; break;
} }

View File

@ -224,18 +224,30 @@ gfxPlatformMac::MakePlatformFont(const nsAString& aFontName,
// Since HTTPS is becoming more common, check that first. // Since HTTPS is becoming more common, check that first.
#define HTTP_OR_HTTPS_SUBDIR(x) \ #define HTTP_OR_HTTPS_SUBDIR(x) \
{ \ { \
if (!failed) { \
NS_NAMED_LITERAL_CSTRING(https_, "https://" x); \ NS_NAMED_LITERAL_CSTRING(https_, "https://" x); \
spec.Left(loc, https_.Length()); \ spec.Left(loc, https_.Length()); \
if (loc.Equals(https_)) { \ if (loc.Equals(https_)) { \
failed = true; \ failed = true; \
goto halt_font; \
} else { \ } else { \
NS_NAMED_LITERAL_CSTRING(http_, "http://" x); \ NS_NAMED_LITERAL_CSTRING(http_, "http://" x); \
spec.Left(loc, http_.Length()); \ spec.Left(loc, http_.Length()); \
if (loc.Equals(http_)) \ if (loc.Equals(http_)) { \
failed = true; \ failed = true; \
goto halt_font; \
} \
} \ } \
} \ }
// TenFourFox issue 477: deal with changing infix version URLs, such as latimes.com
#define HOST_AND_KEY(x, y) \
{ \
if (hostname.Equals(x)) { \
if (spec.Find(y) != kNotFound) { \
failed = true; \
goto halt_font; \
} \
} \
} }
bool bool
@ -246,40 +258,52 @@ gfxPlatformMac::IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags)
"strange font format hint set"); "strange font format hint set");
// TenFourFox issue 261. Prevent loading certain known bad font URIs. // TenFourFox issue 261. Prevent loading certain known bad font URIs.
// Our checks only know about HTTP, though, so don't check others (issue 477).
nsAutoCString spec, loc; nsAutoCString spec, loc;
nsresult rv = aFontURI->GetAsciiSpec(spec); nsresult rv = aFontURI->GetAsciiSpec(spec);
bool failed = false; bool failed = false;
if (MOZ_LIKELY(NS_SUCCEEDED(rv))) { if (MOZ_LIKELY(NS_SUCCEEDED(rv))) {
nsAutoCString scheme;
if (MOZ_LIKELY(NS_SUCCEEDED(aFontURI->GetScheme(scheme)))) {
if (scheme.Equals("http") || scheme.Equals("https")) {
#if DEBUG #if DEBUG
fprintf(stderr, "Font blacklist checking: %s\n", spec.get()); fprintf(stderr, "Font blacklist checking: %s\n", spec.get());
#endif #endif
HTTP_OR_HTTPS_SUBDIR("www.apple.com/wss/fonts/SF-Pro-Text/v1/"); // Do left-most URL checks first.
HTTP_OR_HTTPS_SUBDIR("www.apple.com/wss/fonts/SF-Pro-Display/v1/");
HTTP_OR_HTTPS_SUBDIR("fonts.gstatic.com/ea/notosansjapanese/v6/NotoSansJP-");
HTTP_OR_HTTPS_SUBDIR("www.icloud.com/fonts/SFNSText-");
HTTP_OR_HTTPS_SUBDIR("typeface.nyt.com/fonts/nyt-cheltenham-");
HTTP_OR_HTTPS_SUBDIR("typeface.nytimes.com/fonts/nyt-cheltenham-");
// Don't cut to SF-Pro-; there are some dingbat fonts that DO work.
HTTP_OR_HTTPS_SUBDIR("www.apple.com/wss/fonts/SF-Pro-Text/v1/");
HTTP_OR_HTTPS_SUBDIR("www.apple.com/wss/fonts/SF-Pro-Display/v1/");
HTTP_OR_HTTPS_SUBDIR("lib.intuitcdn.net/fonts/AvenirNext/1.0/");
// Check hostname and subpatterns (TenFourFox issue 477).
nsAutoCString hostname;
if (MOZ_LIKELY(NS_SUCCEEDED(aFontURI->GetHost(hostname)))) {
ToLowerCase(hostname);
HOST_AND_KEY("www.latimes.com", "/fonts/KisFBDisplay-");
} else
failed = true; // Didn't get hostname, should have.
} // Must not be HTTP(S). We could catch others below.
} else
failed = true; // Didn't get scheme, should have.
} else } else
failed = true; failed = true; // Didn't get URL, should have.
halt_font:
if (failed || if (failed ||
spec.Equals("http://www.latimes.com/pb/resources/dist/la/latest/4dcd1b9d7833fcec708a/fonts/KisFBDisplay-Bold.woff") || // XXX: Reserve listing things here for one-offs that are too expensive to check otherwise,
spec.Equals("http://www.latimes.com/pb/resources/dist/la/latest/4dcd1b9d7833fcec708a/fonts/KisFBDisplay-Bold.woff2") || // or if there is a non-HTTP(S) URL we need to block (!!).
spec.Equals("http://www.latimes.com/pb/resources/dist/la/latest/4dcd1b9d7833fcec708a/fonts/KisFBDisplay-Roman.woff") || // spec.Equals("URL") ||
spec.Equals("http://www.latimes.com/pb/resources/dist/la/latest/4dcd1b9d7833fcec708a/fonts/KisFBDisplay-Roman.woff2") ||
spec.Equals("http://www.latimes.com/pb/resources/dist/la/latest/4b58868f482c8c9570aa/fonts/KisFBDisplay-Bold.woff") ||
spec.Equals("http://www.latimes.com/pb/resources/dist/la/latest/4b58868f482c8c9570aa/fonts/KisFBDisplay-Bold.woff2") ||
spec.Equals("http://www.latimes.com/pb/resources/dist/la/latest/4b58868f482c8c9570aa/fonts/KisFBDisplay-Roman.woff") ||
spec.Equals("http://www.latimes.com/pb/resources/dist/la/latest/4b58868f482c8c9570aa/fonts/KisFBDisplay-Roman.woff2") ||
spec.Equals("https://cdn-static-1.medium.com/_/fp/fonts/charter-nonlatin.b-nw7PXlIqmGHGmHvkDiTw.woff") || spec.Equals("https://cdn-static-1.medium.com/_/fp/fonts/charter-nonlatin.b-nw7PXlIqmGHGmHvkDiTw.woff") ||
spec.Equals("http://typeface.nytimes.com/fonts/nyt-cheltenham-200-normal.woff") ||
spec.Equals("https://typeface.nyt.com/fonts/nyt-cheltenham-200-normal.woff") ||
spec.Equals("http://typeface.nytimes.com/fonts/nyt-cheltenham-300-normal.woff") ||
spec.Equals("https://typeface.nyt.com/fonts/nyt-cheltenham-300-normal.woff") ||
spec.Equals("http://typeface.nytimes.com/fonts/nyt-cheltenham-400-normal.woff") ||
spec.Equals("https://typeface.nyt.com/fonts/nyt-cheltenham-400-normal.woff") ||
spec.Equals("http://fonts.gstatic.com/ea/notosansjapanese/v6/NotoSansJP-Regular.woff") ||
spec.Equals("http://fonts.gstatic.com/ea/notosansjapanese/v6/NotoSansJP-Bold.woff") ||
spec.Equals("http://fonts.gstatic.com/ea/notosansjapanese/v6/NotoSansJP-Regular.otf") ||
spec.Equals("http://fonts.gstatic.com/ea/notosansjapanese/v6/NotoSansJP-Bold.otf") ||
spec.Equals("https://www.icloud.com/fonts/SFNSText-Light.woff") ||
spec.Equals("https://www.icloud.com/fonts/SFNSText-Medium.woff") ||
0) { 0) {
if (MOZ_LIKELY(NS_SUCCEEDED(rv))) // Don't print if we couldn't get the URL. if (MOZ_LIKELY(NS_SUCCEEDED(rv))) // Don't print if we couldn't get the URL.
fprintf(stderr, "Warning: TenFourFox blocking ATSUI-incompatible webfont %s.\n", spec.get()); fprintf(stderr, "Warning: TenFourFox blocking ATSUI-incompatible webfont %s.\n", spec.get());

View File

@ -189,7 +189,7 @@ GCRuntime::tryNewTenuredObject(ExclusiveContext* cx, AllocKind kind, size_t thin
JSObject* obj = tryNewTenuredThing<JSObject, allowGC>(cx, kind, thingSize); JSObject* obj = tryNewTenuredThing<JSObject, allowGC>(cx, kind, thingSize);
if (obj) if (MOZ_LIKELY(obj))
obj->setInitialSlotsMaybeNonNative(slots); obj->setInitialSlotsMaybeNonNative(slots);
else else
js_free(slots); js_free(slots);
@ -262,7 +262,7 @@ GCRuntime::tryNewTenuredThing(ExclusiveContext* cx, AllocKind kind, size_t thing
rt->gc.waitBackgroundSweepOrAllocEnd(); rt->gc.waitBackgroundSweepOrAllocEnd();
t = tryNewTenuredThing<T, NoGC>(cx, kind, thingSize); t = tryNewTenuredThing<T, NoGC>(cx, kind, thingSize);
if (!t) if (MOZ_UNLIKELY(!t))
ReportOutOfMemory(cx); ReportOutOfMemory(cx);
} }
} }

View File

@ -215,7 +215,7 @@ js::Nursery::allocateObject(JSContext* cx, size_t size, size_t numDynamic, const
/* Make the object allocation. */ /* Make the object allocation. */
JSObject* obj = static_cast<JSObject*>(allocate(size)); JSObject* obj = static_cast<JSObject*>(allocate(size));
if (!obj) if (MOZ_UNLIKELY(!obj))
return nullptr; return nullptr;
/* If we want external slots, add them. */ /* If we want external slots, add them. */
@ -223,7 +223,7 @@ js::Nursery::allocateObject(JSContext* cx, size_t size, size_t numDynamic, const
if (numDynamic) { if (numDynamic) {
MOZ_ASSERT(clasp->isNative()); MOZ_ASSERT(clasp->isNative());
slots = static_cast<HeapSlot*>(allocateBuffer(cx->zone(), numDynamic * sizeof(HeapSlot))); slots = static_cast<HeapSlot*>(allocateBuffer(cx->zone(), numDynamic * sizeof(HeapSlot)));
if (!slots) { if (MOZ_UNLIKELY(!slots)) {
/* /*
* It is safe to leave the allocated object uninitialized, since we * It is safe to leave the allocated object uninitialized, since we
* do not visit unallocated things in the nursery. * do not visit unallocated things in the nursery.

View File

@ -2095,7 +2095,7 @@ AllocRelocatedCell(Zone* zone, AllocKind thingKind, size_t thingSize)
void* dstAlloc = zone->arenas.allocateFromFreeList(thingKind, thingSize); void* dstAlloc = zone->arenas.allocateFromFreeList(thingKind, thingSize);
if (!dstAlloc) if (!dstAlloc)
dstAlloc = GCRuntime::refillFreeListInGC(zone, thingKind); dstAlloc = GCRuntime::refillFreeListInGC(zone, thingKind);
if (!dstAlloc) { if (MOZ_UNLIKELY(!dstAlloc)) {
// This can only happen in zeal mode or debug builds as we don't // This can only happen in zeal mode or debug builds as we don't
// otherwise relocate more cells than we have existing free space // otherwise relocate more cells than we have existing free space
// for. // for.
@ -4313,7 +4313,7 @@ js::gc::MarkingValidator::nonIncrementalMark()
for (auto chunk = gc->allNonEmptyChunks(); !chunk.done(); chunk.next()) { for (auto chunk = gc->allNonEmptyChunks(); !chunk.done(); chunk.next()) {
ChunkBitmap* bitmap = &chunk->bitmap; ChunkBitmap* bitmap = &chunk->bitmap;
ChunkBitmap* entry = js_new<ChunkBitmap>(); ChunkBitmap* entry = js_new<ChunkBitmap>();
if (!entry) if (MOZ_UNLIKELY(!entry))
return; return;
memcpy((void*)entry->bitmap, (void*)bitmap->bitmap, sizeof(bitmap->bitmap)); memcpy((void*)entry->bitmap, (void*)bitmap->bitmap, sizeof(bitmap->bitmap));

View File

@ -233,7 +233,7 @@ js::Throw(JSContext* cx, jsid id, unsigned errorNumber)
if (!idstr) if (!idstr)
return false; return false;
JSAutoByteString bytes(cx, idstr); JSAutoByteString bytes(cx, idstr);
if (!bytes) if (MOZ_UNLIKELY(!bytes))
return false; return false;
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, errorNumber, bytes.ptr()); JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, errorNumber, bytes.ptr());
return false; return false;
@ -661,12 +661,12 @@ NewObject(ExclusiveContext* cx, HandleObjectGroup group, gc::AllocKind kind,
RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, group->proto(), nfixed, RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, group->proto(), nfixed,
initialShapeFlags)); initialShapeFlags));
if (!shape) if (MOZ_UNLIKELY(!shape))
return nullptr; return nullptr;
gc::InitialHeap heap = GetInitialHeap(newKind, clasp); gc::InitialHeap heap = GetInitialHeap(newKind, clasp);
JSObject* obj = JSObject::create(cx, kind, heap, shape, group); JSObject* obj = JSObject::create(cx, kind, heap, shape, group);
if (!obj) if (MOZ_UNLIKELY(!obj))
return nullptr; return nullptr;
if (newKind == SingletonObject) { if (newKind == SingletonObject) {
@ -723,11 +723,11 @@ js::NewObjectWithGivenTaggedProto(ExclusiveContext* cxArg, const Class* clasp,
} }
RootedObjectGroup group(cxArg, ObjectGroup::defaultNewGroup(cxArg, clasp, proto, nullptr)); RootedObjectGroup group(cxArg, ObjectGroup::defaultNewGroup(cxArg, clasp, proto, nullptr));
if (!group) if (MOZ_UNLIKELY(!group))
return nullptr; return nullptr;
RootedObject obj(cxArg, NewObject(cxArg, group, allocKind, newKind, initialShapeFlags)); RootedObject obj(cxArg, NewObject(cxArg, group, allocKind, newKind, initialShapeFlags));
if (!obj) if (MOZ_UNLIKELY(!obj))
return nullptr; return nullptr;
if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) { if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) {
@ -790,11 +790,11 @@ js::NewObjectWithClassProtoCommon(ExclusiveContext* cxArg, const Class* clasp,
Rooted<TaggedProto> taggedProto(cxArg, TaggedProto(proto)); Rooted<TaggedProto> taggedProto(cxArg, TaggedProto(proto));
RootedObjectGroup group(cxArg, ObjectGroup::defaultNewGroup(cxArg, clasp, taggedProto)); RootedObjectGroup group(cxArg, ObjectGroup::defaultNewGroup(cxArg, clasp, taggedProto));
if (!group) if (MOZ_UNLIKELY(!group))
return nullptr; return nullptr;
JSObject* obj = NewObject(cxArg, group, allocKind, newKind); JSObject* obj = NewObject(cxArg, group, allocKind, newKind);
if (!obj) if (MOZ_UNLIKELY(!obj))
return nullptr; return nullptr;
if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) { if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) {
@ -844,7 +844,7 @@ js::NewObjectWithGroupCommon(ExclusiveContext* cx, HandleObjectGroup group,
} }
JSObject* obj = NewObject(cx, group, allocKind, newKind); JSObject* obj = NewObject(cx, group, allocKind, newKind);
if (!obj) if (MOZ_UNLIKELY(!obj))
return nullptr; return nullptr;
if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) { if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) {
@ -957,7 +957,7 @@ js::CreateThisForFunctionWithProto(JSContext* cx, HandleObject callee, HandleObj
if (proto) { if (proto) {
RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, nullptr, TaggedProto(proto), RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, nullptr, TaggedProto(proto),
newTarget)); newTarget));
if (!group) if (MOZ_UNLIKELY(!group))
return nullptr; return nullptr;
if (group->newScript() && !group->newScript()->analyzed()) { if (group->newScript() && !group->newScript()->analyzed()) {
@ -980,7 +980,7 @@ js::CreateThisForFunctionWithProto(JSContext* cx, HandleObject callee, HandleObj
if (res) { if (res) {
JSScript* script = callee->as<JSFunction>().getOrCreateScript(cx); JSScript* script = callee->as<JSFunction>().getOrCreateScript(cx);
if (!script) if (MOZ_UNLIKELY(!script))
return nullptr; return nullptr;
TypeScript::SetThis(cx, script, TypeSet::ObjectType(res)); TypeScript::SetThis(cx, script, TypeSet::ObjectType(res));
} }
@ -1145,7 +1145,7 @@ js::CloneObject(JSContext* cx, HandleObject obj, Handle<js::TaggedProto> proto)
RootedObject clone(cx); RootedObject clone(cx);
if (obj->isNative()) { if (obj->isNative()) {
clone = NewObjectWithGivenTaggedProto(cx, obj->getClass(), proto); clone = NewObjectWithGivenTaggedProto(cx, obj->getClass(), proto);
if (!clone) if (MOZ_UNLIKELY(!clone))
return nullptr; return nullptr;
if (clone->is<JSFunction>() && (obj->compartment() != clone->compartment())) { if (clone->is<JSFunction>() && (obj->compartment() != clone->compartment())) {
@ -1161,7 +1161,7 @@ js::CloneObject(JSContext* cx, HandleObject obj, Handle<js::TaggedProto> proto)
options.setClass(obj->getClass()); options.setClass(obj->getClass());
clone = ProxyObject::New(cx, GetProxyHandler(obj), JS::NullHandleValue, proto, options); clone = ProxyObject::New(cx, GetProxyHandler(obj), JS::NullHandleValue, proto, options);
if (!clone) if (MOZ_UNLIKELY(!clone))
return nullptr; return nullptr;
if (!CopyProxyObject(cx, obj.as<ProxyObject>(), clone.as<ProxyObject>())) if (!CopyProxyObject(cx, obj.as<ProxyObject>(), clone.as<ProxyObject>()))
@ -1345,13 +1345,13 @@ InitializePropertiesFromCompatibleNativeObject(JSContext* cx,
// dst's object flags are 0. // dst's object flags are 0.
shape = EmptyShape::getInitialShape(cx, dst->getClass(), dst->getTaggedProto(), shape = EmptyShape::getInitialShape(cx, dst->getClass(), dst->getTaggedProto(),
dst->numFixedSlots(), 0); dst->numFixedSlots(), 0);
if (!shape) if (MOZ_UNLIKELY(!shape))
return false; return false;
// Get an in-order list of the shapes in the src object. // Get an in-order list of the shapes in the src object.
Rooted<ShapeVector> shapes(cx, ShapeVector(cx)); Rooted<ShapeVector> shapes(cx, ShapeVector(cx));
for (Shape::Range<NoGC> r(src->lastProperty()); !r.empty(); r.popFront()) { for (Shape::Range<NoGC> r(src->lastProperty()); !r.empty(); r.popFront()) {
if (!shapes.append(&r.front())) if (MOZ_UNLIKELY(!shapes.append(&r.front())))
return false; return false;
} }
Reverse(shapes.begin(), shapes.end()); Reverse(shapes.begin(), shapes.end());
@ -1442,7 +1442,7 @@ js::XDRObjectLiteral(XDRState<mode>* xdr, MutableHandleObject obj)
: ObjectGroup::NewArrayKind::Normal; : ObjectGroup::NewArrayKind::Normal;
obj.set(ObjectGroup::newArrayObject(cx, values.begin(), values.length(), obj.set(ObjectGroup::newArrayObject(cx, values.begin(), values.length(),
TenuredObject, arrayKind)); TenuredObject, arrayKind));
if (!obj) if (MOZ_UNLIKELY(!obj))
return false; return false;
} }
@ -1551,18 +1551,20 @@ JSObject::fixDictionaryShapeAfterSwap()
bool bool
JSObject::swap(JSContext* cx, HandleObject a, HandleObject b) JSObject::swap(JSContext* cx, HandleObject a, HandleObject b)
{ {
#if(0) // See TenFourFox issue 479 for why we can get away with this.
// Ensure swap doesn't cause a finalizer to not be run. // Ensure swap doesn't cause a finalizer to not be run.
MOZ_ASSERT(IsBackgroundFinalized(a->asTenured().getAllocKind()) == MOZ_ASSERT(IsBackgroundFinalized(a->asTenured().getAllocKind()) ==
IsBackgroundFinalized(b->asTenured().getAllocKind())); IsBackgroundFinalized(b->asTenured().getAllocKind()));
#endif
MOZ_ASSERT(a->compartment() == b->compartment()); MOZ_ASSERT(a->compartment() == b->compartment());
AutoEnterOOMUnsafeRegion oomUnsafe; AutoEnterOOMUnsafeRegion oomUnsafe;
AutoCompartment ac(cx, a); AutoCompartment ac(cx, a);
if (!a->getGroup(cx)) if (MOZ_UNLIKELY(!a->getGroup(cx)))
oomUnsafe.crash("JSObject::swap"); oomUnsafe.crash("JSObject::swap");
if (!b->getGroup(cx)) if (MOZ_UNLIKELY(!b->getGroup(cx)))
oomUnsafe.crash("JSObject::swap"); oomUnsafe.crash("JSObject::swap");
/* /*
@ -1644,9 +1646,9 @@ JSObject::swap(JSContext* cx, HandleObject a, HandleObject b)
a->fixDictionaryShapeAfterSwap(); a->fixDictionaryShapeAfterSwap();
b->fixDictionaryShapeAfterSwap(); b->fixDictionaryShapeAfterSwap();
if (na && !b->as<NativeObject>().fillInAfterSwap(cx, avals, apriv)) if (MOZ_UNLIKELY(na && !b->as<NativeObject>().fillInAfterSwap(cx, avals, apriv)))
oomUnsafe.crash("fillInAfterSwap"); oomUnsafe.crash("fillInAfterSwap");
if (nb && !a->as<NativeObject>().fillInAfterSwap(cx, bvals, bpriv)) if (MOZ_UNLIKELY(nb && !a->as<NativeObject>().fillInAfterSwap(cx, bvals, bpriv)))
oomUnsafe.crash("fillInAfterSwap"); oomUnsafe.crash("fillInAfterSwap");
} }
@ -1758,7 +1760,7 @@ DefineConstructorAndPrototype(JSContext* cx, HandleObject obj, JSProtoKey key, H
* used because it won't let us use protoProto as the proto. * used because it won't let us use protoProto as the proto.
*/ */
RootedNativeObject proto(cx, NewNativeObjectWithClassProto(cx, clasp, protoProto, SingletonObject)); RootedNativeObject proto(cx, NewNativeObjectWithClassProto(cx, clasp, protoProto, SingletonObject));
if (!proto) if (MOZ_UNLIKELY(!proto))
return nullptr; return nullptr;
/* After this point, control must exit via label bad or out. */ /* After this point, control must exit via label bad or out. */
@ -1786,7 +1788,7 @@ DefineConstructorAndPrototype(JSContext* cx, HandleObject obj, JSProtoKey key, H
ctor = proto; ctor = proto;
} else { } else {
RootedFunction fun(cx, NewNativeConstructor(cx, constructor, nargs, atom, ctorKind)); RootedFunction fun(cx, NewNativeConstructor(cx, constructor, nargs, atom, ctorKind));
if (!fun) if (MOZ_UNLIKELY(!fun))
goto bad; goto bad;
/* /*
@ -1960,7 +1962,7 @@ js::SetClassAndProto(JSContext* cx, HandleObject obj,
} }
ObjectGroup* group = ObjectGroup::defaultNewGroup(cx, clasp, proto); ObjectGroup* group = ObjectGroup::defaultNewGroup(cx, clasp, proto);
if (!group) if (MOZ_UNLIKELY(!group))
return false; return false;
/* /*
@ -1987,7 +1989,7 @@ JSObject::changeToSingleton(JSContext* cx, HandleObject obj)
ObjectGroup* group = ObjectGroup::lazySingletonGroup(cx, obj->getClass(), ObjectGroup* group = ObjectGroup::lazySingletonGroup(cx, obj->getClass(),
obj->getTaggedProto()); obj->getTaggedProto());
if (!group) if (MOZ_UNLIKELY(!group))
return false; return false;
obj->group_ = group; obj->group_ = group;
@ -3656,12 +3658,12 @@ JSObject::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::ClassIn
} }
// Other things may be measured in the future if DMD indicates it is worthwhile. // Other things may be measured in the future if DMD indicates it is worthwhile.
if (is<JSFunction>() || if (MOZ_LIKELY((is<JSFunction>() ||
is<PlainObject>() || is<PlainObject>() ||
is<ArrayObject>() || is<ArrayObject>() ||
is<CallObject>() || is<CallObject>() ||
is<RegExpObject>() || is<RegExpObject>() ||
is<ProxyObject>()) is<ProxyObject>())))
{ {
// Do nothing. But this function is hot, and we win by getting the // Do nothing. But this function is hot, and we win by getting the
// common cases out of the way early. Some stats on the most common // common cases out of the way early. Some stats on the most common

View File

@ -149,6 +149,6 @@ bool Wrapper::finalizeInBackground(Value priv) const
*/ */
if (IsInsideNursery(&priv.toObject())) if (IsInsideNursery(&priv.toObject()))
return true; return true;
return false; // speculative fix return false; // See TenFourFox issue 479.
return IsBackgroundFinalized(priv.toObject().asTenured().getAllocKind()); //return IsBackgroundFinalized(priv.toObject().asTenured().getAllocKind());
} }

View File

@ -54,7 +54,7 @@ js::RegExpAlloc(ExclusiveContext* cx, HandleObject proto /* = nullptr */)
regexp->initPrivate(nullptr); regexp->initPrivate(nullptr);
if (!EmptyShape::ensureInitialCustomShape<RegExpObject>(cx, regexp)) if (MOZ_UNLIKELY(!EmptyShape::ensureInitialCustomShape<RegExpObject>(cx, regexp)))
return nullptr; return nullptr;
MOZ_ASSERT(regexp->lookupPure(cx->names().lastIndex)->slot() == MOZ_ASSERT(regexp->lookupPure(cx->names().lastIndex)->slot() ==
@ -70,7 +70,7 @@ MatchPairs::initArrayFrom(MatchPairs& copyFrom)
{ {
MOZ_ASSERT(copyFrom.pairCount() > 0); MOZ_ASSERT(copyFrom.pairCount() > 0);
if (!allocOrExpandArray(copyFrom.pairCount())) if (MOZ_UNLIKELY(!allocOrExpandArray(copyFrom.pairCount())))
return false; return false;
PodCopy(pairs_, copyFrom.pairs_, pairCount_); PodCopy(pairs_, copyFrom.pairs_, pairCount_);
@ -90,7 +90,7 @@ ScopedMatchPairs::allocOrExpandArray(size_t pairCount)
MOZ_ASSERT(!pairs_); MOZ_ASSERT(!pairs_);
pairs_ = (MatchPair*)lifoScope_.alloc().alloc(sizeof(MatchPair) * pairCount); pairs_ = (MatchPair*)lifoScope_.alloc().alloc(sizeof(MatchPair) * pairCount);
if (!pairs_) if (MOZ_UNLIKELY(!pairs_))
return false; return false;
pairCount_ = pairCount; pairCount_ = pairCount;
@ -224,7 +224,7 @@ RegExpObject::createNoStatics(ExclusiveContext* cx, HandleAtom source, RegExpFla
return nullptr; return nullptr;
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx)); Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx));
if (!regexp) if (MOZ_UNLIKELY(!regexp))
return nullptr; return nullptr;
regexp->initAndZeroLastIndex(source, flags, cx); regexp->initAndZeroLastIndex(source, flags, cx);
@ -341,7 +341,7 @@ SetupBuffer(StringBuffer& sb, const CharT* oldChars, size_t oldLen, const CharT*
if (mozilla::IsSame<CharT, char16_t>::value && !sb.ensureTwoByteChars()) if (mozilla::IsSame<CharT, char16_t>::value && !sb.ensureTwoByteChars())
return false; return false;
if (!sb.reserve(oldLen + 1)) if (MOZ_UNLIKELY(!sb.reserve(oldLen + 1)))
return false; return false;
sb.infallibleAppend(oldChars, size_t(it - oldChars)); sb.infallibleAppend(oldChars, size_t(it - oldChars));
@ -837,10 +837,10 @@ RegExpCompartment::get(JSContext* cx, JSAtom* source, RegExpFlag flags, RegExpGu
} }
ScopedJSDeletePtr<RegExpShared> shared(cx->new_<RegExpShared>(source, flags)); ScopedJSDeletePtr<RegExpShared> shared(cx->new_<RegExpShared>(source, flags));
if (!shared) if (MOZ_UNLIKELY(!shared))
return false; return false;
if (!set_.add(p, shared)) { if (MOZ_UNLIKELY(!set_.add(p, shared))) {
ReportOutOfMemory(cx); ReportOutOfMemory(cx);
return false; return false;
} }
@ -885,18 +885,18 @@ js::CloneRegExpObject(JSContext* cx, JSObject* obj_)
// in the tenured heap to simplify embedding them in JIT code. // in the tenured heap to simplify embedding them in JIT code.
RootedObjectGroup group(cx, regex->group()); RootedObjectGroup group(cx, regex->group());
Rooted<RegExpObject*> clone(cx, NewObjectWithGroup<RegExpObject>(cx, group, TenuredObject)); Rooted<RegExpObject*> clone(cx, NewObjectWithGroup<RegExpObject>(cx, group, TenuredObject));
if (!clone) if (MOZ_UNLIKELY(!clone))
return nullptr; return nullptr;
clone->initPrivate(nullptr); clone->initPrivate(nullptr);
if (!EmptyShape::ensureInitialCustomShape<RegExpObject>(cx, clone)) if (MOZ_UNLIKELY(!EmptyShape::ensureInitialCustomShape<RegExpObject>(cx, clone)))
return nullptr; return nullptr;
Rooted<JSAtom*> source(cx, regex->getSource()); Rooted<JSAtom*> source(cx, regex->getSource());
// Check that the RegExpShared for |regex| is okay to reuse in the clone. // Check that the RegExpShared for |regex| is okay to reuse in the clone.
RegExpStatics* currentStatics = regex->getProto()->global().getRegExpStatics(cx); RegExpStatics* currentStatics = regex->getProto()->global().getRegExpStatics(cx);
if (!currentStatics) if (MOZ_UNLIKELY(!currentStatics))
return nullptr; return nullptr;
RegExpFlag origFlags = regex->getFlags(); RegExpFlag origFlags = regex->getFlags();
@ -969,7 +969,7 @@ bool
js::ParseRegExpFlags(JSContext* cx, JSString* flagStr, RegExpFlag* flagsOut) js::ParseRegExpFlags(JSContext* cx, JSString* flagStr, RegExpFlag* flagsOut)
{ {
JSLinearString* linear = flagStr->ensureLinear(cx); JSLinearString* linear = flagStr->ensureLinear(cx);
if (!linear) if (MOZ_UNLIKELY(!linear))
return false; return false;
size_t len = linear->length(); size_t len = linear->length();

View File

@ -517,6 +517,12 @@ nsDocumentViewer::~nsDocumentViewer()
mDocument->Destroy(); mDocument->Destroy();
} }
if (mPrintEngine) {
mPrintEngine->Destroy();
mPrintEngine = nullptr;
}
MOZ_RELEASE_ASSERT(mDestroyRefCount == 0);
NS_ASSERTION(!mPresShell && !mPresContext, NS_ASSERTION(!mPresShell && !mPresContext,
"User did not call nsIContentViewer::Destroy"); "User did not call nsIContentViewer::Destroy");
if (mPresShell || mPresContext) { if (mPresShell || mPresContext) {
@ -1564,7 +1570,6 @@ nsDocumentViewer::Destroy()
// We also keep the viewer from being cached in session history, since // We also keep the viewer from being cached in session history, since
// we require all documents there to be sanitized. // we require all documents there to be sanitized.
if (mDestroyRefCount != 0) { if (mDestroyRefCount != 0) {
--mDestroyRefCount;
return NS_OK; return NS_OK;
} }
@ -4209,6 +4214,12 @@ nsDocumentViewer::IncrementDestroyRefCount()
++mDestroyRefCount; ++mDestroyRefCount;
} }
void
nsDocumentViewer::DecrementDestroyRefCount()
{
--mDestroyRefCount;
}
//------------------------------------------------------------ //------------------------------------------------------------
#if defined(NS_PRINTING) && defined(NS_PRINT_PREVIEW) #if defined(NS_PRINTING) && defined(NS_PRINT_PREVIEW)

View File

@ -39,6 +39,7 @@ public:
virtual nsresult CreateStyleSet(nsIDocument* aDocument, nsStyleSet** aStyleSet) = 0; virtual nsresult CreateStyleSet(nsIDocument* aDocument, nsStyleSet** aStyleSet) = 0;
virtual void IncrementDestroyRefCount() = 0; virtual void IncrementDestroyRefCount() = 0;
virtual void DecrementDestroyRefCount() = 0;
virtual void ReturnToGalleyPresentation() = 0; virtual void ReturnToGalleyPresentation() = 0;
@ -73,6 +74,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentViewerPrint,
virtual bool GetIsPrintPreview() override; \ virtual bool GetIsPrintPreview() override; \
virtual nsresult CreateStyleSet(nsIDocument* aDocument, nsStyleSet** aStyleSet) override; \ virtual nsresult CreateStyleSet(nsIDocument* aDocument, nsStyleSet** aStyleSet) override; \
virtual void IncrementDestroyRefCount() override; \ virtual void IncrementDestroyRefCount() override; \
virtual void DecrementDestroyRefCount() override; \
virtual void ReturnToGalleyPresentation() override; \ virtual void ReturnToGalleyPresentation() override; \
virtual void OnDonePrinting() override; \ virtual void OnDonePrinting() override; \
virtual bool IsInitializedForPrintPreview() override; \ virtual bool IsInitializedForPrintPreview() override; \

View File

@ -12,14 +12,8 @@ NS_IMPL_ISUPPORTS_INHERITED(nsPagePrintTimer, nsRunnable, nsITimerCallback)
nsPagePrintTimer::~nsPagePrintTimer() nsPagePrintTimer::~nsPagePrintTimer()
{ {
// "Destroy" the document viewer; this normally doesn't actually // This matches the IncrementDestroyRefCount call in the constructor.
// destroy it because of the IncrementDestroyRefCount call below mDocViewerPrint->DecrementDestroyRefCount();
// XXX This is messy; the document viewer should use a single approach
// to keep itself alive during printing
nsCOMPtr<nsIContentViewer> cv(do_QueryInterface(mDocViewerPrint));
if (cv) {
cv->Destroy();
}
} }
nsresult nsresult

View File

@ -13,8 +13,11 @@
* \brief Provides the high level interface to wrap encoder algorithms. * \brief Provides the high level interface to wrap encoder algorithms.
* *
*/ */
#include <assert.h>
#include <limits.h> #include <limits.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "vp8/common/blockd.h"
#include "vpx_config.h" #include "vpx_config.h"
#include "vpx/internal/vpx_codec_internal.h" #include "vpx/internal/vpx_codec_internal.h"
@ -89,6 +92,8 @@ vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx,
int i; int i;
void *mem_loc = NULL; void *mem_loc = NULL;
if (iface->enc.mr_get_mem_loc == NULL) return VPX_CODEC_INCAPABLE;
if (!(res = iface->enc.mr_get_mem_loc(cfg, &mem_loc))) { if (!(res = iface->enc.mr_get_mem_loc(cfg, &mem_loc))) {
for (i = 0; i < num_enc; i++) { for (i = 0; i < num_enc; i++) {
vpx_codec_priv_enc_mr_cfg_t mr_cfg; vpx_codec_priv_enc_mr_cfg_t mr_cfg;
@ -98,28 +103,29 @@ vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx,
dsf->den > dsf->num) { dsf->den > dsf->num) {
res = VPX_CODEC_INVALID_PARAM; res = VPX_CODEC_INVALID_PARAM;
break; break;
} else {
mr_cfg.mr_low_res_mode_info = mem_loc;
mr_cfg.mr_total_resolutions = num_enc;
mr_cfg.mr_encoder_id = num_enc - 1 - i;
mr_cfg.mr_down_sampling_factor.num = dsf->num;
mr_cfg.mr_down_sampling_factor.den = dsf->den;
/* Force Key-frame synchronization. Namely, encoder at higher
* resolution always use the same frame_type chosen by the
* lowest-resolution encoder.
*/
if (mr_cfg.mr_encoder_id)
cfg->kf_mode = VPX_KF_DISABLED;
ctx->iface = iface;
ctx->name = iface->name;
ctx->priv = NULL;
ctx->init_flags = flags;
ctx->config.enc = cfg;
res = ctx->iface->init(ctx, &mr_cfg);
} }
mr_cfg.mr_low_res_mode_info = mem_loc;
mr_cfg.mr_total_resolutions = num_enc;
mr_cfg.mr_encoder_id = num_enc - 1 - i;
mr_cfg.mr_down_sampling_factor.num = dsf->num;
mr_cfg.mr_down_sampling_factor.den = dsf->den;
/* Force Key-frame synchronization. Namely, encoder at higher
* resolution always use the same frame_type chosen by the
* lowest-resolution encoder.
*/
if (mr_cfg.mr_encoder_id)
cfg->kf_mode = VPX_KF_DISABLED;
ctx->iface = iface;
ctx->name = iface->name;
ctx->priv = NULL;
ctx->init_flags = flags;
ctx->config.enc = cfg;
res = ctx->iface->init(ctx, &mr_cfg);
if (res) { if (res) {
const char *error_detail = const char *error_detail =
ctx->priv ? ctx->priv->err_detail : NULL; ctx->priv ? ctx->priv->err_detail : NULL;
@ -134,11 +140,14 @@ vpx_codec_err_t vpx_codec_enc_init_multi_ver(vpx_codec_ctx_t *ctx,
vpx_codec_destroy(ctx); vpx_codec_destroy(ctx);
i--; i--;
} }
#if CONFIG_MULTI_RES_ENCODING
assert(mem_loc);
free(((LOWER_RES_FRAME_INFO *)mem_loc)->mb_info);
free(mem_loc);
#endif
return SAVE_STATUS(ctx, res);
} }
if (res)
break;
ctx++; ctx++;
cfg++; cfg++;
dsf++; dsf++;

View File

@ -731,6 +731,7 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
{ "business.twitter.com", true, false, false, -1, &kPinset_twitterCom }, { "business.twitter.com", true, false, false, -1, &kPinset_twitterCom },
{ "ca.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, { "ca.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
{ "cd.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, { "cd.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
{ "cdn.ampproject.org", true, false, false, -1, &kPinset_google_root_pems },
{ "cdn.mozilla.net", true, false, true, -1, &kPinset_mozilla }, { "cdn.mozilla.net", true, false, true, -1, &kPinset_mozilla },
{ "cdn.mozilla.org", true, false, true, -1, &kPinset_mozilla }, { "cdn.mozilla.org", true, false, true, -1, &kPinset_mozilla },
{ "cg.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, { "cg.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
@ -1178,8 +1179,8 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
{ "zh.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, { "zh.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
}; };
// Pinning Preload List Length = 476; // Pinning Preload List Length = 477;
static const int32_t kUnknownId = -1; static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1524685607926000); static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1527453921095000);

File diff suppressed because it is too large Load Diff

View File

@ -39,122 +39,29 @@ namespace storage {
#define MAX_MILLISECONDS_BETWEEN_RESULTS 75 #define MAX_MILLISECONDS_BETWEEN_RESULTS 75
#define MAX_ROWS_PER_RESULT 15 #define MAX_ROWS_PER_RESULT 15
//////////////////////////////////////////////////////////////////////////////// // It is not possible to use ESR52's nsProxyRelease.h without substantial and
//// Local Classes // unacceptable modification, so we use part of it here to simulate it and
// fix bugs 1375217 and 1350752.
//
// XXX: If this is needed lots of places, we should move it to that header.
namespace { template<typename T>
class ProxyReleaseEvent : public nsRunnable
typedef AsyncExecuteStatements::ExecutionState ExecutionState;
typedef AsyncExecuteStatements::StatementDataArray StatementDataArray;
/**
* Notifies a callback with a result set.
*/
class CallbackResultNotifier : public nsRunnable
{ {
public: public:
CallbackResultNotifier(mozIStorageStatementCallback *aCallback, explicit ProxyReleaseEvent(already_AddRefed<T> aDoomed)
mozIStorageResultSet *aResults, : mDoomed(aDoomed.take()) {}
AsyncExecuteStatements *aEventStatus) :
mCallback(aCallback) NS_IMETHOD Run() override
, mResults(aResults)
, mEventStatus(aEventStatus)
{ {
} NS_IF_RELEASE(mDoomed);
NS_IMETHOD Run()
{
NS_ASSERTION(mCallback, "Trying to notify about results without a callback!");
if (mEventStatus->shouldNotify()) {
// Hold a strong reference to the callback while notifying it, so that if
// it spins the event loop, the callback won't be released and freed out
// from under us.
nsCOMPtr<mozIStorageStatementCallback> callback = mCallback;
(void)callback->HandleResult(mResults);
}
return NS_OK; return NS_OK;
} }
private: private:
mozIStorageStatementCallback *mCallback; T* MOZ_OWNING_REF mDoomed;
nsCOMPtr<mozIStorageResultSet> mResults;
RefPtr<AsyncExecuteStatements> mEventStatus;
}; };
/**
* Notifies the calling thread that an error has occurred.
*/
class ErrorNotifier : public nsRunnable
{
public:
ErrorNotifier(mozIStorageStatementCallback *aCallback,
mozIStorageError *aErrorObj,
AsyncExecuteStatements *aEventStatus) :
mCallback(aCallback)
, mErrorObj(aErrorObj)
, mEventStatus(aEventStatus)
{
}
NS_IMETHOD Run()
{
if (mEventStatus->shouldNotify() && mCallback) {
// Hold a strong reference to the callback while notifying it, so that if
// it spins the event loop, the callback won't be released and freed out
// from under us.
nsCOMPtr<mozIStorageStatementCallback> callback = mCallback;
(void)callback->HandleError(mErrorObj);
}
return NS_OK;
}
private:
mozIStorageStatementCallback *mCallback;
nsCOMPtr<mozIStorageError> mErrorObj;
RefPtr<AsyncExecuteStatements> mEventStatus;
};
/**
* Notifies the calling thread that the statement has finished executing. Takes
* ownership of the StatementData so it is released on the proper thread.
*/
class CompletionNotifier : public nsRunnable
{
public:
/**
* This takes ownership of the callback and the StatementData. They are
* released on the thread this is dispatched to (which should always be the
* calling thread).
*/
CompletionNotifier(mozIStorageStatementCallback *aCallback,
ExecutionState aReason)
: mCallback(aCallback)
, mReason(aReason)
{
}
NS_IMETHOD Run()
{
if (mCallback) {
(void)mCallback->HandleCompletion(mReason);
NS_RELEASE(mCallback);
}
return NS_OK;
}
private:
mozIStorageStatementCallback *mCallback;
ExecutionState mReason;
};
} // namespace
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//// AsyncExecuteStatements //// AsyncExecuteStatements
@ -208,16 +115,24 @@ AsyncExecuteStatements::AsyncExecuteStatements(StatementDataArray &aStatements,
, mCancelRequested(false) , mCancelRequested(false)
, mMutex(aConnection->sharedAsyncExecutionMutex) , mMutex(aConnection->sharedAsyncExecutionMutex)
, mDBMutex(aConnection->sharedDBMutex) , mDBMutex(aConnection->sharedDBMutex)
, mRequestStartDate(TimeStamp::Now()) , mRequestStartDate(TimeStamp::Now())
{ {
(void)mStatements.SwapElements(aStatements); (void)mStatements.SwapElements(aStatements);
NS_ASSERTION(mStatements.Length(), "We weren't given any statements!"); NS_ASSERTION(mStatements.Length(), "We weren't given any statements!");
NS_IF_ADDREF(mCallback);
} }
AsyncExecuteStatements::~AsyncExecuteStatements() AsyncExecuteStatements::~AsyncExecuteStatements()
{ {
MOZ_ASSERT(!mCallback, "Never called the Completion callback!");
MOZ_ASSERT(!mHasTransaction, "There should be no transaction at this point"); MOZ_ASSERT(!mHasTransaction, "There should be no transaction at this point");
if (mCallback) {
// NS_ProxyRelease(mCallingThread, mCallback.forget());
nsCOMPtr<nsIRunnable> ev =
new ProxyReleaseEvent<mozIStorageStatementCallback>(mCallback.forget());
if (NS_FAILED(mCallingThread->Dispatch(ev, NS_DISPATCH_NORMAL))) {
NS_WARNING("AsyncExecuteStatements dtor failed proxy release");
}
}
} }
bool bool
@ -462,16 +377,30 @@ AsyncExecuteStatements::notifyComplete()
mHasTransaction = false; mHasTransaction = false;
} }
// Always generate a completion notification; it is what guarantees that our // This will take ownership of mCallback and make sure its destruction will
// destruction does not happen here on the async thread. // happen on the owner thread.
RefPtr<CompletionNotifier> completionEvent = (void)mCallingThread->Dispatch(
new CompletionNotifier(mCallback, mState); NS_NewRunnableMethod(this, &AsyncExecuteStatements::notifyCompleteOnCallingThread),
NS_DISPATCH_NORMAL);
// We no longer own mCallback (the CompletionNotifier takes ownership). return NS_OK;
mCallback = nullptr; }
(void)mCallingThread->Dispatch(completionEvent, NS_DISPATCH_NORMAL);
nsresult
AsyncExecuteStatements::notifyCompleteOnCallingThread() {
#ifdef DEBUG
bool onCallingThread = false;
(void)mCallingThread->IsOnCurrentThread(&onCallingThread);
MOZ_ASSERT(onCallingThread);
#endif
// Take ownership of mCallback and responsibility for freeing it when we
// release it. Any notifyResultsOnCallingThread and notifyErrorOnCallingThread
// calls on the stack spinning the event loop have guaranteed their safety by
// creating their own strong reference before invoking the callback.
nsCOMPtr<mozIStorageStatementCallback> callback = mCallback.forget();
if (callback) {
(void)callback->HandleCompletion(mState);
}
return NS_OK; return NS_OK;
} }
@ -500,27 +429,63 @@ AsyncExecuteStatements::notifyError(mozIStorageError *aError)
if (!mCallback) if (!mCallback)
return NS_OK; return NS_OK;
RefPtr<ErrorNotifier> notifier = (void)mCallingThread->Dispatch(
new ErrorNotifier(mCallback, aError, this); NS_NewRunnableMethodWithArg<nsCOMPtr<mozIStorageError>>(this, &AsyncExecuteStatements::notifyErrorOnCallingThread, aError),
NS_ENSURE_TRUE(notifier, NS_ERROR_OUT_OF_MEMORY); NS_DISPATCH_NORMAL);
return mCallingThread->Dispatch(notifier, NS_DISPATCH_NORMAL); return NS_OK;
}
nsresult
AsyncExecuteStatements::notifyErrorOnCallingThread(mozIStorageError *aError) {
#ifdef DEBUG
bool onCallingThread = false;
(void)mCallingThread->IsOnCurrentThread(&onCallingThread);
MOZ_ASSERT(onCallingThread);
#endif
// Acquire our own strong reference so that if the callback spins a nested
// event loop and notifyCompleteOnCallingThread is executed, forgetting
// mCallback, we still have a valid/strong reference that won't be freed until
// we exit.
nsCOMPtr<mozIStorageStatementCallback> callback = mCallback;
if (shouldNotify() && callback) {
(void)callback->HandleError(aError);
}
return NS_OK;
} }
nsresult nsresult
AsyncExecuteStatements::notifyResults() AsyncExecuteStatements::notifyResults()
{ {
mMutex.AssertNotCurrentThreadOwns(); mMutex.AssertNotCurrentThreadOwns();
NS_ASSERTION(mCallback, "notifyResults called without a callback!"); MOZ_ASSERT(mCallback, "notifyResults called without a callback!");
RefPtr<CallbackResultNotifier> notifier = // This takes ownership of mResultSet, a new one will be generated in
new CallbackResultNotifier(mCallback, mResultSet, this); // buildAndNotifyResults() when further results will arrive.
NS_ENSURE_TRUE(notifier, NS_ERROR_OUT_OF_MEMORY); (void)mCallingThread->Dispatch(
NS_NewRunnableMethodWithArg<RefPtr<ResultSet>>(this, &AsyncExecuteStatements::notifyResultsOnCallingThread, mResultSet.forget()),
NS_DISPATCH_NORMAL);
nsresult rv = mCallingThread->Dispatch(notifier, NS_DISPATCH_NORMAL); return NS_OK;
if (NS_SUCCEEDED(rv)) }
mResultSet = nullptr; // we no longer own it on success
return rv; nsresult
AsyncExecuteStatements::notifyResultsOnCallingThread(ResultSet *aResultSet)
{
#ifdef DEBUG
bool onCallingThread = false;
(void)mCallingThread->IsOnCurrentThread(&onCallingThread);
MOZ_ASSERT(onCallingThread);
#endif
// Acquire our own strong reference so that if the callback spins a nested
// event loop and notifyCompleteOnCallingThread is executed, forgetting
// mCallback, we still have a valid/strong reference that won't be freed until
// we exit.
nsCOMPtr<mozIStorageStatementCallback> callback = mCallback;
if (shouldNotify() && callback) {
(void)callback->HandleResult(aResultSet);
}
return NS_OK;
} }
NS_IMPL_ISUPPORTS( NS_IMPL_ISUPPORTS(

View File

@ -82,6 +82,14 @@ public:
*/ */
bool shouldNotify(); bool shouldNotify();
/**
* Used by notifyComplete(), notifyError() and notifyResults() to notify on
* the calling thread.
*/
nsresult notifyCompleteOnCallingThread();
nsresult notifyErrorOnCallingThread(mozIStorageError *aError);
nsresult notifyResultsOnCallingThread(ResultSet *aResultSet);
private: private:
AsyncExecuteStatements(StatementDataArray &aStatements, AsyncExecuteStatements(StatementDataArray &aStatements,
Connection *aConnection, Connection *aConnection,
@ -186,7 +194,10 @@ private:
RefPtr<Connection> mConnection; RefPtr<Connection> mConnection;
sqlite3 *mNativeConnection; sqlite3 *mNativeConnection;
bool mHasTransaction; bool mHasTransaction;
mozIStorageStatementCallback *mCallback; // Note, this may not be a threadsafe object - never addref/release off
// the calling thread. We take a reference when this is created, and
// release it in the CompletionNotifier::Run() call back to this thread.
nsCOMPtr<mozIStorageStatementCallback> mCallback;
nsCOMPtr<nsIThread> mCallingThread; nsCOMPtr<nsIThread> mCallingThread;
RefPtr<ResultSet> mResultSet; RefPtr<ResultSet> mResultSet;