Merge mozilla-central to autoland

This commit is contained in:
Carsten "Tomcat" Book 2017-04-05 14:52:39 +02:00
Родитель c45153c1c9 7a670cdd01
Коммит 5d8f1744bf
175 изменённых файлов: 3455 добавлений и 1603 удалений

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

@ -789,8 +789,16 @@ pref("browser.selfsupport.url", "https://self-repair.mozilla.org/%LOCALE%/repair
pref("browser.sessionstore.resume_from_crash", true);
pref("browser.sessionstore.resume_session_once", false);
// minimal interval between two save operations in milliseconds
pref("browser.sessionstore.interval", 15000);
// Minimal interval between two save operations in milliseconds (while the user is active).
pref("browser.sessionstore.interval", 15000); // 15 seconds
// Minimal interval between two save operations in milliseconds (while the user is idle).
pref("browser.sessionstore.interval.idle", 3600000); // 1h
// Time (ms) before we assume that the user is idle and that we don't need to
// collect/save the session quite as often.
pref("browser.sessionstore.idleDelay", 180000); // 3 minutes
// on which sites to save text data, POSTDATA and cookies
// 0 = everywhere, 1 = unencrypted sites, 2 = nowhere
pref("browser.sessionstore.privacy_level", 0);

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

@ -247,8 +247,6 @@ var whitelist = new Set([
{file: "resource://gre/modules/PropertyListUtils.jsm", platforms: ["linux", "win"]},
// Bug 1351093
{file: "resource://gre/modules/Sntp.jsm"},
// Bug 1351980
{file: "resource://gre/modules/UserAgentOverrides.jsm"},
// Bug 1351097
{file: "resource://gre/modules/accessibility/AccessFu.jsm"},
// Bug 1351099

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

@ -34,7 +34,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "AlertsService", "@mozilla.org/alerts-s
RemotePrompt:false, SelfSupportBackend:false, SessionStore:false,
ShellService:false, SimpleServiceDiscovery:false, TabCrashHandler:false,
Task:false, UITour:false, WebChannel:false,
WindowsRegistry:false, webrtcUI:false */
WindowsRegistry:false, webrtcUI:false, UserAgentOverrides: false */
/**
* IF YOU ADD OR REMOVE FROM THIS LIST, PLEASE UPDATE THE LIST ABOVE AS WELL.
@ -89,6 +89,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "AlertsService", "@mozilla.org/alerts-s
["WebChannel", "resource://gre/modules/WebChannel.jsm"],
["WindowsRegistry", "resource://gre/modules/WindowsRegistry.jsm"],
["webrtcUI", "resource:///modules/webrtcUI.jsm"],
["UserAgentOverrides", "resource://gre/modules/UserAgentOverrides.jsm"],
].forEach(([name, resource]) => XPCOMUtils.defineLazyModuleGetter(this, name, resource));
if (AppConstants.MOZ_CRASHREPORTER) {
@ -431,6 +432,8 @@ BrowserGlue.prototype = {
// and e10s are active together.
E10SAccessibilityCheck.init();
}
UserAgentOverrides.init();
},
// cleanup (called on application shutdown)
@ -470,6 +473,8 @@ BrowserGlue.prototype = {
os.removeObserver(this, "browser-search-engine-modified");
os.removeObserver(this, "flash-plugin-hang");
os.removeObserver(this, "xpi-signature-changed");
UserAgentOverrides.uninit();
},
_onAppDefaults: function BG__onAppDefaults() {

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

@ -30,22 +30,27 @@ XPCOMUtils.defineLazyModuleGetter(this, "SessionFile",
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
// Minimal interval between two save operations (in milliseconds).
XPCOMUtils.defineLazyGetter(this, "gInterval", function() {
const PREF = "browser.sessionstore.interval";
// Observer that updates the cached value when the preference changes.
Services.prefs.addObserver(PREF, () => {
this.gInterval = Services.prefs.getIntPref(PREF);
// Cancel any pending runs and call runDelayed() with
// zero to apply the newly configured interval.
SessionSaverInternal.cancel();
SessionSaverInternal.runDelayed(0);
}, false);
return Services.prefs.getIntPref(PREF);
});
/*
* Minimal interval between two save operations (in milliseconds).
*
* To save system resources, we generally do not save changes immediately when
* a change is detected. Rather, we wait a little to see if this change is
* followed by other changes, in which case only the last write is necessary.
* This delay is defined by "browser.sessionstore.interval".
*
* Furthermore, when the user is not actively using the computer, webpages
* may still perform changes that require (re)writing to sessionstore, e.g.
* updating Session Cookies or DOM Session Storage, or refreshing, etc. We
* expect that these changes are much less critical to the user and do not
* need to be saved as often. In such cases, we increase the delay to
* "browser.sessionstore.interval.idle".
*
* When the user returns to the computer, if a save is pending, we reschedule
* it to happen soon, with "browser.sessionstore.interval".
*/
const PREF_INTERVAL_ACTIVE = "browser.sessionstore.interval";
const PREF_INTERVAL_IDLE = "browser.sessionstore.interval.idle";
const PREF_IDLE_DELAY = "browser.sessionstore.idleDelay";
// Notify observers about a given topic with a given subject.
function notify(subject, topic) {
@ -118,6 +123,36 @@ var SessionSaverInternal = {
*/
_lastSaveTime: 0,
/**
* `true` if the user has been idle for at least
* `SessionSaverInternal._intervalWhileIdle` ms. Idleness is computed
* with `nsIIdleService`.
*/
_isIdle: false,
/**
* `true` if the user was idle when we last scheduled a delayed save.
* See `_isIdle` for details on idleness.
*/
_wasIdle: false,
/**
* Minimal interval between two save operations (in ms), while the user
* is active.
*/
_intervalWhileActive: null,
/**
* Minimal interval between two save operations (in ms), while the user
* is idle.
*/
_intervalWhileIdle: null,
/**
* How long before we assume that the user is idle (ms).
*/
_idleDelay: null,
/**
* Immediately saves the current session to disk.
*/
@ -141,9 +176,11 @@ var SessionSaverInternal = {
}
// Interval until the next disk operation is allowed.
delay = Math.max(this._lastSaveTime + gInterval - Date.now(), delay, 0);
let interval = this._isIdle ? this._intervalWhileIdle : this._intervalWhileActive;
delay = Math.max(this._lastSaveTime + interval - Date.now(), delay, 0);
// Schedule a state save.
this._wasIdle = this._isIdle;
this._timeoutID = setTimeout(() => this._saveStateAsync(), delay);
},
@ -163,6 +200,29 @@ var SessionSaverInternal = {
this._timeoutID = null;
},
/**
* Observe idle/ active notifications.
*/
observe(subject, topic, data) {
switch (topic) {
case "idle":
this._isIdle = true;
break;
case "active":
this._isIdle = false;
if (this._timeoutID && this._wasIdle) {
// A state save has been scheduled while we were idle.
// Replace it by an active save.
clearTimeout(this._timeoutID);
this._timeoutID = null;
this.runDelayed();
}
break;
default:
throw new Error(`Unexpected change value ${topic}`);
}
},
/**
* Saves the current session state. Collects data and writes to disk.
*
@ -268,3 +328,33 @@ var SessionSaverInternal = {
}, console.error);
},
};
XPCOMUtils.defineLazyPreferenceGetter(SessionSaverInternal, "_intervalWhileActive", PREF_INTERVAL_ACTIVE,
15000 /* 15 seconds */, () => {
// Cancel any pending runs and call runDelayed() with
// zero to apply the newly configured interval.
SessionSaverInternal.cancel();
SessionSaverInternal.runDelayed(0);
});
XPCOMUtils.defineLazyPreferenceGetter(SessionSaverInternal, "_intervalWhileIdle", PREF_INTERVAL_IDLE,
3600000 /* 1 h */);
XPCOMUtils.defineLazyPreferenceGetter(SessionSaverInternal, "_idleDelay", PREF_IDLE_DELAY,
180000 /* 3 minutes */, (key, previous, latest) => {
// Update the idle observer for the new `PREF_IDLE_DELAY` value. Here we need
// to re-fetch the service instead of the original one in use; This is for a
// case that the Mock service in the unit test needs to be fetched to
// replace the original one.
var idleService = Cc["@mozilla.org/widget/idleservice;1"].getService(Ci.nsIIdleService);
if (previous != undefined) {
idleService.removeIdleObserver(SessionSaverInternal, previous);
}
if (latest != undefined) {
idleService.addIdleObserver(SessionSaverInternal, latest);
}
});
var idleService = Cc["@mozilla.org/widget/idleservice;1"].getService(Ci.nsIIdleService);
idleService.addIdleObserver(SessionSaverInternal, SessionSaverInternal._idleDelay);

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

@ -210,6 +210,7 @@ skip-if = true # Needs to be rewritten as Marionette test, bug 995916
[browser_739805.js]
[browser_819510_perwindowpb.js]
skip-if = (os == 'win' && bits == 64) # Bug 1284312
[browser_not_collect_when_idle.js]
# Disabled for frequent intermittent failures
[browser_464620_a.js]

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

@ -0,0 +1,122 @@
/** Test for Bug 1305950 **/
Cu.import("resource://testing-common/MockRegistrar.jsm", this);
// The mock idle service.
var idleService = {
_observers: new Set(),
_activity: {
addCalls: [],
removeCalls: [],
observerFires: [],
},
_reset() {
this._observers.clear();
this._activity.addCalls = [];
this._activity.removeCalls = [];
this._activity.observerFires = [];
},
_fireObservers(state) {
for (let observer of this._observers.values()) {
observer.observe(observer, state, null);
this._activity.observerFires.push(state);
}
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIIdleService]),
idleTime: 19999,
addIdleObserver(observer, time) {
this._observers.add(observer);
this._activity.addCalls.push(time);
},
removeIdleObserver(observer, time) {
this._observers.delete(observer);
this._activity.removeCalls.push(time);
}
};
add_task(async function testIntervalChanges() {
const PREF_SS_INTERVAL = 2000;
// We speed up the interval between session saves to ensure that the test
// runs quickly.
Services.prefs.setIntPref("browser.sessionstore.interval", PREF_SS_INTERVAL);
// Increase `idleDelay` to 1 day to update the pre-registered idle observer
// in "real" idle service to avoid possible interference, especially for the
// CI server environment.
Services.prefs.setIntPref("browser.sessionstore.idleDelay", 86400000);
// Mock an idle service.
let fakeIdleService = MockRegistrar.register("@mozilla.org/widget/idleservice;1", idleService);
idleService._reset();
registerCleanupFunction(function() {
Services.prefs.clearUserPref("browser.sessionstore.interval");
MockRegistrar.unregister(fakeIdleService);
});
// Hook idle/active observer to mock idle service by changing pref `idleDelay`
// to a whatever value, which will not be used.
Services.prefs.setIntPref("browser.sessionstore.idleDelay", 5000000);
// Wait a `sessionstore-state-write-complete` event from any previous
// scheduled state write. This is needed since the `_lastSaveTime` in
// runDelayed() should be set at least once, or the `_isIdle` flag will not
// become effective.
// We wait at most 30 sec which is about as long as the timeout for the
// regular whole test case, and we don't expect the write event comes fast
// enough for an immediate `waitForSaveState()` from now.
await new Promise(function(resolve, reject) {
waitForTopic("sessionstore-state-write-complete", 30 * 1000, function(isSuccessful) {
if (!isSuccessful) {
reject(new Error("Timeout: didn't get any `sessionstore-state-write-complete` event"));
} else {
resolve();
}
});
});
info("Got the state write event, start to test idle mode...");
// Enter the "idle mode" (raise the `_isIdle` flag) by firing idle
// observer of mock idle service.
idleService._fireObservers("idle");
// Cancel any possible state save, which is not related with this test to
// avoid interference.
SessionSaver.cancel();
let p1 = promiseSaveState();
// Schedule a state write, which is expeced to be postponed after about
// `browser.sessionstore.interval.idle` ms, since the idle flag was just set.
SessionSaver.runDelayed(0);
// We expect `p1` hits the timeout.
await Assert.rejects(p1, null, "[Test 1A] No state write during idle.");
// Test again for better reliability. Same, we expect following promise hits
// the timeout.
await Assert.rejects(promiseSaveState(), null, "[Test 1B] Again: No state write during idle.");
// Back to the active mode.
info("Start to test active mode...");
idleService._fireObservers("active");
await new Promise(function(resolve, reject) {
waitForTopic("sessionstore-state-write-complete", PREF_SS_INTERVAL + 10000, function(isSuccessful) {
if (!isSuccessful) {
reject(new Error("Timeout: didn't get any `sessionstore-state-write-complete` event"));
} else {
resolve();
}
});
});
info("[Test 2] Has state write during active.");
});

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

@ -247,13 +247,13 @@ function waitForSaveState(aCallback) {
return waitForTopic("sessionstore-state-write-complete", timeout, aCallback);
}
function promiseSaveState() {
return new Promise(resolve => {
return new Promise((resolve, reject) => {
waitForSaveState(isSuccessful => {
if (!isSuccessful) {
throw new Error("timeout");
reject(new Error("Save state timeout"));
} else {
resolve();
}
resolve();
});
});
}

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

@ -433,5 +433,6 @@ function enableServiceWorkerDebugging() {
["dom.ipc.processCount", 1],
]};
SpecialPowers.pushPrefEnv(options, done);
Services.ppmm.releaseCachedProcesses();
});
}

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

@ -46,14 +46,14 @@ public:
NS_DECL_NSIMUTATIONOBSERVER
NS_DECL_NSIBFCACHEENTRY
nsExpirationState *GetExpirationState() { return &mExpirationState; }
private:
~nsSHEntryShared();
friend class nsSHEntry;
friend class HistoryTracker;
friend class nsExpirationTracker<nsSHEntryShared, 3>;
nsExpirationState *GetExpirationState() { return &mExpirationState; }
static already_AddRefed<nsSHEntryShared> Duplicate(nsSHEntryShared* aEntry);

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

@ -56,11 +56,11 @@ extern mozilla::LazyLogModule gContentSinkLogModuleInfo;
#define SINK_LOG_TEST(_lm, _bit) (int((_lm)->Level()) & (_bit))
#define SINK_TRACE(_lm, _bit, _args) \
PR_BEGIN_MACRO \
do { \
if (SINK_LOG_TEST(_lm, _bit)) { \
PR_LogPrint _args; \
printf_stderr _args; \
} \
PR_END_MACRO
} while(0)
#else
#define SINK_TRACE(_lm, _bit, _args)

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

@ -315,7 +315,9 @@ nsDOMWindowUtils::Redraw(uint32_t aCount, uint32_t *aDurationOut)
rootFrame->InvalidateFrame();
#if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False);
if (!gfxPlatform::IsHeadless()) {
XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False);
}
#endif
*aDurationOut = PR_IntervalToMilliseconds(PR_IntervalNow() - iStart);

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

@ -1203,8 +1203,9 @@ nsDOMStyleSheetSetList::EnsureFresh()
}
// ==================================================================
nsIDocument::SelectorCache::SelectorCache()
: nsExpirationTracker<SelectorCacheKey, 4>(1000, "nsIDocument::SelectorCache")
nsIDocument::SelectorCache::SelectorCache(nsIEventTarget* aEventTarget)
: nsExpirationTracker<SelectorCacheKey, 4>(
1000, "nsIDocument::SelectorCache", aEventTarget)
{ }
nsIDocument::SelectorCache::~SelectorCache()

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

@ -1068,7 +1068,7 @@ public:
: public nsExpirationTracker<SelectorCacheKey, 4>
{
public:
SelectorCache();
explicit SelectorCache(nsIEventTarget* aEventTarget);
// CacheList takes ownership of aSelectorList.
void CacheList(const nsAString& aSelector, nsCSSSelectorList* aSelectorList);
@ -1091,9 +1091,12 @@ public:
nsClassHashtable<nsStringHashKey, nsCSSSelectorList> mTable;
};
SelectorCache& GetSelectorCache()
{
return mSelectorCache;
SelectorCache& GetSelectorCache() {
if (!mSelectorCache) {
mSelectorCache =
new SelectorCache(EventTargetFor(mozilla::TaskCategory::Other));
}
return *mSelectorCache;
}
// Get the root <html> element, or return null if there isn't one (e.g.
// if the root isn't <html>)
@ -2916,7 +2919,8 @@ protected:
private:
mutable std::bitset<eDeprecatedOperationCount> mDeprecationWarnedAbout;
mutable std::bitset<eDocumentWarningCount> mDocWarningWarnedAbout;
SelectorCache mSelectorCache;
// Lazy-initialization to have mDocGroup initialized in prior to mSelectorCache.
nsAutoPtr<SelectorCache> mSelectorCache;
protected:
~nsIDocument();

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

@ -2225,25 +2225,47 @@ ScopedLazyBind::UnwrapImpl()
////////////////////////////////////////
void
Intersect(uint32_t srcSize, int32_t dstStartInSrc, uint32_t dstSize,
uint32_t* const out_intStartInSrc, uint32_t* const out_intStartInDst,
uint32_t* const out_intSize)
bool
Intersect(const int32_t srcSize, const int32_t read0, const int32_t readSize,
int32_t* const out_intRead0, int32_t* const out_intWrite0,
int32_t* const out_intSize)
{
// Only >0 if dstStartInSrc is >0:
// 0 3 // src coords
// | [========] // dst box
// ^--^
*out_intStartInSrc = std::max<int32_t>(0, dstStartInSrc);
MOZ_ASSERT(srcSize >= 0);
MOZ_ASSERT(readSize >= 0);
const auto read1 = int64_t(read0) + readSize;
// Only >0 if dstStartInSrc is <0:
//-6 0 // src coords
// [=====|==] // dst box
// ^-----^
*out_intStartInDst = std::max<int32_t>(0, 0 - dstStartInSrc);
int32_t intRead0 = read0; // Clearly doesn't need validation.
int64_t intWrite0 = 0;
int64_t intSize = readSize;
int32_t intEndInSrc = std::min<int32_t>(srcSize, dstStartInSrc + dstSize);
*out_intSize = std::max<int32_t>(0, intEndInSrc - *out_intStartInSrc);
if (read1 <= 0 || read0 >= srcSize) {
// Disjoint ranges.
intSize = 0;
} else {
if (read0 < 0) {
const auto diff = int64_t(0) - read0;
MOZ_ASSERT(diff >= 0);
intRead0 = 0;
intWrite0 = diff;
intSize -= diff;
}
if (read1 > srcSize) {
const auto diff = int64_t(read1) - srcSize;
MOZ_ASSERT(diff >= 0);
intSize -= diff;
}
if (!CheckedInt<int32_t>(intWrite0).isValid() ||
!CheckedInt<int32_t>(intSize).isValid())
{
return false;
}
}
*out_intRead0 = intRead0;
*out_intWrite0 = intWrite0;
*out_intSize = intSize;
return true;
}
////////////////////////////////////////////////////////////////////////////////

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

@ -2164,10 +2164,9 @@ private:
////
void
Intersect(uint32_t srcSize, int32_t dstStartInSrc, uint32_t dstSize,
uint32_t* const out_intStartInSrc, uint32_t* const out_intStartInDst,
uint32_t* const out_intSize);
bool
Intersect(int32_t srcSize, int32_t read0, int32_t readSize, int32_t* out_intRead0,
int32_t* out_intWrite0, int32_t* out_intSize);
////

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

@ -1556,18 +1556,32 @@ WebGLContext::ReadPixelsImpl(GLint x, GLint y, GLsizei rawWidth, GLsizei rawHeig
return;
}
////
int32_t readX, readY;
int32_t writeX, writeY;
int32_t rwWidth, rwHeight;
if (!Intersect(srcWidth, x, width, &readX, &writeX, &rwWidth) ||
!Intersect(srcHeight, y, height, &readY, &writeY, &rwHeight))
{
ErrorOutOfMemory("readPixels: Bad subrect selection.");
return;
}
////////////////
// Now that the errors are out of the way, on to actually reading!
OnBeforeReadCall();
uint32_t readX, readY;
uint32_t writeX, writeY;
uint32_t rwWidth, rwHeight;
Intersect(srcWidth, x, width, &readX, &writeX, &rwWidth);
Intersect(srcHeight, y, height, &readY, &writeY, &rwHeight);
if (!rwWidth || !rwHeight) {
// Disjoint rects, so we're done already.
DummyReadFramebufferOperation("readPixels");
return;
}
if (rwWidth == uint32_t(width) && rwHeight == uint32_t(height)) {
if (uint32_t(rwWidth) == width &&
uint32_t(rwHeight) == height)
{
DoReadPixelsAndConvert(srcFormat->format, x, y, width, height, packFormat,
packType, dest, dataLen, rowStride);
return;
@ -1586,12 +1600,6 @@ WebGLContext::ReadPixelsImpl(GLint x, GLint y, GLsizei rawWidth, GLsizei rawHeig
////////////////////////////////////
// Read only the in-bounds pixels.
if (!rwWidth || !rwHeight) {
// There aren't any, so we're 'done'.
DummyReadFramebufferOperation("readPixels");
return;
}
if (IsWebGL2()) {
if (!mPixelStore_PackRowLength) {
gl->fPixelStorei(LOCAL_GL_PACK_ROW_LENGTH,
@ -1611,7 +1619,7 @@ WebGLContext::ReadPixelsImpl(GLint x, GLint y, GLsizei rawWidth, GLsizei rawHeig
uint8_t* row = (uint8_t*)dest + writeX * bytesPerPixel;
row += writeY * rowStride;
for (uint32_t j = 0; j < rwHeight; j++) {
for (uint32_t j = 0; j < uint32_t(rwHeight); j++) {
DoReadPixelsAndConvert(srcFormat->format, readX, readY+j, rwWidth, 1,
packFormat, packType, row, dataLen, rowStride);
row += rowStride;

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

@ -2011,11 +2011,15 @@ DoCopyTexOrSubImage(WebGLContext* webgl, const char* funcName, bool isSubImage,
////
uint32_t readX, readY;
uint32_t writeX, writeY;
uint32_t rwWidth, rwHeight;
Intersect(srcTotalWidth, xWithinSrc, dstWidth, &readX, &writeX, &rwWidth);
Intersect(srcTotalHeight, yWithinSrc, dstHeight, &readY, &writeY, &rwHeight);
int32_t readX, readY;
int32_t writeX, writeY;
int32_t rwWidth, rwHeight;
if (!Intersect(srcTotalWidth, xWithinSrc, dstWidth, &readX, &writeX, &rwWidth) ||
!Intersect(srcTotalHeight, yWithinSrc, dstHeight, &readY, &writeY, &rwHeight))
{
webgl->ErrorOutOfMemory("%s: Bad subrect selection.", funcName);
return false;
}
writeX += xOffset;
writeY += yOffset;
@ -2028,7 +2032,7 @@ DoCopyTexOrSubImage(WebGLContext* webgl, const char* funcName, bool isSubImage,
if (!isSubImage) {
UniqueBuffer buffer;
if (rwWidth != dstWidth || rwHeight != dstHeight) {
if (uint32_t(rwWidth) != dstWidth || uint32_t(rwHeight) != dstHeight) {
const auto& pi = idealUnpack->ToPacking();
CheckedUint32 byteCount = BytesPerPixel(pi);
byteCount *= dstWidth;

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

@ -746,6 +746,10 @@ ContentParent::IsMaxProcessCountReached(const nsAString& aContentProcessType)
/*static*/ void
ContentParent::ReleaseCachedProcesses()
{
if (!GetPoolSize(NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE))) {
return;
}
// We might want to extend this for other process types as well in the future...
nsTArray<ContentParent*>& contentParents = GetOrCreatePool(NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE));
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();

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

@ -14,16 +14,11 @@
#include "prenv.h"
#include "mozilla/SizePrintfMacros.h"
#ifdef PR_LOGGING
extern mozilla::LazyLogModule gMediaDemuxerLog;
#define ADTSLOG(msg, ...) \
MOZ_LOG(gMediaDemuxerLog, LogLevel::Debug, ("ADTSDemuxer " msg, ##__VA_ARGS__))
#define ADTSLOGV(msg, ...) \
MOZ_LOG(gMediaDemuxerLog, LogLevel::Verbose, ("ADTSDemuxer " msg, ##__VA_ARGS__))
#else
#define ADTSLOG(msg, ...) do {} while (false)
#define ADTSLOGV(msg, ...) do {} while (false)
#endif
namespace mozilla {
namespace adts {

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

@ -17,16 +17,11 @@
#include "TimeUnits.h"
#include "prenv.h"
#ifdef PR_LOGGING
extern mozilla::LazyLogModule gMediaDemuxerLog;
#define MP3LOG(msg, ...) \
MOZ_LOG(gMediaDemuxerLog, LogLevel::Debug, ("MP3Demuxer " msg, ##__VA_ARGS__))
#define MP3LOGV(msg, ...) \
MOZ_LOG(gMediaDemuxerLog, LogLevel::Verbose, ("MP3Demuxer " msg, ##__VA_ARGS__))
#else
#define MP3LOG(msg, ...)
#define MP3LOGV(msg, ...)
#endif
using mozilla::media::TimeUnit;
using mozilla::media::TimeInterval;

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

@ -128,9 +128,7 @@ public:
StaticRefPtr<MediaMemoryTracker> MediaMemoryTracker::sUniqueInstance;
#if defined(PR_LOGGING)
LazyLogModule gMediaTimerLog("MediaTimer");
#endif
void
MediaDecoder::InitStatics()

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

@ -15,16 +15,11 @@
#include "VideoUtils.h"
#include "TimeUnits.h"
#ifdef PR_LOGGING
extern mozilla::LazyLogModule gMediaDemuxerLog;
#define LOG(msg, ...) \
MOZ_LOG(gMediaDemuxerLog, LogLevel::Debug, ("FlacDemuxer " msg, ##__VA_ARGS__))
#define LOGV(msg, ...) \
MOZ_LOG(gMediaDemuxerLog, LogLevel::Verbose, ("FlacDemuxer " msg, ##__VA_ARGS__))
#else
#define LOG(msg, ...) do {} while (false)
#define LOGV(msg, ...) do {} while (false)
#endif
using namespace mozilla::media;

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

@ -48,16 +48,18 @@ namespace camera {
// called "VideoCapture". On Windows this is a thread with an event loop
// suitable for UI access.
// InputObserver is owned by CamerasParent, and it has a ref to CamerasParent
void InputObserver::OnDeviceChange() {
LOG((__PRETTY_FUNCTION__));
MOZ_ASSERT(mParent);
RefPtr<InputObserver> self(this);
RefPtr<nsIRunnable> ipc_runnable =
media::NewRunnableFrom([this]() -> nsresult {
if (mParent->IsShuttingDown()) {
media::NewRunnableFrom([self]() -> nsresult {
if (self->mParent->IsShuttingDown()) {
return NS_ERROR_FAILURE;
}
Unused << mParent->SendDeviceChange();
Unused << self->mParent->SendDeviceChange();
return NS_OK;
});
@ -354,11 +356,11 @@ CamerasParent::SetupEngine(CaptureEngine aCapEngine)
return false;
}
InputObserver** observer = mObservers.AppendElement(new InputObserver(this));
RefPtr<InputObserver>* observer = mObservers.AppendElement(new InputObserver(this));
auto device_info = engine->get()->GetOrCreateVideoCaptureDeviceInfo();
MOZ_ASSERT(device_info);
if (device_info) {
device_info->RegisterVideoInputFeedBack(**observer);
device_info->RegisterVideoInputFeedBack(*(observer->get()));
}
return true;
@ -398,9 +400,7 @@ CamerasParent::CloseEngines()
}
}
for (InputObserver* observer : mObservers) {
delete observer;
}
// the observers hold references to us
mObservers.Clear();
mWebRTCAlive = false;

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

@ -69,6 +69,8 @@ private:
class InputObserver : public webrtc::VideoInputFeedBack
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InputObserver)
explicit InputObserver(CamerasParent* aParent)
: mParent(aParent) {};
virtual void OnDeviceChange();
@ -76,6 +78,8 @@ public:
friend CamerasParent;
private:
~InputObserver() {}
RefPtr<CamerasParent> mParent;
};
@ -161,7 +165,7 @@ protected:
// Above 2 are PBackground only, but this is potentially
// read cross-thread.
mozilla::Atomic<bool> mWebRTCAlive;
nsTArray<InputObserver*> mObservers;
nsTArray<RefPtr<InputObserver>> mObservers;
};
PCamerasParent* CreateCamerasParent();

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

@ -151,11 +151,9 @@ static const char kDirectoryServiceContractID[] = "@mozilla.org/file/directory_s
#define kPluginRegistryFilename NS_LITERAL_CSTRING("pluginreg.dat")
#ifdef PLUGIN_LOGGING
LazyLogModule nsPluginLogging::gNPNLog(NPN_LOG_NAME);
LazyLogModule nsPluginLogging::gNPPLog(NPP_LOG_NAME);
LazyLogModule nsPluginLogging::gPluginLog(PLUGIN_LOG_NAME);
#endif
// #defines for plugin cache and prefs
#define NS_PREF_MAX_NUM_CACHED_INSTANCES "browser.plugins.max_num_cached_plugins"

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

@ -10,10 +10,6 @@
#include "mozilla/Logging.h"
#ifndef PLUGIN_LOGGING // allow external override
#define PLUGIN_LOGGING 1 // master compile-time switch for pluging logging
#endif
////////////////////////////////////////////////////////////////////////////////
// Basic Plugin Logging Usage Instructions
//
@ -43,8 +39,6 @@
// https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Gecko_Logging
#ifdef PLUGIN_LOGGING
class nsPluginLogging
{
public:
@ -53,38 +47,10 @@ public:
static mozilla::LazyLogModule gPluginLog; // general plugin log
};
#endif // PLUGIN_LOGGING
// Quick-use macros
#ifdef PLUGIN_LOGGING
#define NPN_PLUGIN_LOG(a, b) \
PR_BEGIN_MACRO \
MOZ_LOG(nsPluginLogging::gNPNLog, a, b); \
PR_LogFlush(); \
PR_END_MACRO
#else
#define NPN_PLUGIN_LOG(a, b)
#endif
#ifdef PLUGIN_LOGGING
#define NPP_PLUGIN_LOG(a, b) \
PR_BEGIN_MACRO \
MOZ_LOG(nsPluginLogging::gNPPLog, a, b); \
PR_LogFlush(); \
PR_END_MACRO
#else
#define NPP_PLUGIN_LOG(a, b)
#endif
#ifdef PLUGIN_LOGGING
#define PLUGIN_LOG(a, b) \
PR_BEGIN_MACRO \
MOZ_LOG(nsPluginLogging::gPluginLog, a, b); \
PR_LogFlush(); \
PR_END_MACRO
#else
#define PLUGIN_LOG(a, b)
#endif
#define NPN_PLUGIN_LOG(a, b) MOZ_LOG(nsPluginLogging::gNPNLog, a, b)
#define NPP_PLUGIN_LOG(a, b) MOZ_LOG(nsPluginLogging::gNPPLog, a, b)
#define PLUGIN_LOG(a, b) MOZ_LOG(nsPluginLogging::gPluginLog, a, b)
#endif // nsPluginLogging_h__

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

@ -8,7 +8,7 @@ interface CommandEvent : Event {
readonly attribute DOMString? command;
void initCommandEvent(DOMString type,
boolean canBubble,
boolean cancelable,
DOMString? command);
optional boolean canBubble = false,
optional boolean cancelable = false,
optional DOMString? command = null);
};

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

@ -31,9 +31,9 @@ dictionary CompositionEventInit : UIEventInit {
partial interface CompositionEvent
{
void initCompositionEvent(DOMString typeArg,
boolean canBubbleArg,
boolean cancelableArg,
Window? viewArg,
DOMString? dataArg,
DOMString localeArg);
optional boolean canBubbleArg = false,
optional boolean cancelableArg = false,
optional Window? viewArg = null,
optional DOMString? dataArg = null,
optional DOMString localeArg = "");
};

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

@ -19,9 +19,9 @@ interface CustomEvent : Event
// initCustomEvent is a Gecko specific deprecated method.
[Throws]
void initCustomEvent(DOMString type,
boolean canBubble,
boolean cancelable,
any detail);
optional boolean canBubble = false,
optional boolean cancelable = false,
optional any detail = null);
};
dictionary CustomEventInit : EventInit

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

@ -48,10 +48,10 @@ dictionary DeviceMotionEventInit : EventInit {
// Mozilla extensions.
partial interface DeviceMotionEvent {
void initDeviceMotionEvent(DOMString type,
boolean canBubble,
boolean cancelable,
DeviceAccelerationInit acceleration,
DeviceAccelerationInit accelerationIncludingGravity,
DeviceRotationRateInit rotationRate,
double? interval);
optional boolean canBubble = false,
optional boolean cancelable = false,
optional DeviceAccelerationInit acceleration,
optional DeviceAccelerationInit accelerationIncludingGravity,
optional DeviceRotationRateInit rotationRate,
optional double? interval = null);
};

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

@ -14,12 +14,12 @@ interface DeviceOrientationEvent : Event
// initDeviceOrientationEvent is a Gecko specific deprecated method.
void initDeviceOrientationEvent(DOMString type,
boolean canBubble,
boolean cancelable,
double? alpha,
double? beta,
double? gamma,
boolean absolute);
optional boolean canBubble = false,
optional boolean cancelable = false,
optional double? alpha = null,
optional double? beta = null,
optional double? gamma = null,
optional boolean absolute = false);
};
dictionary DeviceOrientationEventInit : EventInit

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

@ -10,21 +10,21 @@ interface DragEvent : MouseEvent
readonly attribute DataTransfer? dataTransfer;
void initDragEvent(DOMString type,
boolean canBubble,
boolean cancelable,
Window? aView,
long aDetail,
long aScreenX,
long aScreenY,
long aClientX,
long aClientY,
boolean aCtrlKey,
boolean aAltKey,
boolean aShiftKey,
boolean aMetaKey,
unsigned short aButton,
EventTarget? aRelatedTarget,
DataTransfer? aDataTransfer);
optional boolean canBubble = false,
optional boolean cancelable = false,
optional Window? aView = null,
optional long aDetail = 0,
optional long aScreenX = 0,
optional long aScreenY = 0,
optional long aClientX = 0,
optional long aClientY = 0,
optional boolean aCtrlKey = false,
optional boolean aAltKey = false,
optional boolean aShiftKey = false,
optional boolean aMetaKey = false,
optional unsigned short aButton = 0,
optional EventTarget? aRelatedTarget = null,
optional DataTransfer? aDataTransfer = null);
};
dictionary DragEventInit : MouseEventInit

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

@ -50,7 +50,9 @@ interface Event {
[Pure]
readonly attribute DOMHighResTimeStamp timeStamp;
void initEvent(DOMString type, boolean bubbles, boolean cancelable);
void initEvent(DOMString type,
optional boolean bubbles = false,
optional boolean cancelable = false);
attribute boolean cancelBubble;
};

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

@ -11,10 +11,10 @@ interface HashChangeEvent : Event
readonly attribute DOMString newURL;
void initHashChangeEvent(DOMString typeArg,
boolean canBubbleArg,
boolean cancelableArg,
DOMString oldURLArg,
DOMString newURLArg);
optional boolean canBubbleArg = false,
optional boolean cancelableArg = false,
optional DOMString oldURLArg = "",
optional DOMString newURLArg = "");
};
dictionary HashChangeEventInit : EventInit

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

@ -225,13 +225,13 @@ interface KeyEvent
const unsigned long DOM_VK_WIN_OEM_CLEAR = 0xFE;
void initKeyEvent(DOMString type,
boolean canBubble,
boolean cancelable,
Window? view,
boolean ctrlKey,
boolean altKey,
boolean shiftKey,
boolean metaKey,
unsigned long keyCode,
unsigned long charCode);
optional boolean canBubble = false,
optional boolean cancelable = false,
optional Window? view = null,
optional boolean ctrlKey = false,
optional boolean altKey = false,
optional boolean shiftKey = false,
optional boolean metaKey = false,
optional unsigned long keyCode = 0,
optional unsigned long charCode = 0);
};

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

@ -43,10 +43,14 @@ interface MessageEvent : Event {
[Pure, Cached, Frozen]
readonly attribute sequence<MessagePort> ports;
void initMessageEvent(DOMString type, boolean bubbles, boolean cancelable,
any data, DOMString origin, DOMString lastEventId,
MessageEventSource? source,
sequence<MessagePort> ports);
void initMessageEvent(DOMString type,
optional boolean bubbles = false,
optional boolean cancelable = false,
optional any data = null,
optional DOMString origin = "",
optional DOMString lastEventId = "",
optional MessageEventSource? source = null,
optional sequence<MessagePort> ports = []);
};
dictionary MessageEventInit : EventInit {

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

@ -38,21 +38,21 @@ interface MouseEvent : UIEvent {
readonly attribute long movementY;
// Deprecated in DOM Level 3:
void initMouseEvent(DOMString typeArg,
boolean canBubbleArg,
boolean cancelableArg,
Window? viewArg,
long detailArg,
long screenXArg,
long screenYArg,
long clientXArg,
long clientYArg,
boolean ctrlKeyArg,
boolean altKeyArg,
boolean shiftKeyArg,
boolean metaKeyArg,
short buttonArg,
EventTarget? relatedTargetArg);
void initMouseEvent(DOMString typeArg,
optional boolean canBubbleArg = false,
optional boolean cancelableArg = false,
optional Window? viewArg = null,
optional long detailArg = 0,
optional long screenXArg = 0,
optional long screenYArg = 0,
optional long clientXArg = 0,
optional long clientYArg = 0,
optional boolean ctrlKeyArg = false,
optional boolean altKeyArg = false,
optional boolean shiftKeyArg = false,
optional boolean metaKeyArg = false,
optional short buttonArg = 0,
optional EventTarget? relatedTargetArg = null);
// Introduced in DOM Level 3:
boolean getModifierState(DOMString keyArg);
};
@ -91,23 +91,23 @@ partial interface MouseEvent
readonly attribute unsigned short mozInputSource;
void initNSMouseEvent(DOMString typeArg,
boolean canBubbleArg,
boolean cancelableArg,
Window? viewArg,
long detailArg,
long screenXArg,
long screenYArg,
long clientXArg,
long clientYArg,
boolean ctrlKeyArg,
boolean altKeyArg,
boolean shiftKeyArg,
boolean metaKeyArg,
short buttonArg,
EventTarget? relatedTargetArg,
float pressure,
unsigned short inputSourceArg);
void initNSMouseEvent(DOMString typeArg,
optional boolean canBubbleArg = false,
optional boolean cancelableArg = false,
optional Window? viewArg = null,
optional long detailArg = 0,
optional long screenXArg = 0,
optional long screenYArg = 0,
optional long clientXArg = 0,
optional long clientYArg = 0,
optional boolean ctrlKeyArg = false,
optional boolean altKeyArg = false,
optional boolean shiftKeyArg = false,
optional boolean metaKeyArg = false,
optional short buttonArg = 0,
optional EventTarget? relatedTargetArg = null,
optional float pressure = 0,
optional unsigned short inputSourceArg = 0);
[ChromeOnly]
readonly attribute boolean hitCluster; // True when touch occurs in a cluster of links

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

@ -12,19 +12,19 @@ interface MouseScrollEvent : MouseEvent
readonly attribute long axis;
void initMouseScrollEvent(DOMString type,
boolean canBubble,
boolean cancelable,
Window? view,
long detail,
long screenX,
long screenY,
long clientX,
long clientY,
boolean ctrlKey,
boolean altKey,
boolean shiftKey,
boolean metaKey,
unsigned short button,
EventTarget? relatedTarget,
long axis);
optional boolean canBubble = false,
optional boolean cancelable = false,
optional Window? view = null,
optional long detail = 0,
optional long screenX = 0,
optional long screenY = 0,
optional long clientX = 0,
optional long clientY = 0,
optional boolean ctrlKey = false,
optional boolean altKey = false,
optional boolean shiftKey = false,
optional boolean metaKey = false,
optional short button = 0,
optional EventTarget? relatedTarget = null,
optional long axis = 0);
};

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

@ -23,11 +23,11 @@ interface MutationEvent : Event
[Throws]
void initMutationEvent(DOMString type,
boolean canBubble,
boolean cancelable,
Node? relatedNode,
DOMString prevValue,
DOMString newValue,
DOMString attrName,
unsigned short attrChange);
optional boolean canBubble = false,
optional boolean cancelable = false,
optional Node? relatedNode = null,
optional DOMString prevValue = "",
optional DOMString newValue = "",
optional DOMString attrName = "",
optional unsigned short attrChange = 0);
};

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

@ -12,12 +12,12 @@ interface ScrollAreaEvent : UIEvent
readonly attribute float height;
void initScrollAreaEvent(DOMString type,
boolean canBubble,
boolean cancelable,
Window? view,
long detail,
float x,
float y,
float width,
float height);
optional boolean canBubble = false,
optional boolean cancelable = false,
optional Window? view = null,
optional long detail = 0,
optional float x = 0,
optional float y = 0,
optional float width = 0,
optional float height = 0);
};

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

@ -25,22 +25,22 @@ interface SimpleGestureEvent : MouseEvent
readonly attribute unsigned long clickCount;
void initSimpleGestureEvent(DOMString typeArg,
boolean canBubbleArg,
boolean cancelableArg,
Window? viewArg,
long detailArg,
long screenXArg,
long screenYArg,
long clientXArg,
long clientYArg,
boolean ctrlKeyArg,
boolean altKeyArg,
boolean shiftKeyArg,
boolean metaKeyArg,
unsigned short buttonArg,
EventTarget? relatedTargetArg,
unsigned long allowedDirectionsArg,
unsigned long directionArg,
double deltaArg,
unsigned long clickCount);
optional boolean canBubbleArg = false,
optional boolean cancelableArg = false,
optional Window? viewArg = null,
optional long detailArg = 0,
optional long screenXArg = 0,
optional long screenYArg = 0,
optional long clientXArg = 0,
optional long clientYArg = 0,
optional boolean ctrlKeyArg = false,
optional boolean altKeyArg = false,
optional boolean shiftKeyArg = false,
optional boolean metaKeyArg = false,
optional short buttonArg = 0,
optional EventTarget? relatedTargetArg = null,
optional unsigned long allowedDirectionsArg = 0,
optional unsigned long directionArg = 0,
optional double deltaArg = 0,
optional unsigned long clickCount = 0);
};

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

@ -21,13 +21,13 @@ interface StorageEvent : Event
// Bug 1016053 - This is not spec compliant.
void initStorageEvent(DOMString type,
boolean canBubble,
boolean cancelable,
DOMString? key,
DOMString? oldValue,
DOMString? newValue,
DOMString? url,
Storage? storageArea);
optional boolean canBubble = false,
optional boolean cancelable = false,
optional DOMString? key = null,
optional DOMString? oldValue = null,
optional DOMString? newValue = null,
optional DOMString? url = null,
optional Storage? storageArea = null);
};
dictionary StorageEventInit : EventInit

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

@ -15,6 +15,6 @@ interface TimeEvent : Event
readonly attribute long detail;
readonly attribute WindowProxy? view;
void initTimeEvent(DOMString aType,
Window? aView,
long aDetail);
optional Window? aView = null,
optional long aDetail = 0);
};

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

@ -23,15 +23,15 @@ interface TouchEvent : UIEvent {
readonly attribute boolean shiftKey;
void initTouchEvent(DOMString type,
boolean canBubble,
boolean cancelable,
Window? view,
long detail,
boolean ctrlKey,
boolean altKey,
boolean shiftKey,
boolean metaKey,
TouchList? touches,
TouchList? targetTouches,
TouchList? changedTouches);
optional boolean canBubble = false,
optional boolean cancelable = false,
optional Window? view = null,
optional long detail = 0,
optional boolean ctrlKey = false,
optional boolean altKey = false,
optional boolean shiftKey = false,
optional boolean metaKey = false,
optional TouchList? touches = null,
optional TouchList? targetTouches = null,
optional TouchList? changedTouches = null);
};

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

@ -16,10 +16,10 @@ interface UIEvent : Event
readonly attribute WindowProxy? view;
readonly attribute long detail;
void initUIEvent(DOMString aType,
boolean aCanBubble,
boolean aCancelable,
Window? aView,
long aDetail);
optional boolean aCanBubble = false,
optional boolean aCancelable = false,
optional Window? aView = null,
optional long aDetail = 0);
};
// Additional DOM0 properties.

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

@ -15,13 +15,13 @@ interface XULCommandEvent : UIEvent
readonly attribute Event? sourceEvent;
void initCommandEvent(DOMString type,
boolean canBubble,
boolean cancelable,
Window? view,
long detail,
boolean ctrlKey,
boolean altKey,
boolean shiftKey,
boolean metaKey,
Event? sourceEvent);
optional boolean canBubble = false,
optional boolean cancelable = false,
optional Window? view = null,
optional long detail = 0,
optional boolean ctrlKey = false,
optional boolean altKey = false,
optional boolean shiftKey = false,
optional boolean metaKey = false,
optional Event? sourceEvent = null);
};

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

@ -180,7 +180,7 @@ struct BasicLogger
#else
#if defined(MOZ_LOGGING)
if (MOZ_LOG_TEST(GetGFX2DLog(), PRLogLevelForLevel(aLevel))) {
PR_LogPrint("%s%s", aString.c_str(), aNoNewline ? "" : "\n");
MOZ_LOG(GetGFX2DLog(), PRLogLevelForLevel(aLevel), ("%s%s", aString.c_str(), aNoNewline ? "" : "\n"));
} else
#endif
if ((LoggingPrefs::sGfxLogLevel >= LOG_DEBUG_PRLOG) ||

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

@ -11,6 +11,7 @@
#include "gfxASurface.h" // for gfxASurface, etc
#include "gfxPlatform.h" // for gfxPlatform, gfxImageFormat
#include "gfxUtils.h" // for gfxUtils
#include "mozilla/CheckedInt.h"
#include "mozilla/mozalloc.h" // for operator delete[], etc
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
@ -111,7 +112,13 @@ BasicPlanarYCbCrImage::CopyData(const Data& aData)
gfxImageFormat iFormat = gfx::SurfaceFormatToImageFormat(format);
mStride = gfxASurface::FormatStrideForWidth(iFormat, size.width);
mDecodedBuffer = AllocateBuffer(size.height * mStride);
mozilla::CheckedInt32 requiredBytes =
mozilla::CheckedInt32(size.height) * mozilla::CheckedInt32(mStride);
if (!requiredBytes.isValid()) {
// invalid size
return false;
}
mDecodedBuffer = AllocateBuffer(requiredBytes.value());
if (!mDecodedBuffer) {
// out of memory
return false;

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

@ -502,9 +502,9 @@ LayerTransactionParent::RecvUpdate(const TransactionInfo& aInfo)
severity = 1.f;
}
mLayerManager->VisualFrameWarning(severity);
PR_LogPrint("LayerTransactionParent::RecvUpdate transaction from process %d took %f ms",
OtherPid(),
latency.ToMilliseconds());
printf_stderr("LayerTransactionParent::RecvUpdate transaction from process %d took %f ms",
OtherPid(),
latency.ToMilliseconds());
}
}

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

@ -775,7 +775,7 @@ PreparePattern(FcPattern* aPattern, bool aIsPrinterFont)
cairo_ft_font_options_substitute(options, aPattern);
cairo_font_options_destroy(options);
FcPatternAddBool(aPattern, PRINTING_FC_PROPERTY, FcTrue);
} else {
} else if (!gfxPlatform::IsHeadless()) {
#ifdef MOZ_WIDGET_GTK
ApplyGdkScreenFontOptions(aPattern);

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

@ -836,6 +836,12 @@ gfxPlatform::InitMoz2DLogging()
gfx::Factory::Init(cfg);
}
/* static */ bool
gfxPlatform::IsHeadless()
{
return PR_GetEnv("MOZ_HEADLESS");
}
static bool sLayersIPCIsUp = false;
/* static */ void

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

@ -185,6 +185,8 @@ public:
static void InitMoz2DLogging();
static bool IsHeadless();
/**
* Create an offscreen surface of the given dimensions
* and image format.

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

@ -73,12 +73,14 @@ static cairo_user_data_key_t cairo_gdk_drawable_key;
gfxPlatformGtk::gfxPlatformGtk()
{
gtk_init(nullptr, nullptr);
if (!gfxPlatform::IsHeadless()) {
gtk_init(nullptr, nullptr);
}
mMaxGenericSubstitutions = UNINITIALIZED_VALUE;
#ifdef MOZ_X11
if (XRE_IsParentProcess()) {
if (!gfxPlatform::IsHeadless() && XRE_IsParentProcess()) {
if (GDK_IS_X11_DISPLAY(gdk_display_get_default()) &&
mozilla::Preferences::GetBool("gfx.xrender.enabled"))
{
@ -97,7 +99,7 @@ gfxPlatformGtk::gfxPlatformGtk()
contentMask, BackendType::CAIRO);
#ifdef MOZ_X11
if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
if (gfxPlatform::IsHeadless() && GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
mCompositorDisplay = XOpenDisplay(nullptr);
MOZ_ASSERT(mCompositorDisplay, "Failed to create compositor display!");
} else {

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

@ -423,20 +423,22 @@ public:
void InitMemoryReporter() { RegisterWeakMemoryReporter(this); }
InsertOutcome Insert(NotNull<ISurfaceProvider*> aProvider,
bool aSetAvailable)
bool aSetAvailable,
const StaticMutexAutoLock& aAutoLock)
{
// If this is a duplicate surface, refuse to replace the original.
// XXX(seth): Calling Lookup() and then RemoveEntry() does the lookup
// twice. We'll make this more efficient in bug 1185137.
LookupResult result = Lookup(aProvider->GetImageKey(),
aProvider->GetSurfaceKey(),
aAutoLock,
/* aMarkUsed = */ false);
if (MOZ_UNLIKELY(result)) {
return InsertOutcome::FAILURE_ALREADY_PRESENT;
}
if (result.Type() == MatchType::PENDING) {
RemoveEntry(aProvider->GetImageKey(), aProvider->GetSurfaceKey());
RemoveEntry(aProvider->GetImageKey(), aProvider->GetSurfaceKey(), aAutoLock);
}
MOZ_ASSERT(result.Type() == MatchType::NOT_FOUND ||
@ -456,7 +458,7 @@ public:
while (cost > mAvailableCost) {
MOZ_ASSERT(!mCosts.IsEmpty(),
"Removed everything and it still won't fit");
Remove(mCosts.LastElement().Surface());
Remove(mCosts.LastElement().Surface(), aAutoLock);
}
// Locate the appropriate per-image cache. If there's not an existing cache
@ -488,12 +490,13 @@ public:
// Insert.
MOZ_ASSERT(cost <= mAvailableCost, "Inserting despite too large a cost");
cache->Insert(surface);
StartTracking(surface);
StartTracking(surface, aAutoLock);
return InsertOutcome::SUCCESS;
}
void Remove(NotNull<CachedSurface*> aSurface)
void Remove(NotNull<CachedSurface*> aSurface,
const StaticMutexAutoLock& aAutoLock)
{
ImageKey imageKey = aSurface->GetImageKey();
@ -505,7 +508,7 @@ public:
static_cast<Image*>(imageKey)->OnSurfaceDiscarded(aSurface->GetSurfaceKey());
}
StopTracking(aSurface);
StopTracking(aSurface, aAutoLock);
cache->Remove(aSurface);
// Remove the per-image cache if it's unneeded now. (Keep it if the image is
@ -515,7 +518,8 @@ public:
}
}
void StartTracking(NotNull<CachedSurface*> aSurface)
void StartTracking(NotNull<CachedSurface*> aSurface,
const StaticMutexAutoLock& aAutoLock)
{
CostEntry costEntry = aSurface->GetCostEntry();
MOZ_ASSERT(costEntry.GetCost() <= mAvailableCost,
@ -530,11 +534,12 @@ public:
mCosts.InsertElementSorted(costEntry);
// This may fail during XPCOM shutdown, so we need to ensure the object is
// tracked before calling RemoveObject in StopTracking.
mExpirationTracker.AddObject(aSurface);
mExpirationTracker.AddObjectLocked(aSurface, aAutoLock);
}
}
void StopTracking(NotNull<CachedSurface*> aSurface)
void StopTracking(NotNull<CachedSurface*> aSurface,
const StaticMutexAutoLock& aAutoLock)
{
CostEntry costEntry = aSurface->GetCostEntry();
@ -546,7 +551,7 @@ public:
"Shouldn't have a cost entry for a locked surface");
} else {
if (MOZ_LIKELY(aSurface->GetExpirationState()->IsTracked())) {
mExpirationTracker.RemoveObject(aSurface);
mExpirationTracker.RemoveObjectLocked(aSurface, aAutoLock);
} else {
// Our call to AddObject must have failed in StartTracking; most likely
// we're in XPCOM shutdown right now.
@ -565,6 +570,7 @@ public:
LookupResult Lookup(const ImageKey aImageKey,
const SurfaceKey& aSurfaceKey,
const StaticMutexAutoLock& aAutoLock,
bool aMarkUsed = true)
{
RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
@ -587,12 +593,12 @@ public:
if (!drawableSurface) {
// The surface was released by the operating system. Remove the cache
// entry as well.
Remove(WrapNotNull(surface));
Remove(WrapNotNull(surface), aAutoLock);
return LookupResult(MatchType::NOT_FOUND);
}
if (aMarkUsed) {
MarkUsed(WrapNotNull(surface), WrapNotNull(cache));
MarkUsed(WrapNotNull(surface), WrapNotNull(cache), aAutoLock);
}
MOZ_ASSERT(surface->GetSurfaceKey() == aSurfaceKey,
@ -601,7 +607,8 @@ public:
}
LookupResult LookupBestMatch(const ImageKey aImageKey,
const SurfaceKey& aSurfaceKey)
const SurfaceKey& aSurfaceKey,
const StaticMutexAutoLock& aAutoLock)
{
RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
if (!cache) {
@ -632,7 +639,7 @@ public:
// The surface was released by the operating system. Remove the cache
// entry as well.
Remove(WrapNotNull(surface));
Remove(WrapNotNull(surface), aAutoLock);
}
MOZ_ASSERT_IF(matchType == MatchType::EXACT,
@ -644,7 +651,7 @@ public:
surface->GetSurfaceKey().Flags() == aSurfaceKey.Flags());
if (matchType == MatchType::EXACT) {
MarkUsed(WrapNotNull(surface), WrapNotNull(cache));
MarkUsed(WrapNotNull(surface), WrapNotNull(cache), aAutoLock);
}
return LookupResult(Move(drawableSurface), matchType);
@ -660,7 +667,8 @@ public:
return size_t(mMaxCost);
}
void SurfaceAvailable(NotNull<ISurfaceProvider*> aProvider)
void SurfaceAvailable(NotNull<ISurfaceProvider*> aProvider,
const StaticMutexAutoLock& aAutoLock)
{
if (!aProvider->Availability().IsPlaceholder()) {
MOZ_ASSERT_UNREACHABLE("Calling SurfaceAvailable on non-placeholder");
@ -673,7 +681,7 @@ public:
// surface first, but it's fine either way.
// XXX(seth): This could be implemented more efficiently; we should be able
// to just update our data structures without reinserting.
Insert(aProvider, /* aSetAvailable = */ true);
Insert(aProvider, /* aSetAvailable = */ true, aAutoLock);
}
void LockImage(const ImageKey aImageKey)
@ -690,7 +698,7 @@ public:
// image should arrange for Lookup() to touch them if they are still useful.
}
void UnlockImage(const ImageKey aImageKey)
void UnlockImage(const ImageKey aImageKey, const StaticMutexAutoLock& aAutoLock)
{
RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
if (!cache || !cache->IsLocked()) {
@ -698,10 +706,10 @@ public:
}
cache->SetLocked(false);
DoUnlockSurfaces(WrapNotNull(cache), /* aStaticOnly = */ false);
DoUnlockSurfaces(WrapNotNull(cache), /* aStaticOnly = */ false, aAutoLock);
}
void UnlockEntries(const ImageKey aImageKey)
void UnlockEntries(const ImageKey aImageKey, const StaticMutexAutoLock& aAutoLock)
{
RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
if (!cache || !cache->IsLocked()) {
@ -711,10 +719,10 @@ public:
// (Note that we *don't* unlock the per-image cache here; that's the
// difference between this and UnlockImage.)
DoUnlockSurfaces(WrapNotNull(cache),
/* aStaticOnly = */ !gfxPrefs::ImageMemAnimatedDiscardable());
/* aStaticOnly = */ !gfxPrefs::ImageMemAnimatedDiscardable(), aAutoLock);
}
void RemoveImage(const ImageKey aImageKey)
void RemoveImage(const ImageKey aImageKey, const StaticMutexAutoLock& aAutoLock)
{
RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
if (!cache) {
@ -727,7 +735,7 @@ public:
// small, performance should be good, but if usage patterns change we should
// change the data structure used for mCosts.
for (auto iter = cache->ConstIter(); !iter.Done(); iter.Next()) {
StopTracking(WrapNotNull(iter.UserData()));
StopTracking(WrapNotNull(iter.UserData()), aAutoLock);
}
// The per-image cache isn't needed anymore, so remove it as well.
@ -735,17 +743,17 @@ public:
mImageCaches.Remove(aImageKey);
}
void DiscardAll()
void DiscardAll(const StaticMutexAutoLock& aAutoLock)
{
// Remove in order of cost because mCosts is an array and the other data
// structures are all hash tables. Note that locked surfaces are not
// removed, since they aren't present in mCosts.
while (!mCosts.IsEmpty()) {
Remove(mCosts.LastElement().Surface());
Remove(mCosts.LastElement().Surface(), aAutoLock);
}
}
void DiscardForMemoryPressure()
void DiscardForMemoryPressure(const StaticMutexAutoLock& aAutoLock)
{
// Compute our discardable cost. Since locked surfaces aren't discardable,
// we exclude them.
@ -760,28 +768,29 @@ public:
if (targetCost > mMaxCost - mLockedCost) {
MOZ_ASSERT_UNREACHABLE("Target cost is more than we can discard");
DiscardAll();
DiscardAll(aAutoLock);
return;
}
// Discard surfaces until we've reduced our cost to our target cost.
while (mAvailableCost < targetCost) {
MOZ_ASSERT(!mCosts.IsEmpty(), "Removed everything and still not done");
Remove(mCosts.LastElement().Surface());
Remove(mCosts.LastElement().Surface(), aAutoLock);
}
}
void LockSurface(NotNull<CachedSurface*> aSurface)
void LockSurface(NotNull<CachedSurface*> aSurface,
const StaticMutexAutoLock& aAutoLock)
{
if (aSurface->IsPlaceholder() || aSurface->IsLocked()) {
return;
}
StopTracking(aSurface);
StopTracking(aSurface, aAutoLock);
// Lock the surface. This can fail.
aSurface->SetLocked(true);
StartTracking(aSurface);
StartTracking(aSurface, aAutoLock);
}
NS_IMETHOD
@ -848,16 +857,18 @@ private:
}
void MarkUsed(NotNull<CachedSurface*> aSurface,
NotNull<ImageSurfaceCache*> aCache)
NotNull<ImageSurfaceCache*> aCache,
const StaticMutexAutoLock& aAutoLock)
{
if (aCache->IsLocked()) {
LockSurface(aSurface);
LockSurface(aSurface, aAutoLock);
} else {
mExpirationTracker.MarkUsed(aSurface);
mExpirationTracker.MarkUsedLocked(aSurface, aAutoLock);
}
}
void DoUnlockSurfaces(NotNull<ImageSurfaceCache*> aCache, bool aStaticOnly)
void DoUnlockSurfaces(NotNull<ImageSurfaceCache*> aCache, bool aStaticOnly,
const StaticMutexAutoLock& aAutoLock)
{
// Unlock all the surfaces the per-image cache is holding.
for (auto iter = aCache->ConstIter(); !iter.Done(); iter.Next()) {
@ -868,14 +879,15 @@ private:
if (aStaticOnly && surface->GetSurfaceKey().Playback() != PlaybackType::eStatic) {
continue;
}
StopTracking(surface);
StopTracking(surface, aAutoLock);
surface->SetLocked(false);
StartTracking(surface);
StartTracking(surface, aAutoLock);
}
}
void RemoveEntry(const ImageKey aImageKey,
const SurfaceKey& aSurfaceKey)
const SurfaceKey& aSurfaceKey,
const StaticMutexAutoLock& aAutoLock)
{
RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
if (!cache) {
@ -887,23 +899,29 @@ private:
return; // Lookup in the per-image cache missed.
}
Remove(WrapNotNull(surface));
Remove(WrapNotNull(surface), aAutoLock);
}
struct SurfaceTracker : public nsExpirationTracker<CachedSurface, 2>
struct SurfaceTracker : public ExpirationTrackerImpl<CachedSurface, 2,
StaticMutex,
StaticMutexAutoLock>
{
explicit SurfaceTracker(uint32_t aSurfaceCacheExpirationTimeMS)
: nsExpirationTracker<CachedSurface, 2>(aSurfaceCacheExpirationTimeMS,
"SurfaceTracker")
: ExpirationTrackerImpl<CachedSurface, 2,
StaticMutex, StaticMutexAutoLock>(
aSurfaceCacheExpirationTimeMS, "SurfaceTracker")
{ }
protected:
virtual void NotifyExpired(CachedSurface* aSurface) override
void NotifyExpiredLocked(CachedSurface* aSurface,
const StaticMutexAutoLock& aAutoLock) override
{
StaticMutexAutoLock lock(sInstanceMutex);
if (sInstance) {
sInstance->Remove(WrapNotNull(aSurface));
}
sInstance->Remove(WrapNotNull(aSurface), aAutoLock);
}
StaticMutex& GetMutex() override
{
return sInstanceMutex;
}
};
@ -917,7 +935,7 @@ private:
{
StaticMutexAutoLock lock(sInstanceMutex);
if (sInstance && strcmp(aTopic, "memory-pressure") == 0) {
sInstance->DiscardForMemoryPressure();
sInstance->DiscardForMemoryPressure(lock);
}
return NS_OK;
}
@ -1019,7 +1037,7 @@ SurfaceCache::Lookup(const ImageKey aImageKey,
return LookupResult(MatchType::NOT_FOUND);
}
return sInstance->Lookup(aImageKey, aSurfaceKey);
return sInstance->Lookup(aImageKey, aSurfaceKey, lock);
}
/* static */ LookupResult
@ -1031,7 +1049,7 @@ SurfaceCache::LookupBestMatch(const ImageKey aImageKey,
return LookupResult(MatchType::NOT_FOUND);
}
return sInstance->LookupBestMatch(aImageKey, aSurfaceKey);
return sInstance->LookupBestMatch(aImageKey, aSurfaceKey, lock);
}
/* static */ InsertOutcome
@ -1042,7 +1060,7 @@ SurfaceCache::Insert(NotNull<ISurfaceProvider*> aProvider)
return InsertOutcome::FAILURE;
}
return sInstance->Insert(aProvider, /* aSetAvailable = */ false);
return sInstance->Insert(aProvider, /* aSetAvailable = */ false, lock);
}
/* static */ bool
@ -1076,7 +1094,7 @@ SurfaceCache::SurfaceAvailable(NotNull<ISurfaceProvider*> aProvider)
return;
}
sInstance->SurfaceAvailable(aProvider);
sInstance->SurfaceAvailable(aProvider, lock);
}
/* static */ void
@ -1093,7 +1111,7 @@ SurfaceCache::UnlockImage(const ImageKey aImageKey)
{
StaticMutexAutoLock lock(sInstanceMutex);
if (sInstance) {
return sInstance->UnlockImage(aImageKey);
return sInstance->UnlockImage(aImageKey, lock);
}
}
@ -1102,7 +1120,7 @@ SurfaceCache::UnlockEntries(const ImageKey aImageKey)
{
StaticMutexAutoLock lock(sInstanceMutex);
if (sInstance) {
return sInstance->UnlockEntries(aImageKey);
return sInstance->UnlockEntries(aImageKey, lock);
}
}
@ -1111,7 +1129,7 @@ SurfaceCache::RemoveImage(const ImageKey aImageKey)
{
StaticMutexAutoLock lock(sInstanceMutex);
if (sInstance) {
sInstance->RemoveImage(aImageKey);
sInstance->RemoveImage(aImageKey, lock);
}
}
@ -1120,7 +1138,7 @@ SurfaceCache::DiscardAll()
{
StaticMutexAutoLock lock(sInstanceMutex);
if (sInstance) {
sInstance->DiscardAll();
sInstance->DiscardAll(lock);
}
}

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

@ -30,6 +30,7 @@
#include "NullPrincipal.h"
#include "nsIURL.h"
#include "prlink.h"
#include "gfxPlatform.h"
NS_IMPL_ISUPPORTS(nsIconChannel,
nsIRequest,
@ -308,6 +309,10 @@ nsIconChannel::Init(nsIURI* aURI)
nsCOMPtr<nsIMozIconURI> iconURI = do_QueryInterface(aURI);
NS_ASSERTION(iconURI, "URI is not an nsIMozIconURI");
if (gfxPlatform::IsHeadless()) {
return NS_ERROR_NOT_AVAILABLE;
}
nsAutoCString stockIcon;
iconURI->GetStockIcon(stockIcon);
if (stockIcon.IsEmpty()) {

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

@ -121,7 +121,7 @@ std::wstring SysInfo::GetEnvVar(const wchar_t* var) {
// static
std::string SysInfo::OperatingSystemName() {
utsname info;
struct utsname info;
if (uname(&info) < 0) {
NOTREACHED();
return "";
@ -131,7 +131,7 @@ std::string SysInfo::OperatingSystemName() {
// static
std::string SysInfo::CPUArchitecture() {
utsname info;
struct utsname info;
if (uname(&info) < 0) {
NOTREACHED();
return "";

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

@ -8,6 +8,7 @@
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#if defined(OS_MACOSX)
#include <sched.h>
#endif
@ -39,8 +40,14 @@
#include "mozilla/ipc/Faulty.h"
#endif
// Work around possible OS limitations.
// Use OS specific iovec array limit where it's possible.
#if defined(IOV_MAX)
static const size_t kMaxIOVecSize = IOV_MAX;
#elif defined(ANDROID)
static const size_t kMaxIOVecSize = 256;
#else
static const size_t kMaxIOVecSize = 16;
#endif
#ifdef MOZ_TASK_TRACER
#include "GeckoTaskTracerImpl.h"

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

@ -18,7 +18,7 @@ namespace js {
/* 2^32-2, inclusive */
const uint32_t MAX_ARRAY_INDEX = 4294967294u;
inline bool
MOZ_ALWAYS_INLINE bool
IdIsIndex(jsid id, uint32_t* indexp)
{
if (JSID_IS_INT(id)) {
@ -31,7 +31,11 @@ IdIsIndex(jsid id, uint32_t* indexp)
if (MOZ_UNLIKELY(!JSID_IS_STRING(id)))
return false;
return js::StringIsArrayIndex(JSID_TO_ATOM(id), indexp);
JSAtom* atom = JSID_TO_ATOM(id);
if (atom->length() == 0 || !JS7_ISDEC(atom->latin1OrTwoByteChar(0)))
return false;
return js::StringIsArrayIndex(atom, indexp);
}
// The methods below only create dense boxed arrays.

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

@ -456,6 +456,58 @@ NativeObject::create(JSContext* cx, js::gc::AllocKind kind, js::gc::InitialHeap
return nobj;
}
MOZ_ALWAYS_INLINE bool
NativeObject::updateSlotsForSpan(JSContext* cx, size_t oldSpan, size_t newSpan)
{
MOZ_ASSERT(oldSpan != newSpan);
size_t oldCount = dynamicSlotsCount(numFixedSlots(), oldSpan, getClass());
size_t newCount = dynamicSlotsCount(numFixedSlots(), newSpan, getClass());
if (oldSpan < newSpan) {
if (oldCount < newCount && !growSlots(cx, oldCount, newCount))
return false;
if (newSpan == oldSpan + 1)
initSlotUnchecked(oldSpan, UndefinedValue());
else
initializeSlotRange(oldSpan, newSpan - oldSpan);
} else {
/* Trigger write barriers on the old slots before reallocating. */
prepareSlotRangeForOverwrite(newSpan, oldSpan);
invalidateSlotRange(newSpan, oldSpan - newSpan);
if (oldCount > newCount)
shrinkSlots(cx, oldCount, newCount);
}
return true;
}
MOZ_ALWAYS_INLINE bool
NativeObject::setLastProperty(JSContext* cx, Shape* shape)
{
MOZ_ASSERT(!inDictionaryMode());
MOZ_ASSERT(!shape->inDictionary());
MOZ_ASSERT(shape->zone() == zone());
MOZ_ASSERT(shape->numFixedSlots() == numFixedSlots());
MOZ_ASSERT(shape->getObjectClass() == getClass());
size_t oldSpan = lastProperty()->slotSpan();
size_t newSpan = shape->slotSpan();
if (oldSpan == newSpan) {
shape_ = shape;
return true;
}
if (MOZ_UNLIKELY(!updateSlotsForSpan(cx, oldSpan, newSpan)))
return false;
shape_ = shape;
return true;
}
/* Make an object with pregenerated shape from a NEWOBJECT bytecode. */
static inline PlainObject*
CopyInitializerObject(JSContext* cx, HandlePlainObject baseobj, NewObjectKind newKind = GenericObject)

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

@ -299,58 +299,6 @@ js::NativeObject::dynamicSlotsCount(uint32_t nfixed, uint32_t span, const Class*
return slots;
}
inline bool
NativeObject::updateSlotsForSpan(JSContext* cx, size_t oldSpan, size_t newSpan)
{
MOZ_ASSERT(oldSpan != newSpan);
size_t oldCount = dynamicSlotsCount(numFixedSlots(), oldSpan, getClass());
size_t newCount = dynamicSlotsCount(numFixedSlots(), newSpan, getClass());
if (oldSpan < newSpan) {
if (oldCount < newCount && !growSlots(cx, oldCount, newCount))
return false;
if (newSpan == oldSpan + 1)
initSlotUnchecked(oldSpan, UndefinedValue());
else
initializeSlotRange(oldSpan, newSpan - oldSpan);
} else {
/* Trigger write barriers on the old slots before reallocating. */
prepareSlotRangeForOverwrite(newSpan, oldSpan);
invalidateSlotRange(newSpan, oldSpan - newSpan);
if (oldCount > newCount)
shrinkSlots(cx, oldCount, newCount);
}
return true;
}
bool
NativeObject::setLastProperty(JSContext* cx, Shape* shape)
{
MOZ_ASSERT(!inDictionaryMode());
MOZ_ASSERT(!shape->inDictionary());
MOZ_ASSERT(shape->zone() == zone());
MOZ_ASSERT(shape->numFixedSlots() == numFixedSlots());
MOZ_ASSERT(shape->getObjectClass() == getClass());
size_t oldSpan = lastProperty()->slotSpan();
size_t newSpan = shape->slotSpan();
if (oldSpan == newSpan) {
shape_ = shape;
return true;
}
if (!updateSlotsForSpan(cx, oldSpan, newSpan))
return false;
shape_ = shape;
return true;
}
void
NativeObject::setLastPropertyShrinkFixedSlots(Shape* shape)
{
@ -1091,23 +1039,22 @@ js::NativeLookupOwnProperty<NoGC>(JSContext* cx, NativeObject* const& obj, const
/*** [[DefineOwnProperty]] ***********************************************************************/
static inline bool
CallAddPropertyHook(JSContext* cx, HandleNativeObject obj, HandleShape shape,
HandleValue value)
static MOZ_ALWAYS_INLINE bool
CallAddPropertyHook(JSContext* cx, HandleNativeObject obj, HandleId id, HandleValue value)
{
if (JSAddPropertyOp addProperty = obj->getClass()->getAddProperty()) {
JSAddPropertyOp addProperty = obj->getClass()->getAddProperty();
if (MOZ_UNLIKELY(addProperty)) {
MOZ_ASSERT(!cx->helperThread());
RootedId id(cx, shape->propid());
if (!CallJSAddPropertyOp(cx, addProperty, obj, id, value)) {
NativeObject::removeProperty(cx, obj, shape->propid());
NativeObject::removeProperty(cx, obj, id);
return false;
}
}
return true;
}
static inline bool
static MOZ_ALWAYS_INLINE bool
CallAddPropertyHookDense(JSContext* cx, HandleNativeObject obj, uint32_t index,
HandleValue value)
{
@ -1120,7 +1067,8 @@ CallAddPropertyHookDense(JSContext* cx, HandleNativeObject obj, uint32_t index,
return true;
}
if (JSAddPropertyOp addProperty = obj->getClass()->getAddProperty()) {
JSAddPropertyOp addProperty = obj->getClass()->getAddProperty();
if (MOZ_UNLIKELY(addProperty)) {
MOZ_ASSERT(!cx->helperThread());
if (!obj->maybeCopyElementsForWrite(cx))
@ -1228,7 +1176,10 @@ PurgeEnvironmentChain(JSContext* cx, HandleObject obj, HandleId id)
return true;
}
static bool
enum class IsAddOrChange { Add, AddOrChange };
template <IsAddOrChange AddOrChange>
static MOZ_ALWAYS_INLINE bool
AddOrChangeProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
Handle<PropertyDescriptor> desc)
{
@ -1257,8 +1208,16 @@ AddOrChangeProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
}
}
RootedShape shape(cx, NativeObject::putProperty(cx, obj, id, desc.getter(), desc.setter(),
SHAPE_INVALID_SLOT, desc.attributes(), 0));
// If we know this is a new property we can call addProperty instead of
// the slower putProperty.
Shape* shape;
if (AddOrChange == IsAddOrChange::Add) {
shape = NativeObject::addProperty(cx, obj, id, desc.getter(), desc.setter(),
SHAPE_INVALID_SLOT, desc.attributes(), 0);
} else {
shape = NativeObject::putProperty(cx, obj, id, desc.getter(), desc.setter(),
SHAPE_INVALID_SLOT, desc.attributes(), 0);
}
if (!shape)
return false;
@ -1282,7 +1241,7 @@ AddOrChangeProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
}
}
return CallAddPropertyHook(cx, obj, shape, desc.value());
return CallAddPropertyHook(cx, obj, id, desc.value());
}
static bool IsConfigurable(unsigned attrs) { return (attrs & JSPROP_PERMANENT) == 0; }
@ -1481,7 +1440,7 @@ js::NativeDefineProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
// Fill in missing desc fields with defaults.
CompletePropertyDescriptor(&desc);
if (!AddOrChangeProperty(cx, obj, id, desc))
if (!AddOrChangeProperty<IsAddOrChange::Add>(cx, obj, id, desc))
return false;
return result.succeed();
}
@ -1627,7 +1586,7 @@ js::NativeDefineProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
}
// Step 10.
if (!AddOrChangeProperty(cx, obj, id, desc))
if (!AddOrChangeProperty<IsAddOrChange::AddOrChange>(cx, obj, id, desc))
return false;
return result.succeed();
}

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

@ -449,7 +449,7 @@ class NativeObject : public ShapedObject
// Update the last property, keeping the number of allocated slots in sync
// with the object's new slot span.
bool setLastProperty(JSContext* cx, Shape* shape);
MOZ_ALWAYS_INLINE bool setLastProperty(JSContext* cx, Shape* shape);
// As for setLastProperty(), but allows the number of fixed slots to
// change. This can only be used when fixed slots are being erased from the
@ -735,8 +735,6 @@ class NativeObject : public ShapedObject
void freeSlot(JSContext* cx, uint32_t slot);
private:
static Shape* getChildPropertyOnDictionary(JSContext* cx, HandleNativeObject obj,
HandleShape parent, MutableHandle<StackShape> child);
static Shape* getChildProperty(JSContext* cx, HandleNativeObject obj,
HandleShape parent, MutableHandle<StackShape> child);
@ -881,7 +879,7 @@ class NativeObject : public ShapedObject
static const uint32_t MAX_FIXED_SLOTS = 16;
protected:
inline bool updateSlotsForSpan(JSContext* cx, size_t oldSpan, size_t newSpan);
MOZ_ALWAYS_INLINE bool updateSlotsForSpan(JSContext* cx, size_t oldSpan, size_t newSpan);
private:
void prepareElementRangeForOverwrite(size_t start, size_t end) {

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

@ -291,8 +291,9 @@ Shape::replaceLastProperty(JSContext* cx, StackBaseShape& base,
* one of lastProperty() or lastProperty()->parent.
*/
/* static */ Shape*
NativeObject::getChildPropertyOnDictionary(JSContext* cx, HandleNativeObject obj,
HandleShape parent, MutableHandle<StackShape> child)
NativeObject::getChildProperty(JSContext* cx,
HandleNativeObject obj, HandleShape parent,
MutableHandle<StackShape> child)
{
/*
* Shared properties have no slot, but slot_ will reflect that of parent.
@ -325,11 +326,9 @@ NativeObject::getChildPropertyOnDictionary(JSContext* cx, HandleNativeObject obj
}
}
RootedShape shape(cx);
if (obj->inDictionaryMode()) {
MOZ_ASSERT(parent == obj->lastProperty());
shape = child.isAccessorShape() ? Allocate<AccessorShape>(cx) : Allocate<Shape>(cx);
Shape* shape = child.isAccessorShape() ? Allocate<AccessorShape>(cx) : Allocate<Shape>(cx);
if (!shape)
return nullptr;
if (child.hasSlot() && child.slot() >= obj->lastProperty()->base()->slotSpan()) {
@ -339,28 +338,16 @@ NativeObject::getChildPropertyOnDictionary(JSContext* cx, HandleNativeObject obj
}
}
shape->initDictionaryShape(child, obj->numFixedSlots(), &obj->shape_);
return shape;
}
return shape;
}
/* static */ Shape*
NativeObject::getChildProperty(JSContext* cx,
HandleNativeObject obj, HandleShape parent,
MutableHandle<StackShape> child)
{
Shape* shape = getChildPropertyOnDictionary(cx, obj, parent, child);
if (!obj->inDictionaryMode()) {
shape = cx->zone()->propertyTree().getChild(cx, parent, child);
if (!shape)
return nullptr;
//MOZ_ASSERT(shape->parent == parent);
//MOZ_ASSERT_IF(parent != lastProperty(), parent == lastProperty()->parent);
if (!obj->setLastProperty(cx, shape))
return nullptr;
}
Shape* shape = cx->zone()->propertyTree().getChild(cx, parent, child);
if (!shape)
return nullptr;
//MOZ_ASSERT(shape->parent == parent);
//MOZ_ASSERT_IF(parent != lastProperty(), parent == lastProperty()->parent);
if (!obj->setLastProperty(cx, shape))
return nullptr;
return shape;
}
@ -431,6 +418,7 @@ NativeObject::addProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
MOZ_ASSERT(getter != JS_PropertyStub);
MOZ_ASSERT(setter != JS_StrictPropertyStub);
MOZ_ASSERT(obj->nonProxyIsExtensible());
MOZ_ASSERT(!obj->containsPure(id));
AutoKeepShapeTables keep(cx);
ShapeTable::Entry* entry = nullptr;

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

@ -296,9 +296,14 @@ this.XPCOMUtils = {
* The name of the preference to read.
* @param aDefaultValue
* The default value to use, if the preference is not defined.
* @param aOnUpdate
* A function to call upon update. Receives as arguments
* `(aPreference, previousValue, newValue)`
*/
defineLazyPreferenceGetter: function XPCU_defineLazyPreferenceGetter(
aObject, aName, aPreference, aDefaultValue = null)
aObject, aName, aPreference,
aDefaultValue = null,
aOnUpdate = null)
{
// Note: We need to keep a reference to this observer alive as long
// as aObject is alive. This means that all of our getters need to
@ -312,7 +317,18 @@ this.XPCOMUtils = {
observe(subject, topic, data) {
if (data == aPreference) {
this.value = undefined;
if (aOnUpdate) {
let previous = this.value;
// Fetch and cache value.
this.value = undefined;
let latest = lazyGetter();
aOnUpdate(data, previous, latest);
} else {
// Empty cache, next call to the getter will cause refetch.
this.value = undefined;
}
}
},
}

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

@ -13,7 +13,7 @@ namespace mozilla {
void
FramePropertyTable::SetInternal(
const nsIFrame* aFrame, UntypedDescriptor aProperty, void* aValue)
nsIFrame* aFrame, UntypedDescriptor aProperty, void* aValue)
{
MOZ_ASSERT(NS_IsMainThread());
NS_ASSERTION(aFrame, "Null frame?");
@ -22,6 +22,7 @@ FramePropertyTable::SetInternal(
if (mLastFrame != aFrame || !mLastEntry) {
mLastFrame = aFrame;
mLastEntry = mEntries.PutEntry(aFrame);
aFrame->AddStateBits(NS_FRAME_HAS_PROPERTIES);
}
Entry* entry = mLastEntry;
@ -63,7 +64,8 @@ FramePropertyTable::SetInternal(
void*
FramePropertyTable::GetInternal(
const nsIFrame* aFrame, UntypedDescriptor aProperty, bool* aFoundResult)
const nsIFrame* aFrame, UntypedDescriptor aProperty, bool aSkipBitCheck,
bool* aFoundResult)
{
NS_ASSERTION(aFrame, "Null frame?");
NS_ASSERTION(aProperty, "Null property?");
@ -72,6 +74,10 @@ FramePropertyTable::GetInternal(
*aFoundResult = false;
}
if (!aSkipBitCheck && !(aFrame->GetStateBits() & NS_FRAME_HAS_PROPERTIES)) {
return nullptr;
}
// We can end up here during parallel style traversal, in which case the main
// thread is blocked. Reading from the cache is fine on any thread, but we
// only want to write to it in the main-thread case.
@ -82,6 +88,8 @@ FramePropertyTable::GetInternal(
mLastEntry = entry;
}
MOZ_ASSERT(entry || aSkipBitCheck,
"NS_FRAME_HAS_PROPERTIES bit should match whether entry exists");
if (!entry)
return nullptr;
@ -111,7 +119,8 @@ FramePropertyTable::GetInternal(
void*
FramePropertyTable::RemoveInternal(
const nsIFrame* aFrame, UntypedDescriptor aProperty, bool* aFoundResult)
nsIFrame* aFrame, UntypedDescriptor aProperty, bool aSkipBitCheck,
bool* aFoundResult)
{
MOZ_ASSERT(NS_IsMainThread());
NS_ASSERTION(aFrame, "Null frame?");
@ -121,11 +130,17 @@ FramePropertyTable::RemoveInternal(
*aFoundResult = false;
}
if (!aSkipBitCheck && !(aFrame->GetStateBits() & NS_FRAME_HAS_PROPERTIES)) {
return nullptr;
}
if (mLastFrame != aFrame) {
mLastFrame = aFrame;
mLastEntry = mEntries.GetEntry(aFrame);
}
Entry* entry = mLastEntry;
MOZ_ASSERT(entry || aSkipBitCheck,
"NS_FRAME_HAS_PROPERTIES bit should match whether entry exists");
if (!entry)
return nullptr;
@ -136,6 +151,7 @@ FramePropertyTable::RemoveInternal(
// Here it's ok to use RemoveEntry() -- which may resize mEntries --
// because we null mLastEntry at the same time.
mEntries.RemoveEntry(entry);
aFrame->RemoveStateBits(NS_FRAME_HAS_PROPERTIES);
mLastEntry = nullptr;
if (aFoundResult) {
*aFoundResult = true;
@ -176,14 +192,14 @@ FramePropertyTable::RemoveInternal(
void
FramePropertyTable::DeleteInternal(
const nsIFrame* aFrame, UntypedDescriptor aProperty)
nsIFrame* aFrame, UntypedDescriptor aProperty, bool aSkipBitCheck)
{
MOZ_ASSERT(NS_IsMainThread());
NS_ASSERTION(aFrame, "Null frame?");
NS_ASSERTION(aProperty, "Null property?");
bool found;
void* v = RemoveInternal(aFrame, aProperty, &found);
void* v = RemoveInternal(aFrame, aProperty, aSkipBitCheck, &found);
if (found) {
PropertyValue pv(aProperty, v);
pv.DestroyValueFor(aFrame);
@ -206,11 +222,17 @@ FramePropertyTable::DeleteAllForEntry(Entry* aEntry)
}
void
FramePropertyTable::DeleteAllFor(const nsIFrame* aFrame)
FramePropertyTable::DeleteAllFor(nsIFrame* aFrame)
{
NS_ASSERTION(aFrame, "Null frame?");
if (!(aFrame->GetStateBits() & NS_FRAME_HAS_PROPERTIES)) {
return;
}
Entry* entry = mEntries.GetEntry(aFrame);
MOZ_ASSERT(entry,
"NS_FRAME_HAS_PROPERTIES bit should match whether entry exists");
if (!entry)
return;
@ -226,6 +248,8 @@ FramePropertyTable::DeleteAllFor(const nsIFrame* aFrame)
// mLastEntry points into mEntries, so we use RawRemoveEntry() which will not
// resize mEntries.
mEntries.RawRemoveEntry(entry);
// Don't bother unsetting NS_FRAME_HAS_PROPERTIES, since aFrame is going away
}
void

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

@ -165,7 +165,7 @@ public:
* is destroyed.
*/
template<typename T>
void Set(const nsIFrame* aFrame, Descriptor<T> aProperty,
void Set(nsIFrame* aFrame, Descriptor<T> aProperty,
PropertyType<T> aValue)
{
void* ptr = ReinterpretHelper<T>::ToPointer(aValue);
@ -188,12 +188,25 @@ public:
*
* - Calling Has() before Set() in cases where we don't want to overwrite
* an existing value for the frame property.
*
* The HasSkippingBitCheck variant doesn't test NS_FRAME_HAS_PROPERTIES
* on aFrame, so it is safe to call after aFrame has been destroyed as
* long as, since that destruction happened, it isn't possible for a
* new frame to have been created and the same property added.
*/
template<typename T>
bool Has(const nsIFrame* aFrame, Descriptor<T> aProperty)
{
bool foundResult = false;
mozilla::Unused << GetInternal(aFrame, aProperty, &foundResult);
mozilla::Unused << GetInternal(aFrame, aProperty, false, &foundResult);
return foundResult;
}
template<typename T>
bool HasSkippingBitCheck(const nsIFrame* aFrame, Descriptor<T> aProperty)
{
bool foundResult = false;
mozilla::Unused << GetInternal(aFrame, aProperty, true, &foundResult);
return foundResult;
}
@ -212,7 +225,7 @@ public:
PropertyType<T> Get(const nsIFrame* aFrame, Descriptor<T> aProperty,
bool* aFoundResult = nullptr)
{
void* ptr = GetInternal(aFrame, aProperty, aFoundResult);
void* ptr = GetInternal(aFrame, aProperty, false, aFoundResult);
return ReinterpretHelper<T>::FromPointer(ptr);
}
/**
@ -228,10 +241,10 @@ public:
* 'property value is null'.
*/
template<typename T>
PropertyType<T> Remove(const nsIFrame* aFrame, Descriptor<T> aProperty,
PropertyType<T> Remove(nsIFrame* aFrame, Descriptor<T> aProperty,
bool* aFoundResult = nullptr)
{
void* ptr = RemoveInternal(aFrame, aProperty, aFoundResult);
void* ptr = RemoveInternal(aFrame, aProperty, false, aFoundResult);
return ReinterpretHelper<T>::FromPointer(ptr);
}
/**
@ -239,17 +252,29 @@ public:
* hashtable lookup (using the frame as the key) and a linear search
* through the properties of that frame. If the frame has no such
* property, nothing happens.
*
* The DeleteSkippingBitCheck variant doesn't test
* NS_FRAME_HAS_PROPERTIES on aFrame, so it is safe to call after
* aFrame has been destroyed as long as, since that destruction
* happened, it isn't possible for a new frame to have been created
* and the same property added.
*/
template<typename T>
void Delete(const nsIFrame* aFrame, Descriptor<T> aProperty)
void Delete(nsIFrame* aFrame, Descriptor<T> aProperty)
{
DeleteInternal(aFrame, aProperty);
DeleteInternal(aFrame, aProperty, false);
}
template<typename T>
void DeleteSkippingBitCheck(nsIFrame* aFrame, Descriptor<T> aProperty)
{
DeleteInternal(aFrame, aProperty, true);
}
/**
* Remove and destroy all property values for a frame. This requires one
* hashtable lookup (using the frame as the key).
*/
void DeleteAllFor(const nsIFrame* aFrame);
void DeleteAllFor(nsIFrame* aFrame);
/**
* Remove and destroy all property values for all frames.
*/
@ -258,16 +283,17 @@ public:
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
protected:
void SetInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty,
void SetInternal(nsIFrame* aFrame, UntypedDescriptor aProperty,
void* aValue);
void* GetInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty,
bool* aFoundResult);
bool aSkipBitCheck, bool* aFoundResult);
void* RemoveInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty,
bool* aFoundResult);
void* RemoveInternal(nsIFrame* aFrame, UntypedDescriptor aProperty,
bool aSkipBitCheck, bool* aFoundResult);
void DeleteInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty);
void DeleteInternal(nsIFrame* aFrame, UntypedDescriptor aProperty,
bool aSkipBitCheck);
template<typename T>
struct ReinterpretHelper
@ -392,22 +418,21 @@ protected:
};
/**
* This class encapsulates the properties of a frame.
* The FrameProperties/ConstFrameProperties class encapsulates the
* properties of a frame.
*
* However, since frame properties are like member variables, we have
* different versions for whether the frame is |const|, sharing a common
* base class.
*
* CVnsIFrame is either |nsIFrame| or |const nsIFrame|.
*/
class FrameProperties {
template<class CVnsIFrame>
class FramePropertiesBase {
public:
template<typename T> using Descriptor = FramePropertyTable::Descriptor<T>;
template<typename T> using PropertyType = FramePropertyTable::PropertyType<T>;
FrameProperties(FramePropertyTable* aTable, const nsIFrame* aFrame)
: mTable(aTable), mFrame(aFrame) {}
template<typename T>
void Set(Descriptor<T> aProperty, PropertyType<T> aValue) const
{
mTable->Set(mFrame, aProperty, aValue);
}
template<typename T>
bool Has(Descriptor<T> aProperty) const
{
@ -420,21 +445,49 @@ public:
{
return mTable->Get(mFrame, aProperty, aFoundResult);
}
protected:
FramePropertiesBase(FramePropertyTable* aTable, CVnsIFrame* aFrame)
: mTable(aTable), mFrame(aFrame) {}
FramePropertyTable* const mTable;
CVnsIFrame* const mFrame;
};
class ConstFrameProperties : public FramePropertiesBase<const nsIFrame> {
public:
ConstFrameProperties(FramePropertyTable* aTable, const nsIFrame* aFrame)
: FramePropertiesBase(aTable, aFrame)
{
}
};
class FrameProperties : public FramePropertiesBase<nsIFrame> {
public:
FrameProperties(FramePropertyTable* aTable, nsIFrame* aFrame)
: FramePropertiesBase(aTable, aFrame)
{
}
template<typename T>
void Set(Descriptor<T> aProperty, PropertyType<T> aValue) const
{
mTable->Set(mFrame, aProperty, aValue);
}
template<typename T>
PropertyType<T> Remove(Descriptor<T> aProperty,
bool* aFoundResult = nullptr) const
{
return mTable->Remove(mFrame, aProperty, aFoundResult);
}
template<typename T>
void Delete(Descriptor<T> aProperty)
void Delete(Descriptor<T> aProperty) const
{
mTable->Delete(mFrame, aProperty);
}
private:
FramePropertyTable* mTable;
const nsIFrame* mFrame;
};
} // namespace mozilla

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

@ -6003,8 +6003,6 @@ PresShell::MarkFramesInSubtreeApproximatelyVisible(nsIFrame* aFrame,
nsIScrollableFrame* scrollFrame = do_QueryFrame(aFrame);
if (scrollFrame) {
scrollFrame->NotifyApproximateFrameVisibilityUpdate();
bool ignoreDisplayPort = false;
if (nsLayoutUtils::IsMissingDisplayPortBaseRect(aFrame->GetContent())) {
// We can properly set the base rect for root scroll frames on top level
@ -6023,6 +6021,8 @@ PresShell::MarkFramesInSubtreeApproximatelyVisible(nsIFrame* aFrame,
}
}
scrollFrame->NotifyApproximateFrameVisibilityUpdate(ignoreDisplayPort);
nsRect displayPort;
bool usingDisplayport = !ignoreDisplayPort &&
nsLayoutUtils::GetDisplayPortForVisibilityTesting(

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

@ -1396,7 +1396,8 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
break;
}
const nsStyleChangeData& data = aChangeList[i];
nsStyleChangeData& mutable_data = aChangeList[i];
const nsStyleChangeData& data = mutable_data;
nsIFrame* frame = data.mFrame;
nsIContent* content = data.mContent;
nsChangeHint hint = data.mHint;
@ -1407,7 +1408,11 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
"Reflow hint bits set without actually asking for a reflow");
// skip any frame that has been destroyed due to a ripple effect
if (frame && !propTable->Get(frame, ChangeListProperty())) {
if (frame && !propTable->HasSkippingBitCheck(frame, ChangeListProperty())) {
// Null out the pointer since the frame was already destroyed.
// This is important so we don't try to delete its
// ChangeListProperty() below.
mutable_data.mFrame = nullptr;
continue;
}
@ -1475,6 +1480,11 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
}
if (hint & nsChangeHint_ReconstructFrame) {
// We're about to destroy data.mFrame, so null out the pointer.
// This is important so we don't try to delete its
// ChangeListProperty() below.
mutable_data.mFrame = nullptr;
// If we ever start passing true here, be careful of restyles
// that involve a reframe and animations. In particular, if the
// restyle we're processing here is an animation restyle, but
@ -1664,7 +1674,7 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
// is not in fact in a consistent state.
for (const nsStyleChangeData& data : aChangeList) {
if (data.mFrame) {
propTable->Delete(data.mFrame, ChangeListProperty());
propTable->DeleteSkippingBitCheck(data.mFrame, ChangeListProperty());
}
#ifdef DEBUG

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

@ -1702,7 +1702,7 @@ nsIFrame::GetVisibility() const
}
bool isSet = false;
FrameProperties props = Properties();
ConstFrameProperties props = Properties();
uint32_t visibleCount = props.Get(VisibilityStateProperty(), &isSet);
MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value "
@ -9982,8 +9982,9 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState,
parentReflowInput(aPresContext, parentFrame, aRenderingContext,
LogicalSize(parentWM, parentSize),
ReflowInput::DUMMY_PARENT_REFLOW_STATE);
parentFrame->RemoveStateBits(~nsFrameState(0));
parentFrame->AddStateBits(savedState);
const nsFrameState bitsToLeaveUntouched = NS_FRAME_HAS_PROPERTIES;
parentFrame->RemoveStateBits(~bitsToLeaveUntouched);
parentFrame->AddStateBits(savedState & ~bitsToLeaveUntouched);
// This may not do very much useful, but it's probably worth trying.
if (parentSize.width != NS_INTRINSICSIZE)
@ -10543,7 +10544,7 @@ nsFrame::Trace(const char* aMethod, bool aEnter)
if (NS_FRAME_LOG_TEST(sFrameLogModule, NS_FRAME_TRACE_CALLS)) {
char tagbuf[40];
GetTagName(this, mContent, sizeof(tagbuf), tagbuf);
PR_LogPrint("%s: %s %s", tagbuf, aEnter ? "enter" : "exit", aMethod);
printf_stderr("%s: %s %s", tagbuf, aEnter ? "enter" : "exit", aMethod);
}
}
@ -10553,7 +10554,7 @@ nsFrame::Trace(const char* aMethod, bool aEnter, nsReflowStatus aStatus)
if (NS_FRAME_LOG_TEST(sFrameLogModule, NS_FRAME_TRACE_CALLS)) {
char tagbuf[40];
GetTagName(this, mContent, sizeof(tagbuf), tagbuf);
PR_LogPrint("%s: %s %s, status=%scomplete%s",
printf_stderr("%s: %s %s, status=%scomplete%s",
tagbuf, aEnter ? "enter" : "exit", aMethod,
aStatus.IsIncomplete() ? "not" : "",
(aStatus.NextInFlowNeedsReflow()) ? "+reflow" : "");
@ -10573,7 +10574,7 @@ nsFrame::TraceMsg(const char* aFormatString, ...)
char tagbuf[40];
GetTagName(this, mContent, sizeof(tagbuf), tagbuf);
PR_LogPrint("%s: %s", tagbuf, argbuf);
printf_stderr("%s: %s", tagbuf, argbuf);
}
}

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

@ -24,6 +24,9 @@
* PRLogModuleInfo.level field to be a bitfield. Each bit controls a
* specific type of logging. Each logging operation has associated
* inline methods defined below.
*
* Due to the redefinition of the level field we cannot use MOZ_LOG directly
* as that will cause assertions due to invalid log levels.
*/
#define NS_FRAME_TRACE_CALLS 0x1
#define NS_FRAME_TRACE_PUSH_PULL 0x2
@ -36,7 +39,7 @@
#define NS_FRAME_LOG(_bit,_args) \
PR_BEGIN_MACRO \
if (NS_FRAME_LOG_TEST(nsFrame::sFrameLogModule,_bit)) { \
PR_LogPrint _args; \
printf_stderr _args; \
} \
PR_END_MACRO
#else

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

@ -270,6 +270,9 @@ FRAME_STATE_BIT(Generic, 54, NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY)
// a stylo tree traversal.
FRAME_STATE_BIT(Generic, 55, NS_FRAME_OWNS_ANON_BOXES)
// Frame has properties in the nsIFrame::Properties() hash.
FRAME_STATE_BIT(Generic, 56, NS_FRAME_HAS_PROPERTIES)
// Set for all descendants of MathML sub/supscript elements (other than the
// base frame) to indicate that the SSTY font feature should be used.
FRAME_STATE_BIT(Generic, 58, NS_FRAME_MATHML_SCRIPT_DESCENDANT)

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

@ -2717,12 +2717,17 @@ ScrollFrameHelper::ScheduleSyntheticMouseMove()
}
void
ScrollFrameHelper::NotifyApproximateFrameVisibilityUpdate()
ScrollFrameHelper::NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort)
{
mLastUpdateFramesPos = GetScrollPosition();
mHadDisplayPortAtLastFrameUpdate =
nsLayoutUtils::GetDisplayPort(mOuter->GetContent(),
&mDisplayPortAtLastFrameUpdate);
if (aIgnoreDisplayPort) {
mHadDisplayPortAtLastFrameUpdate = false;
mDisplayPortAtLastFrameUpdate = nsRect();
} else {
mHadDisplayPortAtLastFrameUpdate =
nsLayoutUtils::GetDisplayPort(mOuter->GetContent(),
&mDisplayPortAtLastFrameUpdate);
}
}
bool
@ -3238,7 +3243,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists)
{
if (aBuilder->IsForFrameVisibility()) {
NotifyApproximateFrameVisibilityUpdate();
NotifyApproximateFrameVisibilityUpdate(false);
}
mOuter->DisplayBorderBackgroundOutline(aBuilder, aLists);

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

@ -405,7 +405,7 @@ public:
bool DecideScrollableLayer(nsDisplayListBuilder* aBuilder,
nsRect* aDirtyRect,
bool aAllowCreateDisplayPort);
void NotifyApproximateFrameVisibilityUpdate();
void NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort);
bool GetDisplayPortAtLastApproximateFrameVisibilityUpdate(nsRect* aDisplayPort);
bool AllowDisplayPortExpiration();
@ -943,8 +943,8 @@ public:
bool aAllowCreateDisplayPort) override {
return mHelper.DecideScrollableLayer(aBuilder, aDirtyRect, aAllowCreateDisplayPort);
}
virtual void NotifyApproximateFrameVisibilityUpdate() override {
mHelper.NotifyApproximateFrameVisibilityUpdate();
virtual void NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort) override {
mHelper.NotifyApproximateFrameVisibilityUpdate(aIgnoreDisplayPort);
}
virtual bool GetDisplayPortAtLastApproximateFrameVisibilityUpdate(nsRect* aDisplayPort) override {
return mHelper.GetDisplayPortAtLastApproximateFrameVisibilityUpdate(aDisplayPort);
@ -1463,8 +1463,8 @@ public:
bool aAllowCreateDisplayPort) override {
return mHelper.DecideScrollableLayer(aBuilder, aDirtyRect, aAllowCreateDisplayPort);
}
virtual void NotifyApproximateFrameVisibilityUpdate() override {
mHelper.NotifyApproximateFrameVisibilityUpdate();
virtual void NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort) override {
mHelper.NotifyApproximateFrameVisibilityUpdate(aIgnoreDisplayPort);
}
virtual bool GetDisplayPortAtLastApproximateFrameVisibilityUpdate(nsRect* aDisplayPort) override {
return mHelper.GetDisplayPortAtLastApproximateFrameVisibilityUpdate(aDisplayPort);

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

@ -577,6 +577,7 @@ public:
using Visibility = mozilla::Visibility;
typedef mozilla::FrameProperties FrameProperties;
typedef mozilla::ConstFrameProperties ConstFrameProperties;
typedef mozilla::layers::Layer Layer;
typedef mozilla::layout::FrameChildList ChildList;
typedef mozilla::layout::FrameChildListID ChildListID;
@ -3251,10 +3252,14 @@ public:
return mContent == aParentContent;
}
FrameProperties Properties() const {
FrameProperties Properties() {
return FrameProperties(PresContext()->PropertyTable(), this);
}
ConstFrameProperties Properties() const {
return ConstFrameProperties(PresContext()->PropertyTable(), this);
}
/**
* Return true if and only if this frame obeys visibility:hidden.
* if it does not, then nsContainerFrame will hide its view even though

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

@ -452,8 +452,10 @@ public:
/**
* Notification that this scroll frame is getting its frame visibility updated.
* aIgnoreDisplayPort indicates that the display port was ignored (because
* there was no suitable base rect)
*/
virtual void NotifyApproximateFrameVisibilityUpdate() = 0;
virtual void NotifyApproximateFrameVisibilityUpdate(bool aIgnoreDisplayPort) = 0;
/**
* Returns true if this scroll frame had a display port at the last frame

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

@ -63,9 +63,6 @@
#include "nsAccessibilityService.h"
#endif
#ifdef MOZ_LOGGING
#define FORCE_PR_LOG 1 /* Allow logging in the release build */
#endif /* MOZ_LOGGING */
#include "mozilla/Logging.h"
#ifdef XP_MACOSX

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

@ -3204,7 +3204,7 @@ protected:
const nsStyleText* mTextStyle;
const nsTextFragment* mFrag;
const nsIFrame* mLineContainer;
const nsTextFrame* mFrame;
nsTextFrame* mFrame;
gfxSkipCharsIterator mStart; // Offset in original and transformed string
const gfxSkipCharsIterator mTempIterator;

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

@ -167,7 +167,7 @@ FindCellProperty(const nsIFrame* aCellFrame,
nsTArray<int8_t>* propertyData = nullptr;
while (currentFrame) {
FrameProperties props = currentFrame->Properties();
ConstFrameProperties props = currentFrame->Properties();
propertyData = props.Get(aFrameProperty);
bool frameIsTable = (currentFrame->GetType() == nsGkAtoms::tableFrame);

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

@ -2306,6 +2306,12 @@ nsDisplayItem* nsDisplayList::RemoveBottom() {
void nsDisplayList::DeleteAll() {
nsDisplayItem* item;
while ((item = RemoveBottom()) != nullptr) {
#ifdef NIGHTLY_BUILD
if (XRE_IsContentProcess()) {
mozilla::Telemetry::Accumulate(mozilla::Telemetry::DISPLAY_ITEM_USAGE_COUNT,
item->GetType());
}
#endif
item->~nsDisplayItem();
}
}

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

@ -2794,11 +2794,17 @@ nsTableFrame::GetUsedMargin() const
NS_DECLARE_FRAME_PROPERTY_DELETABLE(TableBCProperty, BCPropertyData)
BCPropertyData*
nsTableFrame::GetBCProperty(bool aCreateIfNecessary) const
nsTableFrame::GetBCProperty() const
{
return Properties().Get(TableBCProperty());
}
BCPropertyData*
nsTableFrame::GetOrCreateBCProperty()
{
FrameProperties props = Properties();
BCPropertyData* value = props.Get(TableBCProperty());
if (!value && aCreateIfNecessary) {
if (!value) {
value = new BCPropertyData();
props.Set(TableBCProperty(), value);
}
@ -4247,7 +4253,7 @@ nsTableFrame::AddBCDamageArea(const TableArea& aValue)
SetNeedToCalcBCBorders(true);
// Get the property
BCPropertyData* value = GetBCProperty(true);
BCPropertyData* value = GetOrCreateBCProperty();
if (value) {
#ifdef DEBUG
VerifyNonNegativeDamageRect(value->mDamageArea);
@ -4287,7 +4293,7 @@ nsTableFrame::SetFullBCDamageArea()
SetNeedToCalcBCBorders(true);
BCPropertyData* value = GetBCProperty(true);
BCPropertyData* value = GetOrCreateBCProperty();
if (value) {
value->mDamageArea = TableArea(0, 0, GetColCount(), GetRowCount());
}

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

@ -807,7 +807,8 @@ protected:
void SetBorderCollapse(bool aValue);
BCPropertyData* GetBCProperty(bool aCreateIfNecessary = false) const;
BCPropertyData* GetBCProperty() const;
BCPropertyData* GetOrCreateBCProperty();
void SetFullBCDamageArea();
void CalcBCBorders();

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

@ -24,7 +24,21 @@
static mozilla::LazyLogModule log(n); \
return static_cast<mozilla::LogModule*>(log); \
}
#define MOZ_MTLOG(level, b) \
do { \
if (MOZ_LOG_TEST(getLogModule(), level)) { \
std::stringstream str; \
str << b; \
MOZ_LOG(getLogModule(), level, ("%s", str.str().c_str())); \
} \
} while(0)
#else
// When building mtransport outside of XUL, for example in stand-alone gtests,
// PR_Logging needs to be used instead of mozilla logging.
#include "prlog.h"
#define MOZ_MTLOG_MODULE(n) \
static PRLogModuleInfo* getLogModule() { \
static PRLogModuleInfo* log; \
@ -32,15 +46,14 @@
log = PR_NewLogModule(n); \
return log; \
}
#endif
#define MOZ_MTLOG(level, b) \
do { \
if (MOZ_LOG_TEST(getLogModule(), level)) { \
std::stringstream str; \
str << b; \
MOZ_LOG(getLogModule(), level, ("%s", str.str().c_str())); \
} \
#define MOZ_MTLOG(level, b) \
do { \
if (PR_LOG_TEST(getLogModule(), (PRLogModuleLevel)level)) { \
std::stringstream str; \
str << b; \
PR_LOG(getLogModule(), (PRLogModuleLevel)level, ("%s", str.str().c_str())); \
} \
} while(0)
#endif // MOZILLA_INTERNAL_API
#endif // logging_h__

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

@ -1,3 +1,5 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* vim: ts=4 sw=4 expandtab:
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
@ -9,7 +11,6 @@ import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.mozglue.JNIObject;
import org.mozilla.gecko.NativeQueue.StateHolder;
import org.mozilla.gecko.util.BundleEventListener;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoBundle;
@ -55,7 +56,7 @@ public final class EventDispatcher extends JNIObject {
new HashMap<String, List<BundleEventListener>>(DEFAULT_BACKGROUND_EVENTS_COUNT);
private boolean mAttachedToGecko;
private volatile StateHolder mStateHolder;
private final NativeQueue mNativeQueue;
@ReflectionTarget
@WrapForJNI(calledFrom = "gecko")
@ -64,22 +65,15 @@ public final class EventDispatcher extends JNIObject {
}
/* package */ EventDispatcher() {
mStateHolder = GeckoThread.getStateHolder();
mNativeQueue = GeckoThread.getNativeQueue();
}
/* package */ EventDispatcher(final NativeQueue.StateHolder stateHolder) {
mStateHolder = stateHolder;
}
/* package */ void setStateHolder(final NativeQueue.StateHolder stateHolder) {
mStateHolder = stateHolder;
// Force queue flushing.
final NativeQueue.State state = mStateHolder.getState();
mStateHolder.checkAndSetState(state, state);
/* package */ EventDispatcher(final NativeQueue queue) {
mNativeQueue = queue;
}
private boolean isReadyForDispatchingToGecko() {
return mStateHolder.isReady();
return mNativeQueue.isReady();
}
@WrapForJNI(dispatchTo = "gecko") @Override // JNIObject
@ -301,8 +295,7 @@ public final class EventDispatcher extends JNIObject {
// Gecko, we make a special exception to queue this event until
// Gecko(View) is ready. This way, Gecko can first register its
// listeners, and accept the event when it is ready.
NativeQueue.queueUntil(mStateHolder,
mStateHolder.getReadyState(), this, "dispatchToGecko",
mNativeQueue.queueUntilReady(this, "dispatchToGecko",
String.class, type,
GeckoBundle.class, message,
EventCallback.class, JavaCallbackDelegate.wrap(callback));

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

@ -8,7 +8,6 @@ package org.mozilla.gecko;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.mozglue.GeckoLoader;
import org.mozilla.gecko.NativeQueue.StateHolder;
import org.mozilla.gecko.util.FileUtils;
import org.mozilla.gecko.util.ThreadUtils;
@ -80,11 +79,11 @@ public class GeckoThread extends Thread {
}
}
private static final StateHolder sStateHolder =
new StateHolder(State.INITIAL, State.RUNNING);
private static final NativeQueue sNativeQueue =
new NativeQueue(State.INITIAL, State.RUNNING);
/* package */ static StateHolder getStateHolder() {
return sStateHolder;
/* package */ static NativeQueue getNativeQueue() {
return sNativeQueue;
}
public static final State MIN_STATE = State.INITIAL;
@ -446,7 +445,7 @@ public class GeckoThread extends Thread {
* @return True if the current Gecko thread state matches
*/
public static boolean isState(final State state) {
return sStateHolder.getState().is(state);
return sNativeQueue.getState().is(state);
}
/**
@ -457,7 +456,7 @@ public class GeckoThread extends Thread {
* @return True if the current Gecko thread state matches
*/
public static boolean isStateAtLeast(final State state) {
return sStateHolder.getState().isAtLeast(state);
return sNativeQueue.getState().isAtLeast(state);
}
/**
@ -468,7 +467,7 @@ public class GeckoThread extends Thread {
* @return True if the current Gecko thread state matches
*/
public static boolean isStateAtMost(final State state) {
return state.isAtLeast(sStateHolder.getState());
return state.isAtLeast(sNativeQueue.getState());
}
/**
@ -485,13 +484,13 @@ public class GeckoThread extends Thread {
@WrapForJNI(calledFrom = "gecko")
private static void setState(final State newState) {
sStateHolder.setState(newState);
sNativeQueue.setState(newState);
}
@WrapForJNI(calledFrom = "gecko")
private static boolean checkAndSetState(final State expectedState,
final State newState) {
return sStateHolder.checkAndSetState(expectedState, newState);
return sNativeQueue.checkAndSetState(expectedState, newState);
}
@WrapForJNI(stubName = "SpeculativeConnect")
@ -561,7 +560,7 @@ public class GeckoThread extends Thread {
*/
public static void queueNativeCall(final Class<?> cls, final String methodName,
final Object... args) {
NativeQueue.queueUntil(getStateHolder(), State.RUNNING, cls, methodName, args);
sNativeQueue.queueUntilReady(cls, methodName, args);
}
/**
@ -569,7 +568,7 @@ public class GeckoThread extends Thread {
*/
public static void queueNativeCall(final Object obj, final String methodName,
final Object... args) {
NativeQueue.queueUntil(getStateHolder(), State.RUNNING, obj, methodName, args);
sNativeQueue.queueUntilReady(obj, methodName, args);
}
/**
@ -577,7 +576,7 @@ public class GeckoThread extends Thread {
*/
public static void queueNativeCallUntil(final State state, final Object obj, final String methodName,
final Object... args) {
NativeQueue.queueUntil(getStateHolder(), state, obj, methodName, args);
sNativeQueue.queueUntil(state, obj, methodName, args);
}
/**
@ -585,6 +584,6 @@ public class GeckoThread extends Thread {
*/
public static void queueNativeCallUntil(final State state, final Class<?> cls, final String methodName,
final Object... args) {
NativeQueue.queueUntil(getStateHolder(), state, cls, methodName, args);
sNativeQueue.queueUntil(state, cls, methodName, args);
}
}

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

@ -12,7 +12,6 @@ import org.mozilla.gecko.annotation.ReflectionTarget;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.mozglue.JNIObject;
import org.mozilla.gecko.NativeQueue.StateHolder;
import org.mozilla.gecko.util.BundleEventListener;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoBundle;
@ -47,7 +46,7 @@ public class GeckoView extends LayerView
@WrapForJNI INITIAL(0),
@WrapForJNI READY(1);
private int mRank;
private final int mRank;
private State(int rank) {
mRank = rank;
@ -60,18 +59,16 @@ public class GeckoView extends LayerView
@Override
public boolean isAtLeast(final NativeQueue.State other) {
if (other instanceof State) {
return mRank >= ((State) other).mRank;
}
return false;
return (other instanceof State) &&
mRank >= ((State) other).mRank;
}
}
private static final StateHolder sDummyStateHolder =
new StateHolder(State.INITIAL, State.READY);
private final NativeQueue mNativeQueue =
new NativeQueue(State.INITIAL, State.READY);
private final EventDispatcher mEventDispatcher =
new EventDispatcher(sDummyStateHolder);
new EventDispatcher(mNativeQueue);
private ChromeDelegate mChromeDelegate;
/* package */ ContentListener mContentListener;
@ -88,11 +85,12 @@ public class GeckoView extends LayerView
@WrapForJNI(dispatchTo = "proxy")
protected static final class Window extends JNIObject {
@WrapForJNI(skip = true)
/* package */ final StateHolder mStateHolder =
new StateHolder(State.INITIAL, State.READY);
/* package */ NativeQueue mNativeQueue;
@WrapForJNI(skip = true)
/* package */ Window() {}
/* package */ Window(final NativeQueue queue) {
mNativeQueue = queue;
}
static native void open(Window instance, GeckoView view,
Object compositor, EventDispatcher dispatcher,
@ -109,8 +107,8 @@ public class GeckoView extends LayerView
native void loadUri(String uri, int flags);
@WrapForJNI(calledFrom = "gecko")
private void setState(final State newState) {
mStateHolder.setState(newState);
private synchronized void setState(final State newState) {
mNativeQueue.setState(newState);
}
}
@ -287,7 +285,12 @@ public class GeckoView extends LayerView
}
protected void reattachWindow() {
mEventDispatcher.setStateHolder(mWindow.mStateHolder);
synchronized (mWindow) {
if (mNativeQueue != mWindow.mNativeQueue) {
mNativeQueue.setState(mWindow.mNativeQueue.getState());
mWindow.mNativeQueue = mNativeQueue;
}
}
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
mWindow.reattach(this, getCompositor(), mEventDispatcher);
@ -304,8 +307,7 @@ public class GeckoView extends LayerView
if (mWindow == null) {
// Open a new nsWindow if we didn't have one from before.
mWindow = new Window();
mEventDispatcher.setStateHolder(mWindow.mStateHolder);
mWindow = new Window(mNativeQueue);
openWindow();
} else {
reattachWindow();
@ -336,7 +338,6 @@ public class GeckoView extends LayerView
mWindow, "disposeNative");
}
mEventDispatcher.setStateHolder(sDummyStateHolder);
mOnAttachedToWindowCalled = false;
}

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

@ -1,4 +1,5 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* vim: ts=4 sw=4 expandtab:
* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
@ -20,42 +21,34 @@ public class NativeQueue {
boolean isAtLeast(final State other);
}
public static class StateHolder {
private volatile State mState;
private final State mReadyState;
private volatile State mState;
private final State mReadyState;
public StateHolder(final State initial, final State ready) {
this.mState = initial;
this.mReadyState = ready;
}
public NativeQueue(final State initial, final State ready) {
mState = initial;
mReadyState = ready;
}
public boolean isReady() {
return getState().isAtLeast(mReadyState);
}
public boolean isReady() {
return getState().isAtLeast(mReadyState);
}
public State getReadyState() {
return mReadyState;
}
public State getState() {
return mState;
}
public State getState() {
return mState;
}
public boolean setState(final State newState) {
return checkAndSetState(null, newState);
}
public boolean setState(final State newState) {
return checkAndSetState(null, newState);
}
public boolean checkAndSetState(final State expectedState,
final State newState) {
synchronized (NativeQueue.sQueue) {
if (expectedState != null && !mState.is(expectedState)) {
return false;
}
NativeQueue.flushQueuedLocked(newState);
mState = newState;
return true;
}
public synchronized boolean checkAndSetState(final State expectedState,
final State newState) {
if (expectedState != null && !mState.is(expectedState)) {
return false;
}
flushQueuedLocked(newState);
mState = newState;
return true;
}
private static class QueuedCall {
@ -74,7 +67,7 @@ public class NativeQueue {
}
private static final int QUEUED_CALLS_COUNT = 16;
/* package */ static final ArrayList<QueuedCall> sQueue =
/* package */ final ArrayList<QueuedCall> mQueue =
new ArrayList<>(QUEUED_CALLS_COUNT);
// Invoke the given Method and handle checked Exceptions.
@ -91,12 +84,11 @@ public class NativeQueue {
}
// Queue a call to the given method.
private static void queueNativeCallLocked(final StateHolder stateHolder,
final Class<?> cls,
final String methodName,
final Object obj,
final Object[] args,
final State state) {
private void queueNativeCallLocked(final Class<?> cls,
final String methodName,
final Object obj,
final Object[] args,
final State state) {
final ArrayList<Class<?>> argTypes = new ArrayList<>(args.length);
final ArrayList<Object> argValues = new ArrayList<>(args.length);
@ -135,63 +127,82 @@ public class NativeQueue {
throw new UnsupportedOperationException("Not allowed to queue non-native methods");
}
if (stateHolder.getState().isAtLeast(state)) {
if (getState().isAtLeast(state)) {
invokeMethod(method, obj, argValues.toArray());
return;
}
sQueue.add(new QueuedCall(
mQueue.add(new QueuedCall(
method, obj, argValues.toArray(), state));
}
/**
* Queue a call to the given instance method if the given current state does
* not satisfy the isReady condition.
*
* @param obj Object that declares the instance method.
* @param methodName Name of the instance method.
* @param args Args to call the instance method with; to specify a parameter
* type, pass in a Class instance first, followed by the value.
*/
public synchronized void queueUntilReady(final Object obj,
final String methodName,
final Object... args) {
queueNativeCallLocked(obj.getClass(), methodName, obj, args, mReadyState);
}
/**
* Queue a call to the given static method if the given current state does
* not satisfy the isReady condition.
*
* @param cls Class that declares the static method.
* @param methodName Name of the instance method.
* @param args Args to call the instance method with; to specify a parameter
* type, pass in a Class instance first, followed by the value.
*/
public synchronized void queueUntilReady(final Class<?> cls,
final String methodName,
final Object... args) {
queueNativeCallLocked(cls, methodName, null, args, mReadyState);
}
/**
* Queue a call to the given instance method if the given current state does
* not satisfy the given state.
*
* @param stateHolder The state holder used to query the current state.
* @param state The state in which the native call could be executed.
* @param obj Object that declares the instance method.
* @param methodName Name of the instance method.
* @param args Args to call the instance method with; to specify a parameter
* type, pass in a Class instance first, followed by the value.
*/
public static void queueUntil(final StateHolder stateHolder,
final State state,
final Object obj,
final String methodName,
final Object... args) {
synchronized (sQueue) {
queueNativeCallLocked(stateHolder, obj.getClass(), methodName, obj,
args, state);
}
public synchronized void queueUntil(final State state, final Object obj,
final String methodName,
final Object... args) {
queueNativeCallLocked(obj.getClass(), methodName, obj, args, state);
}
/**
* Queue a call to the given static method if the given current state does
* not satisfy the given state.
*
* @param stateHolder The state holder used to query the current state.
* @param state The state in which the native call could be executed.
* @param cls Class that declares the static method.
* @param methodName Name of the instance method.
* @param args Args to call the instance method with; to specify a parameter
* type, pass in a Class instance first, followed by the value.
*/
public static void queueUntil(final StateHolder stateHolder,
final State state,
final Class<?> cls,
final String methodName,
final Object... args) {
synchronized (sQueue) {
queueNativeCallLocked(stateHolder, cls, methodName, null, args, state);
}
public synchronized void queueUntil(final State state, final Class<?> cls,
final String methodName,
final Object... args) {
queueNativeCallLocked(cls, methodName, null, args, state);
}
// Run all queued methods
private static void flushQueuedLocked(final State state) {
private void flushQueuedLocked(final State state) {
int lastSkipped = -1;
for (int i = 0; i < sQueue.size(); i++) {
final QueuedCall call = sQueue.get(i);
for (int i = 0; i < mQueue.size(); i++) {
final QueuedCall call = mQueue.get(i);
if (call == null) {
// We already handled the call.
continue;
@ -202,18 +213,18 @@ public class NativeQueue {
continue;
}
// Mark as handled.
sQueue.set(i, null);
mQueue.set(i, null);
invokeMethod(call.method, call.target, call.args);
}
if (lastSkipped < 0) {
// We're done here; release the memory
sQueue.clear();
sQueue.trimToSize();
} else if (lastSkipped < sQueue.size() - 1) {
mQueue.clear();
mQueue.trimToSize();
} else if (lastSkipped < mQueue.size() - 1) {
// We skipped some; free up null entries at the end,
// but keep all the previous entries for later.
sQueue.subList(lastSkipped + 1, sQueue.size()).clear();
mQueue.subList(lastSkipped + 1, mQueue.size()).clear();
}
}
}

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

@ -570,7 +570,7 @@ nsZipArchive::FindInit(const char * aPattern, nsZipFind **aFind)
default:
// undocumented return value from RegExpValid!
PR_ASSERT(false);
MOZ_ASSERT(false);
return NS_ERROR_ILLEGAL_VALUE;
}

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

@ -17,6 +17,7 @@
#include "nsCOMPtr.h"
#include "nsTArray.h"
#include "nsWeakReference.h"
#include "mozilla/Atomics.h"
#include "mozilla/MemoryReporting.h"
class nsIFile;

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

@ -1599,6 +1599,9 @@ pref("network.http.altsvc.oe", true);
// Turn on 0RTT data for TLS 1.3
pref("security.tls.enable_0rtt_data", true);
// the origin extension impacts h2 coalescing
pref("network.http.originextension", true);
pref("network.http.diagnostics", false);
pref("network.http.pacing.requests.enabled", true);

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

@ -131,15 +131,10 @@ ThrottlingService::AddChannel(nsIHttpChannel *channel)
return NS_ERROR_NOT_AVAILABLE;
}
nsAutoCString strKey;
nsresult rv = channel->GetChannelId(strKey);
uint64_t key;
nsresult rv = channel->GetChannelId(&key);
NS_ENSURE_SUCCESS(rv, rv);
nsID key;
if (!key.Parse(strKey.get())) {
return NS_ERROR_UNEXPECTED;
}
if (mChannelHash.Get(key, nullptr)) {
// We already have this channel under our control, not adding it again.
MOZ_ASSERT(false, "Trying to throttle an already-throttled channel");
@ -178,15 +173,10 @@ ThrottlingService::RemoveChannel(nsIHttpChannel *channel)
return NS_ERROR_NOT_AVAILABLE;
}
nsAutoCString strKey;
nsresult rv = channel->GetChannelId(strKey);
uint64_t key;
nsresult rv = channel->GetChannelId(&key);
NS_ENSURE_SUCCESS(rv, rv);
nsID key;
if (!key.Parse(strKey.get())) {
return NS_ERROR_UNEXPECTED;
}
if (!mChannelHash.Get(key, nullptr)) {
// TODO - warn?
return NS_ERROR_ILLEGAL_VALUE;

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

@ -50,7 +50,7 @@ private:
uint32_t mSuspendPeriod; // How long we should Suspend() channels for
uint32_t mResumePeriod; // How long we should Resume() channels for
nsCOMPtr<nsITimer> mTimer;
typedef nsInterfaceHashtable<nsIDHashKey, nsIHttpChannel> ChannelHash;
typedef nsInterfaceHashtable<nsUint64HashKey, nsIHttpChannel> ChannelHash;
ChannelHash mChannelHash;
// Used to avoid inconsistencies in the hash and the suspend/resume count of

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

@ -128,7 +128,7 @@ struct HttpChannelOpenArgs
bool suspendAfterSynthesizeResponse;
bool allowStaleCacheContent;
nsCString contentTypeHint;
nsCString channelId;
uint64_t channelId;
uint64_t contentWindowId;
nsCString preferredAlternativeType;
uint64_t topLevelOuterContentWindowId;

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

@ -32,6 +32,9 @@ public:
static ASpdySession *NewSpdySession(uint32_t version, nsISocketTransport *, bool);
virtual bool TestJoinConnection(const nsACString &hostname, int32_t port) = 0;
virtual bool JoinConnection(const nsACString &hostname, int32_t port) = 0;
// MaybeReTunnel() is called by the connection manager when it cannot
// dispatch a tunneled transaction. That might be because the tunnels it
// expects to see are dead (and we may or may not be able to make more),

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

@ -670,9 +670,9 @@ private:
MakeChannel(nsHttpChannel *chan, TransactionObserver *obs, nsHttpConnectionInfo *ci,
nsIURI *uri, uint32_t caps, nsILoadInfo *loadInfo)
{
nsID channelId;
uint64_t channelId;
nsLoadFlags flags;
if (NS_FAILED(gHttpHandler->NewChannelId(&channelId)) ||
if (NS_FAILED(gHttpHandler->NewChannelId(channelId)) ||
NS_FAILED(chan->Init(uri, caps, nullptr, 0, nullptr, channelId)) ||
NS_FAILED(chan->SetAllowAltSvc(false)) ||
NS_FAILED(chan->SetRedirectMode(nsIHttpChannelInternal::REDIRECT_MODE_ERROR)) ||

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

@ -67,8 +67,7 @@ nsHttpConnectionMgr::OnMsgPrintDiagnostics(int32_t, ARefBase *)
ent->mHalfOpens.Length());
mLogData.AppendPrintf(" Coalescing Keys Length = %" PRIuSIZE "\n",
ent->mCoalescingKeys.Length());
mLogData.AppendPrintf(" Spdy using = %d, preferred = %d\n",
ent->mUsingSpdy, ent->mInPreferredHash);
mLogData.AppendPrintf(" Spdy using = %d\n", ent->mUsingSpdy);
uint32_t i;
for (i = 0; i < ent->mActiveConns.Length(); ++i) {

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

@ -111,6 +111,7 @@ Http2Session::Http2Session(nsISocketTransport *aSocketTransport, uint32_t versio
, mGoAwayOnPush(false)
, mUseH2Deps(false)
, mAttemptingEarlyData(attemptingEarlyData)
, mOriginFrameActivated(false)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
@ -224,7 +225,8 @@ static Http2ControlFx sControlFunctions[] = {
Http2Session::RecvGoAway,
Http2Session::RecvWindowUpdate,
Http2Session::RecvContinuation,
Http2Session::RecvAltSvc // extension for type 0x0A
Http2Session::RecvAltSvc, // extension for type 0x0A
Http2Session::RecvOrigin // extension for type 0x0B
};
bool
@ -1798,26 +1800,23 @@ Http2Session::RecvPushPromise(Http2Session *self)
return NS_OK;
}
RefPtr<nsStandardURL> associatedURL, pushedURL;
rv = Http2Stream::MakeOriginURL(associatedStream->Origin(), associatedURL);
// does the pushed origin belong on this connection?
LOG3(("Http2Session::RecvPushPromise %p origin check %s", self,
pushedStream->Origin().get()));
RefPtr<nsStandardURL> pushedURL;
rv = Http2Stream::MakeOriginURL(pushedStream->Origin(), pushedURL);
nsAutoCString pushedHostName;
int32_t pushedPort = -1;
if (NS_SUCCEEDED(rv)) {
rv = Http2Stream::MakeOriginURL(pushedStream->Origin(), pushedURL);
rv = pushedURL->GetHost(pushedHostName);
}
LOG3(("Http2Session::RecvPushPromise %p checking %s == %s", self,
associatedStream->Origin().get(), pushedStream->Origin().get()));
bool match = false;
if (NS_SUCCEEDED(rv)) {
rv = associatedURL->Equals(pushedURL, &match);
rv = pushedURL->GetPort(&pushedPort);
}
if (NS_FAILED(rv)) {
// Fallback to string equality of origins. This won't be guaranteed to be as
// liberal as we want it to be, but it will at least be safe
match = associatedStream->Origin().Equals(pushedStream->Origin());
}
if (!match) {
LOG3(("Http2Session::RecvPushPromise %p pushed stream mismatched origin "
"associated origin %s .. pushed origin %s\n", self,
associatedStream->Origin().get(), pushedStream->Origin().get()));
if (NS_FAILED(rv) ||
!self->TestJoinConnection(pushedHostName, pushedPort)) {
LOG3(("Http2Session::RecvPushPromise %p pushed stream mismatched origin %s\n",
self, pushedStream->Origin().get()));
self->CleanupStream(pushedStream, NS_ERROR_FAILURE, REFUSED_STREAM_ERROR);
self->ResetDownstreamState();
return NS_OK;
@ -2291,6 +2290,111 @@ Http2Session::RecvAltSvc(Http2Session *self)
return NS_OK;
}
void
Http2Session::Received421(nsHttpConnectionInfo *ci)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
LOG3(("Http2Session::Recevied421 %p %d\n", this, mOriginFrameActivated));
if (!mOriginFrameActivated || !ci) {
return;
}
nsAutoCString key(ci->GetOrigin());
key.Append(':');
key.AppendInt(ci->OriginPort());
mOriginFrame.Remove(key);
LOG3(("Http2Session::Received421 %p key %s removed\n", this, key.get()));
}
// defined as an http2 extension - origin
// defines receipt of frame type 0x0b.. http://httpwg.org/http-extensions/origin-frame.html
// as this is an extension, never generate protocol error - just ignore problems
nsresult
Http2Session::RecvOrigin(Http2Session *self)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
MOZ_ASSERT(self->mInputFrameType == FRAME_TYPE_ORIGIN);
LOG3(("Http2Session::RecvOrigin %p Flags 0x%X id 0x%X\n", self,
self->mInputFrameFlags, self->mInputFrameID));
if (self->mInputFrameFlags & 0x0F) {
LOG3(("Http2Session::RecvOrigin %p leading flags must be 0", self));
self->ResetDownstreamState();
return NS_OK;
}
if (self->mInputFrameID) {
LOG3(("Http2Session::RecvOrigin %p not stream 0", self));
self->ResetDownstreamState();
return NS_OK;
}
if (self->ConnectionInfo()->UsingProxy()) {
LOG3(("Http2Session::RecvOrigin %p must not use proxy", self));
self->ResetDownstreamState();
return NS_OK;
}
if (!gHttpHandler->AllowOriginExtension()) {
LOG3(("Http2Session::RecvOrigin %p origin extension pref'd off", self));
self->ResetDownstreamState();
return NS_OK;
}
uint32_t offset = 0;
self->mOriginFrameActivated = true;
while (self->mInputFrameDataSize >= (offset + 2U)) {
uint16_t originLen = NetworkEndian::readUint16(
self->mInputFrameBuffer.get() + kFrameHeaderBytes + offset);
LOG3(("Http2Session::RecvOrigin %p origin extension defined as %d bytes\n", self, originLen));
if (originLen + 2U + offset > self->mInputFrameDataSize) {
LOG3(("Http2Session::RecvOrigin %p origin len too big for frame", self));
break;
}
nsAutoCString originString;
RefPtr<nsStandardURL> originURL;
originString.Assign(self->mInputFrameBuffer.get() + kFrameHeaderBytes + offset + 2, originLen);
offset += originLen + 2;
if (NS_FAILED(Http2Stream::MakeOriginURL(originString, originURL))){
LOG3(("Http2Session::RecvOrigin %p origin frame string %s failed to parse\n", self, originString.get()));
continue;
}
LOG3(("Http2Session::RecvOrigin %p origin frame string %s parsed OK\n", self, originString.get()));
bool isHttps = false;
if (NS_FAILED(originURL->SchemeIs("https", &isHttps)) || !isHttps) {
LOG3(("Http2Session::RecvOrigin %p origin frame not https\n", self));
continue;
}
int32_t port = -1;
originURL->GetPort(&port);
if (port == -1) {
port = 443;
}
// dont use ->GetHostPort because we want explicit 443
nsAutoCString host;
originURL->GetHost(host);
nsAutoCString key(host);
key.Append(':');
key.AppendInt(port);
if (!self->mOriginFrame.Get(key)) {
self->mOriginFrame.Put(key, true);
RefPtr<nsHttpConnection> conn(self->HttpConnection());
MOZ_ASSERT(conn.get());
gHttpHandler->ConnMgr()->RegisterOriginCoalescingKey(conn, host, port);
} else {
LOG3(("Http2Session::RecvOrigin %p origin frame already in set\n", self));
}
}
self->ResetDownstreamState();
return NS_OK;
}
//-----------------------------------------------------------------------------
// nsAHttpTransaction. It is expected that nsHttpConnection is the caller
// of these methods
@ -3848,6 +3952,15 @@ Http2Session::TakeHttpConnection()
return nullptr;
}
already_AddRefed<nsHttpConnection>
Http2Session::HttpConnection()
{
if (mConnection) {
return mConnection->HttpConnection();
}
return nullptr;
}
void
Http2Session::GetSecurityCallbacks(nsIInterfaceRequestor **aOut)
{
@ -4005,5 +4118,108 @@ Http2Session::SendPing()
Unused << ResumeRecv();
}
bool
Http2Session::TestOriginFrame(const nsACString &hostname, int32_t port)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
MOZ_ASSERT(mOriginFrameActivated);
nsAutoCString key(hostname);
key.Append (':');
key.AppendInt(port);
bool rv = mOriginFrame.Get(key);
LOG3(("TestOriginFrame() hash.get %p %s %d\n", this, key.get(), rv));
if (!rv && ConnectionInfo()) {
// the SNI is also implicitly in this list, so consult that too
nsHttpConnectionInfo *ci = ConnectionInfo();
rv = nsCString(hostname).EqualsIgnoreCase(ci->Origin()) && (port == ci->OriginPort());
LOG3(("TestOriginFrame() %p sni test %d\n", this, rv));
}
return rv;
}
bool
Http2Session::TestJoinConnection(const nsACString &hostname, int32_t port)
{
if (!mConnection || mClosed || mShouldGoAway) {
return false;
}
if (mOriginFrameActivated) {
bool originFrameResult = TestOriginFrame(hostname, port);
if (!originFrameResult) {
return false;
}
} else {
LOG3(("TestJoinConnection %p no origin frame check used.\n", this));
}
nsresult rv;
bool isJoined = false;
nsCOMPtr<nsISupports> securityInfo;
nsCOMPtr<nsISSLSocketControl> sslSocketControl;
mConnection->GetSecurityInfo(getter_AddRefs(securityInfo));
sslSocketControl = do_QueryInterface(securityInfo, &rv);
if (NS_FAILED(rv) || !sslSocketControl) {
return false;
}
// try all the coalescable versions we support.
const SpdyInformation *info = gHttpHandler->SpdyInfo();
for (uint32_t index = SpdyInformation::kCount; index > 0; --index) {
if (info->ProtocolEnabled(index - 1)) {
rv = sslSocketControl->TestJoinConnection(info->VersionString[index - 1],
hostname, port, &isJoined);
if (NS_SUCCEEDED(rv) && isJoined) {
return true;
}
}
}
return false;
}
bool
Http2Session::JoinConnection(const nsACString &hostname, int32_t port)
{
if (!mConnection || mClosed || mShouldGoAway) {
return false;
}
if (mOriginFrameActivated) {
bool originFrameResult = TestOriginFrame(hostname, port);
if (!originFrameResult) {
return false;
}
} else {
LOG3(("JoinConnection %p no origin frame check used.\n", this));
}
nsresult rv;
bool isJoined = false;
nsCOMPtr<nsISupports> securityInfo;
nsCOMPtr<nsISSLSocketControl> sslSocketControl;
mConnection->GetSecurityInfo(getter_AddRefs(securityInfo));
sslSocketControl = do_QueryInterface(securityInfo, &rv);
if (NS_FAILED(rv) || !sslSocketControl) {
return false;
}
// try all the coalescable versions we support.
const SpdyInformation *info = gHttpHandler->SpdyInfo();
for (uint32_t index = SpdyInformation::kCount; index > 0; --index) {
if (info->ProtocolEnabled(index - 1)) {
rv = sslSocketControl->JoinConnection(info->VersionString[index - 1],
hostname, port, &isJoined);
if (NS_SUCCEEDED(rv) && isJoined) {
return true;
}
}
}
return false;
}
} // namespace net
} // namespace mozilla

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

@ -50,6 +50,8 @@ public:
bool CanReuse() override { return !mShouldGoAway && !mClosed; }
bool RoomForMoreStreams() override;
uint32_t SpdyVersion() override;
bool TestJoinConnection(const nsACString &hostname, int32_t port) override;
bool JoinConnection(const nsACString &hostname, int32_t port) override;
// When the connection is active this is called up to once every 1 second
// return the interval (in seconds) that the connection next wants to
@ -89,7 +91,8 @@ public:
FRAME_TYPE_WINDOW_UPDATE = 0x8,
FRAME_TYPE_CONTINUATION = 0x9,
FRAME_TYPE_ALTSVC = 0xA,
FRAME_TYPE_LAST = 0xB
FRAME_TYPE_ORIGIN = 0xB,
FRAME_TYPE_LAST = 0xC
};
// NO_ERROR is a macro defined on windows, so we'll name the HTTP2 goaway
@ -185,6 +188,7 @@ public:
static nsresult RecvWindowUpdate(Http2Session *);
static nsresult RecvContinuation(Http2Session *);
static nsresult RecvAltSvc(Http2Session *);
static nsresult RecvOrigin(Http2Session *);
char *EnsureOutputBuffer(uint32_t needed);
@ -243,6 +247,9 @@ public:
MOZ_MUST_USE bool Do0RTT() override final { return true; }
MOZ_MUST_USE nsresult Finish0RTT(bool aRestart, bool aAlpnChanged) override final;
// For use by an HTTP2Stream
void Received421(nsHttpConnectionInfo *ci);
private:
// These internal states do not correspond to the states of the HTTP/2 specification
@ -508,6 +515,10 @@ private:
// The ID(s) of the stream(s) that we are getting 0RTT data from.
nsTArray<uint32_t> m0RTTStreams;
bool TestOriginFrame(const nsACString &name, int32_t port);
bool mOriginFrameActivated;
nsDataHashtable<nsCStringHashKey, bool> mOriginFrame;
private:
/// connect tunnels
void DispatchOnTunnel(nsAHttpTransaction *, nsIInterfaceRequestor *);

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

@ -1022,6 +1022,7 @@ Http2Stream::ConvertResponseHeaders(Http2Decompressor *decompressor,
nsresult errcode;
httpResponseCode = statusString.ToInteger(&errcode);
LOG3(("Http2Stream::ConvertResponseHeaders %p response code %d\n", this, httpResponseCode));
if (mIsTunnel) {
LOG3(("Http2Stream %p Tunnel Response code %d", this, httpResponseCode));
if ((httpResponseCode / 100) != 2) {
@ -1035,6 +1036,11 @@ Http2Stream::ConvertResponseHeaders(Http2Decompressor *decompressor,
return NS_ERROR_ILLEGAL_VALUE;
}
if (httpResponseCode == 421) {
// Origin Frame requires 421 to remove this origin from the origin set
mSession->Received421(mTransaction->ConnectionInfo());
}
if (aHeadersIn.Length() && aHeadersOut.Length()) {
Telemetry::Accumulate(Telemetry::SPDY_SYN_REPLY_SIZE, aHeadersIn.Length());
uint32_t ratio =

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

@ -264,7 +264,7 @@ HttpBaseChannel::Init(nsIURI *aURI,
nsProxyInfo *aProxyInfo,
uint32_t aProxyResolveFlags,
nsIURI *aProxyURI,
const nsID& aChannelId)
uint64_t aChannelId)
{
LOG(("HttpBaseChannel::Init [this=%p]\n", this));
@ -1333,25 +1333,18 @@ HttpBaseChannel::nsContentEncodings::PrepareForNext(void)
//-----------------------------------------------------------------------------
NS_IMETHODIMP
HttpBaseChannel::GetChannelId(nsACString& aChannelId)
HttpBaseChannel::GetChannelId(uint64_t *aChannelId)
{
char id[NSID_LENGTH];
mChannelId.ToProvidedString(id);
aChannelId.AssignASCII(id);
NS_ENSURE_ARG_POINTER(aChannelId);
*aChannelId = mChannelId;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SetChannelId(const nsACString& aChannelId)
HttpBaseChannel::SetChannelId(uint64_t aChannelId)
{
nsID newId;
nsAutoCString idStr(aChannelId);
if (newId.Parse(idStr.get())) {
mChannelId = newId;
return NS_OK;
}
return NS_ERROR_FAILURE;
mChannelId = aChannelId;
return NS_OK;
}
NS_IMETHODIMP HttpBaseChannel::GetTopLevelContentWindowId(uint64_t *aWindowId)

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

@ -115,7 +115,7 @@ public:
nsProxyInfo *aProxyInfo,
uint32_t aProxyResolveFlags,
nsIURI *aProxyURI,
const nsID& aChannelId);
uint64_t aChannelId);
// nsIRequest
NS_IMETHOD GetName(nsACString& aName) override;
@ -202,8 +202,8 @@ public:
NS_IMETHOD GetIsMainDocumentChannel(bool* aValue) override;
NS_IMETHOD SetIsMainDocumentChannel(bool aValue) override;
NS_IMETHOD GetProtocolVersion(nsACString & aProtocolVersion) override;
NS_IMETHOD GetChannelId(nsACString& aChannelId) override;
NS_IMETHOD SetChannelId(const nsACString& aChannelId) override;
NS_IMETHOD GetChannelId(uint64_t *aChannelId) override;
NS_IMETHOD SetChannelId(uint64_t aChannelId) override;
NS_IMETHOD GetTopLevelContentWindowId(uint64_t *aContentWindowId) override;
NS_IMETHOD SetTopLevelContentWindowId(uint64_t aContentWindowId) override;
NS_IMETHOD GetTopLevelOuterContentWindowId(uint64_t *aWindowId) override;
@ -611,7 +611,7 @@ protected:
bool mForceMainDocumentChannel;
bool mIsTrackingResource;
nsID mChannelId;
uint64_t mChannelId;
nsString mIntegrityMetadata;

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

@ -1421,7 +1421,7 @@ class Redirect1Event : public ChannelEvent
const uint32_t& redirectFlags,
const nsHttpResponseHead& responseHead,
const nsACString& securityInfoSerialization,
const nsACString& channelId)
const uint64_t& channelId)
: mChild(child)
, mRegistrarId(registrarId)
, mNewURI(newURI)
@ -1450,7 +1450,7 @@ class Redirect1Event : public ChannelEvent
uint32_t mRedirectFlags;
nsHttpResponseHead mResponseHead;
nsCString mSecurityInfoSerialization;
nsCString mChannelId;
uint64_t mChannelId;
};
mozilla::ipc::IPCResult
@ -1459,7 +1459,7 @@ HttpChannelChild::RecvRedirect1Begin(const uint32_t& registrarId,
const uint32_t& redirectFlags,
const nsHttpResponseHead& responseHead,
const nsCString& securityInfoSerialization,
const nsCString& channelId)
const uint64_t& channelId)
{
// TODO: handle security info
LOG(("HttpChannelChild::RecvRedirect1Begin [this=%p]\n", this));
@ -1537,7 +1537,7 @@ HttpChannelChild::Redirect1Begin(const uint32_t& registrarId,
const uint32_t& redirectFlags,
const nsHttpResponseHead& responseHead,
const nsACString& securityInfoSerialization,
const nsACString& channelId)
const uint64_t& channelId)
{
LOG(("HttpChannelChild::Redirect1Begin [this=%p]\n", this));
@ -2418,9 +2418,7 @@ HttpChannelChild::ContinueAsyncOpen()
EnsureRequestContextID();
openArgs.requestContextID() = mRequestContextID;
char chid[NSID_LENGTH];
mChannelId.ToProvidedString(chid);
openArgs.channelId().AssignASCII(chid);
openArgs.channelId() = mChannelId;
openArgs.contentWindowId() = contentWindowId;
openArgs.topLevelOuterContentWindowId() = mTopLevelOuterContentWindowId;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше