Merge mozilla-central to mozilla-inbound. a=merge on a CLOSED TREE

This commit is contained in:
Razvan Maries 2019-01-16 19:09:08 +02:00
Родитель 17fc46877b 4c67bec411
Коммит 3a732b5669
155 изменённых файлов: 5926 добавлений и 1515 удалений

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

@ -135,8 +135,8 @@ HandlerProvider::GetHandlerPayloadSize(
MOZ_ASSERT(mscom::IsCurrentThreadMTA()); MOZ_ASSERT(mscom::IsCurrentThreadMTA());
if (!IsTargetInterfaceCacheable()) { if (!IsTargetInterfaceCacheable()) {
*aOutPayloadSize = mscom::StructToStream::GetEmptySize(); // No handler, so no payload for this instance.
return S_OK; return E_NOTIMPL;
} }
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
@ -378,6 +378,11 @@ bool HandlerProvider::IsTargetInterfaceCacheable() {
HRESULT HRESULT
HandlerProvider::WriteHandlerPayload(NotNull<mscom::IInterceptor*> aInterceptor, HandlerProvider::WriteHandlerPayload(NotNull<mscom::IInterceptor*> aInterceptor,
NotNull<IStream*> aStream) { NotNull<IStream*> aStream) {
if (!IsTargetInterfaceCacheable()) {
// No handler, so no payload for this instance.
return E_NOTIMPL;
}
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
if (!mSerializer || !(*mSerializer)) { if (!mSerializer || !(*mSerializer)) {
@ -435,6 +440,13 @@ HandlerProvider::GetEffectiveOutParamIid(REFIID aCallIid, ULONG aCallMethod) {
return NEWEST_IA2_IID; return NEWEST_IA2_IID;
} }
// IAccessible::get_accSelection
if ((aCallIid == IID_IAccessible || aCallIid == IID_IAccessible2 ||
aCallIid == IID_IAccessible2_2 || aCallIid == IID_IAccessible2_3) &&
aCallMethod == 19) {
return IID_IEnumVARIANT;
}
MOZ_ASSERT(false); MOZ_ASSERT(false);
return IID_IUnknown; return IID_IUnknown;
} }

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

@ -4155,10 +4155,8 @@ const BrowserSearch = {
* allowed values. * allowed values.
* @param type * @param type
* (string) Indicates how the user selected the search item. * (string) Indicates how the user selected the search item.
* @param where
* (string) Where was the search link opened (e.g. new tab, current tab, ..).
*/ */
recordOneoffSearchInTelemetry(engine, source, type, where) { recordOneoffSearchInTelemetry(engine, source, type) {
try { try {
const details = {type, isOneOff: true}; const details = {type, isOneOff: true};
BrowserUsageTelemetry.recordSearch(gBrowser, engine, source, details); BrowserUsageTelemetry.recordSearch(gBrowser, engine, source, details);

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

@ -699,8 +699,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
[url, postData] = [url, postData] =
this._parseAndRecordSearchEngineLoad(selectedOneOff.engine, this._parseAndRecordSearchEngineLoad(selectedOneOff.engine,
this.oneOffSearchQuery, this.oneOffSearchQuery,
event, where, event);
openUILinkParams);
} else if (action) { } else if (action) {
switch (action.type) { switch (action.type) {
case "visiturl": case "visiturl":
@ -776,8 +775,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
action.params.engineName, action.params.engineName,
action.params.searchSuggestion || action.params.searchQuery, action.params.searchSuggestion || action.params.searchQuery,
event, event,
where,
openUILinkParams,
actionDetails actionDetails
); );
break; break;
@ -904,8 +901,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<parameter name="engineOrEngineName"/> <parameter name="engineOrEngineName"/>
<parameter name="query"/> <parameter name="query"/>
<parameter name="event"/> <parameter name="event"/>
<parameter name="openUILinkWhere"/>
<parameter name="openUILinkParams"/>
<parameter name="searchActionDetails"/> <parameter name="searchActionDetails"/>
<body><![CDATA[ <body><![CDATA[
let engine = let engine =
@ -913,7 +908,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
Services.search.getEngineByName(engineOrEngineName) : Services.search.getEngineByName(engineOrEngineName) :
engineOrEngineName; engineOrEngineName;
let isOneOff = this.popup.oneOffSearchButtons let isOneOff = this.popup.oneOffSearchButtons
.maybeRecordTelemetry(event, openUILinkWhere, openUILinkParams); .maybeRecordTelemetry(event);
// Infer the type of the event which triggered the search. // Infer the type of the event which triggered the search.
let eventType = "unknown"; let eventType = "unknown";
if (event instanceof KeyboardEvent) { if (event instanceof KeyboardEvent) {

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

@ -64,6 +64,7 @@
flex="1">&contentBlocking.title;</label> flex="1">&contentBlocking.title;</label>
<toolbarbutton id="tracking-protection-preferences-button" <toolbarbutton id="tracking-protection-preferences-button"
class="identity-popup-preferences-button subviewbutton" class="identity-popup-preferences-button subviewbutton"
tooltiptext="&identity.contentBlockingPreferences.tooltip;"
oncommand="ContentBlocking.openPreferences('identityPopup-TP-preferencesButton'); gIdentityHandler.recordClick('cb_prefs_button');" /> oncommand="ContentBlocking.openPreferences('identityPopup-TP-preferencesButton'); gIdentityHandler.recordClick('cb_prefs_button');" />
</hbox> </hbox>

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

@ -987,13 +987,9 @@ class SearchOneOffs {
* *
* @param {Event} aEvent * @param {Event} aEvent
* An event, like a click on a one-off button. * An event, like a click on a one-off button.
* @param {string} aOpenUILinkWhere
* The "where" passed to openUILink.
* @param {object} aOpenUILinkParams
* The "params" passed to openUILink.
* @returns {boolean} True if telemetry was recorded and false if not. * @returns {boolean} True if telemetry was recorded and false if not.
*/ */
maybeRecordTelemetry(aEvent, aOpenUILinkWhere, aOpenUILinkParams) { maybeRecordTelemetry(aEvent) {
if (!aEvent) { if (!aEvent) {
return false; return false;
} }
@ -1029,11 +1025,7 @@ class SearchOneOffs {
source += "-" + this.telemetryOrigin; source += "-" + this.telemetryOrigin;
} }
let tabBackground = aOpenUILinkWhere == "tab" && BrowserSearch.recordOneoffSearchInTelemetry(engine, source, type);
aOpenUILinkParams &&
aOpenUILinkParams.inBackground;
let where = tabBackground ? "tab-background" : aOpenUILinkWhere;
BrowserSearch.recordOneoffSearchInTelemetry(engine, source, type, where);
return true; return true;
} }

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

@ -304,7 +304,7 @@ class MozSearchbar extends MozXULElement {
if (!selection || (selection.index == -1)) { if (!selection || (selection.index == -1)) {
oneOffRecorded = this.textbox.popup.oneOffButtons oneOffRecorded = this.textbox.popup.oneOffButtons
.maybeRecordTelemetry(aEvent, aWhere, aParams); .maybeRecordTelemetry(aEvent);
if (!oneOffRecorded) { if (!oneOffRecorded) {
let source = "unknown"; let source = "unknown";
let type = "unknown"; let type = "unknown";
@ -325,8 +325,7 @@ class MozSearchbar extends MozXULElement {
if (!aEngine) { if (!aEngine) {
aEngine = this.currentEngine; aEngine = this.currentEngine;
} }
BrowserSearch.recordOneoffSearchInTelemetry(aEngine, source, type, BrowserSearch.recordOneoffSearchInTelemetry(aEngine, source, type);
aWhere);
} }
} }

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

@ -29,7 +29,7 @@ class UrlbarView {
this._mainContainer = this.panel.querySelector(".urlbarView-body-inner"); this._mainContainer = this.panel.querySelector(".urlbarView-body-inner");
this._rows = this.panel.querySelector(".urlbarView-results"); this._rows = this.panel.querySelector(".urlbarView-results");
this._rows.addEventListener("click", this); this._rows.addEventListener("mouseup", this);
// For the horizontal fade-out effect, set the overflow attribute on result // For the horizontal fade-out effect, set the overflow attribute on result
// rows when they overflow. // rows when they overflow.
@ -346,7 +346,12 @@ class UrlbarView {
} }
} }
_on_click(event) { _on_mouseup(event) {
if (event.button == 2) {
// Ignore right clicks.
return;
}
let row = event.target; let row = event.target;
while (!row.classList.contains("urlbarView-row")) { while (!row.classList.contains("urlbarView-row")) {
row = row.parentNode; row = row.parentNode;

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

@ -878,6 +878,8 @@ you can use these alternative items. Otherwise, their values should be empty. -
<!ENTITY identity.permissionsEmpty "You have not granted this site any special permissions."> <!ENTITY identity.permissionsEmpty "You have not granted this site any special permissions.">
<!ENTITY identity.permissionsReloadHint "You may need to reload the page for changes to apply."> <!ENTITY identity.permissionsReloadHint "You may need to reload the page for changes to apply.">
<!ENTITY identity.permissionsPreferences.tooltip "Open Permissions Preferences"> <!ENTITY identity.permissionsPreferences.tooltip "Open Permissions Preferences">
<!ENTITY identity.contentBlockingPreferences.tooltip "Open Content Blocking Preferences">
<!-- Name for the tabs toolbar as spoken by screen readers. <!-- Name for the tabs toolbar as spoken by screen readers.
The word "toolbar" is appended automatically and should not be contained below! --> The word "toolbar" is appended automatically and should not be contained below! -->

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

@ -19,8 +19,8 @@ inline HTMLBodyElement* Document::GetBodyElement() {
} }
template <typename T> template <typename T>
size_t Document::FindDocStyleSheetInsertionPoint( size_t Document::FindDocStyleSheetInsertionPoint(const nsTArray<T>& aDocSheets,
const nsTArray<T>& aDocSheets, const StyleSheet& aSheet) { const StyleSheet& aSheet) {
nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance(); nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance();
// lowest index first // lowest index first

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

@ -31,7 +31,7 @@ namespace mozilla {
namespace dom { namespace dom {
class Document; class Document;
class Element; class Element;
} } // namespace dom
/** /**
* Right now our identifier map entries contain information for 'name' * Right now our identifier map entries contain information for 'name'

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

@ -175,8 +175,8 @@ class RemoteObjectProxy : public RemoteObjectProxyBase {
using RemoteObjectProxyBase::RemoteObjectProxyBase; using RemoteObjectProxyBase::RemoteObjectProxyBase;
private: private:
bool DefinePropertiesAndFunctions( bool DefinePropertiesAndFunctions(JSContext* aCx,
JSContext* aCx, JS::Handle<JSObject*> aHolder) const final { JS::Handle<JSObject*> aHolder) const final {
return JS_DefineProperties(aCx, aHolder, P) && return JS_DefineProperties(aCx, aHolder, P) &&
JS_DefineFunctions(aCx, aHolder, F); JS_DefineFunctions(aCx, aHolder, F);
} }

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

@ -750,7 +750,8 @@ class HTMLInputElement final : public nsGenericHTMLFormElementWithState,
/* /*
* This locates the inner datetimebox UA Widget element and only the * This locates the inner datetimebox UA Widget element and only the
* UA Widget * UA Widget
* element. This should fold into GetDateTimeBoxElement() when the XBL binding is removed. * element. This should fold into GetDateTimeBoxElement() when the XBL binding
* is removed.
*/ */
Element* GetDateTimeBoxElementInUAWidget(); Element* GetDateTimeBoxElementInUAWidget();

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

@ -33,6 +33,7 @@
#include "mozilla/SnappyUncompressInputStream.h" #include "mozilla/SnappyUncompressInputStream.h"
#include "mozilla/StaticPtr.h" #include "mozilla/StaticPtr.h"
#include "mozilla/storage.h" #include "mozilla/storage.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Unused.h" #include "mozilla/Unused.h"
#include "mozilla/UniquePtrExtensions.h" #include "mozilla/UniquePtrExtensions.h"
#include "mozilla/dom/ContentParent.h" #include "mozilla/dom/ContentParent.h"
@ -8329,6 +8330,17 @@ nsresult DeserializeStructuredCloneFile(FileManager* aFileManager,
RefPtr<FileInfo> fileInfo = aFileManager->GetFileInfo(id); RefPtr<FileInfo> fileInfo = aFileManager->GetFileInfo(id);
MOZ_ASSERT(fileInfo); MOZ_ASSERT(fileInfo);
// XXX In bug 1432133, for some reasons FileInfo object cannot be got. This
// is just a short-term fix, and we are working on finding the real cause
// in bug 1519859.
if (!fileInfo) {
IDB_WARNING(
"Corrupt structured clone data detected in IndexedDB. Failing the "
"database request. Bug 1519859 will address this problem.");
Telemetry::ScalarAdd(Telemetry::ScalarID::IDB_FAILURE_FILEINFO_ERROR, 1);
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
aFile->mFileInfo.swap(fileInfo); aFile->mFileInfo.swap(fileInfo);
aFile->mType = type; aFile->mType = type;

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

@ -54,8 +54,8 @@ NS_IMPL_ISUPPORTS(MemoryReportRequestClient, nsIRunnable)
const ReportCallback& aReportCallback, const ReportCallback& aReportCallback,
const FinishCallback& aFinishCallback) { const FinishCallback& aFinishCallback) {
RefPtr<MemoryReportRequestClient> request = new MemoryReportRequestClient( RefPtr<MemoryReportRequestClient> request = new MemoryReportRequestClient(
aGeneration, aAnonymize, aDMDFile, aProcessString, aGeneration, aAnonymize, aDMDFile, aProcessString, aReportCallback,
aReportCallback, aFinishCallback); aFinishCallback);
DebugOnly<nsresult> rv; DebugOnly<nsresult> rv;
if (aMinimizeMemoryUsage) { if (aMinimizeMemoryUsage) {
@ -127,8 +127,7 @@ class FinishReportingCallback final : public nsIFinishReportingCallback {
explicit FinishReportingCallback(uint32_t aGeneration, explicit FinishReportingCallback(uint32_t aGeneration,
const FinishCallback& aFinishCallback) const FinishCallback& aFinishCallback)
: mGeneration(aGeneration), : mGeneration(aGeneration), mFinishCallback(aFinishCallback) {}
mFinishCallback(aFinishCallback) {}
NS_IMETHOD Callback(nsISupports* aUnused) override { NS_IMETHOD Callback(nsISupports* aUnused) override {
return mFinishCallback(mGeneration) ? NS_OK : NS_ERROR_FAILURE; return mFinishCallback(mGeneration) ? NS_OK : NS_ERROR_FAILURE;

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

@ -4180,7 +4180,8 @@ SourceListener::InitializeAsync() {
LOG("started all sources"); LOG("started all sources");
aHolder.Resolve(true, __func__); aHolder.Resolve(true, __func__);
}) })
->Then(GetMainThreadSerialEventTarget(), __func__, ->Then(
GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr<SourceListener>(this), this]() { [self = RefPtr<SourceListener>(this), this]() {
if (mStopped) { if (mStopped) {
// We were shut down during the async init // We were shut down during the async init
@ -4200,8 +4201,7 @@ SourceListener::InitializeAsync() {
state->mTrackEnabled = true; state->mTrackEnabled = true;
state->mTrackEnabledTime = TimeStamp::Now(); state->mTrackEnabledTime = TimeStamp::Now();
if (state == mVideoDeviceState.get() && if (state == mVideoDeviceState.get() && !mStream->IsDestroyed()) {
!mStream->IsDestroyed()) {
mStream->SetPullingEnabled(kVideoTrack, true); mStream->SetPullingEnabled(kVideoTrack, true);
} }
} }
@ -4210,8 +4210,8 @@ SourceListener::InitializeAsync() {
[self = RefPtr<SourceListener>(this), [self = RefPtr<SourceListener>(this),
this](RefPtr<MediaMgrError>&& aResult) { this](RefPtr<MediaMgrError>&& aResult) {
if (mStopped) { if (mStopped) {
return SourceListenerPromise::CreateAndReject( return SourceListenerPromise::CreateAndReject(std::move(aResult),
std::move(aResult), __func__); __func__);
} }
for (DeviceState* state : for (DeviceState* state :

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

@ -94,7 +94,7 @@ TEST(MP4Metadata, EmptyStream) {
TEST(MoofParser, EmptyStream) { TEST(MoofParser, EmptyStream) {
RefPtr<ByteStream> stream = new TestStream(nullptr, 0); RefPtr<ByteStream> stream = new TestStream(nullptr, 0);
MoofParser parser(stream, 0, false); MoofParser parser(stream, 0, false, true);
EXPECT_EQ(0u, parser.mOffset); EXPECT_EQ(0u, parser.mOffset);
EXPECT_TRUE(parser.ReachedEnd()); EXPECT_TRUE(parser.ReachedEnd());
@ -404,7 +404,7 @@ TEST(MoofParser, test_case_mp4) {
RefPtr<ByteStream> stream = RefPtr<ByteStream> stream =
new TestStream(buffer.Elements(), buffer.Length()); new TestStream(buffer.Elements(), buffer.Length());
MoofParser parser(stream, 0, false); MoofParser parser(stream, 0, false, true);
EXPECT_EQ(0u, parser.mOffset) << tests[test].mFilename; EXPECT_EQ(0u, parser.mOffset) << tests[test].mFilename;
EXPECT_FALSE(parser.ReachedEnd()) << tests[test].mFilename; EXPECT_FALSE(parser.ReachedEnd()) << tests[test].mFilename;
EXPECT_TRUE(parser.mInitRange.IsEmpty()) << tests[test].mFilename; EXPECT_TRUE(parser.mInitRange.IsEmpty()) << tests[test].mFilename;

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

@ -526,7 +526,8 @@ class MP4ContainerParser : public ContainerParser,
// consumers of ParseStartAndEndTimestamps to add their timestamp offset // consumers of ParseStartAndEndTimestamps to add their timestamp offset
// manually. This allows the ContainerParser to be shared across different // manually. This allows the ContainerParser to be shared across different
// timestampOffsets. // timestampOffsets.
mParser = new MoofParser(mStream, 0, /* aIsAudio = */ false); mParser = new MoofParser(mStream, 0, /* aIsAudio = */ false,
/* aIsMultitrackParser */ true);
DDLINKCHILD("parser", mParser.get()); DDLINKCHILD("parser", mParser.get());
mInitData = new MediaByteBuffer(); mInitData = new MediaByteBuffer();
mCompleteInitSegmentRange = MediaByteRange(); mCompleteInitSegmentRange = MediaByteRange();

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

@ -460,7 +460,7 @@ MP4Metadata::ResultAndIndice MP4Metadata::GetTrackIndice(
/*static*/ MP4Metadata::ResultAndByteBuffer MP4Metadata::Metadata( /*static*/ MP4Metadata::ResultAndByteBuffer MP4Metadata::Metadata(
ByteStream* aSource) { ByteStream* aSource) {
auto parser = mozilla::MakeUnique<MoofParser>(aSource, 0, false); auto parser = mozilla::MakeUnique<MoofParser>(aSource, 0, false, true);
RefPtr<mozilla::MediaByteBuffer> buffer = parser->Metadata(); RefPtr<mozilla::MediaByteBuffer> buffer = parser->Metadata();
if (!buffer) { if (!buffer) {
return {MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR, return {MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR,

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

@ -55,7 +55,7 @@ bool MoofParser::RebuildFragmentedIndex(BoxContext& aContext) {
ParseMoov(box); ParseMoov(box);
} else if (box.IsType("moof")) { } else if (box.IsType("moof")) {
Moof moof(box, mTrex, mMvhd, mMdhd, mEdts, mSinf, &mLastDecodeTime, Moof moof(box, mTrex, mMvhd, mMdhd, mEdts, mSinf, &mLastDecodeTime,
mIsAudio); mIsAudio, mIsMultitrackParser);
if (!moof.IsValid() && !box.Next().IsAvailable()) { if (!moof.IsValid() && !box.Next().IsAvailable()) {
// Moof isn't valid abort search for now. // Moof isn't valid abort search for now.
@ -227,11 +227,11 @@ void MoofParser::ParseTrak(Box& aBox) {
if (box.IsType("tkhd")) { if (box.IsType("tkhd")) {
tkhd = Tkhd(box); tkhd = Tkhd(box);
} else if (box.IsType("mdia")) { } else if (box.IsType("mdia")) {
if (!mTrex.mTrackId || tkhd.mTrackId == mTrex.mTrackId) { if (mIsMultitrackParser || tkhd.mTrackId == mTrex.mTrackId) {
ParseMdia(box, tkhd); ParseMdia(box, tkhd);
} }
} else if (box.IsType("edts") && } else if (box.IsType("edts") &&
(!mTrex.mTrackId || tkhd.mTrackId == mTrex.mTrackId)) { (mIsMultitrackParser || tkhd.mTrackId == mTrex.mTrackId)) {
mEdts = Edts(box); mEdts = Edts(box);
} }
} }
@ -251,12 +251,8 @@ void MoofParser::ParseMvex(Box& aBox) {
for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) { for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
if (box.IsType("trex")) { if (box.IsType("trex")) {
Trex trex = Trex(box); Trex trex = Trex(box);
if (!mTrex.mTrackId || trex.mTrackId == mTrex.mTrackId) { if (mIsMultitrackParser || trex.mTrackId == mTrex.mTrackId) {
auto trackId = mTrex.mTrackId;
mTrex = trex; mTrex = trex;
// Keep the original trackId, as should it be 0 we want to continue
// parsing all tracks.
mTrex.mTrackId = trackId;
} }
} }
} }
@ -299,8 +295,8 @@ void MoofParser::ParseStbl(Box& aBox) {
} }
void MoofParser::ParseStsd(Box& aBox) { void MoofParser::ParseStsd(Box& aBox) {
if (mTrex.mTrackId == 0) { if (mIsMultitrackParser) {
// If mTrex.mTrackId is 0, then the parser is being used to read multiple // If mIsMultitrackParser, then the parser is being used to read multiple
// tracks metadata, and it is not a sane operation to try and map multiple // tracks metadata, and it is not a sane operation to try and map multiple
// sample description boxes, from different tracks, onto the parser, which // sample description boxes, from different tracks, onto the parser, which
// is modeled around storing metadata for a single track. // is modeled around storing metadata for a single track.
@ -353,12 +349,14 @@ class CtsComparator {
}; };
Moof::Moof(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, Moof::Moof(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts,
Sinf& aSinf, uint64_t* aDecodeTime, bool aIsAudio) Sinf& aSinf, uint64_t* aDecodeTime, bool aIsAudio,
bool aIsMultitrackParser)
: mRange(aBox.Range()), mTfhd(aTrex), mMaxRoundingError(35000) { : mRange(aBox.Range()), mTfhd(aTrex), mMaxRoundingError(35000) {
nsTArray<Box> psshBoxes; nsTArray<Box> psshBoxes;
for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) { for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
if (box.IsType("traf")) { if (box.IsType("traf")) {
ParseTraf(box, aTrex, aMvhd, aMdhd, aEdts, aSinf, aDecodeTime, aIsAudio); ParseTraf(box, aTrex, aMvhd, aMdhd, aEdts, aSinf, aDecodeTime, aIsAudio,
aIsMultitrackParser);
} }
if (box.IsType("pssh")) { if (box.IsType("pssh")) {
psshBoxes.AppendElement(box); psshBoxes.AppendElement(box);
@ -506,14 +504,14 @@ bool Moof::ProcessCencAuxInfo(AtomType aScheme) {
void Moof::ParseTraf(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, void Moof::ParseTraf(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd,
Edts& aEdts, Sinf& aSinf, uint64_t* aDecodeTime, Edts& aEdts, Sinf& aSinf, uint64_t* aDecodeTime,
bool aIsAudio) { bool aIsAudio, bool aIsMultitrackParser) {
MOZ_ASSERT(aDecodeTime); MOZ_ASSERT(aDecodeTime);
Tfdt tfdt; Tfdt tfdt;
for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) { for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
if (box.IsType("tfhd")) { if (box.IsType("tfhd")) {
mTfhd = Tfhd(box, aTrex); mTfhd = Tfhd(box, aTrex);
} else if (!aTrex.mTrackId || mTfhd.mTrackId == aTrex.mTrackId) { } else if (aIsMultitrackParser || mTfhd.mTrackId == aTrex.mTrackId) {
if (box.IsType("tfdt")) { if (box.IsType("tfdt")) {
tfdt = Tfdt(box); tfdt = Tfdt(box);
} else if (box.IsType("sgpd")) { } else if (box.IsType("sgpd")) {
@ -551,7 +549,7 @@ void Moof::ParseTraf(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd,
} }
} }
} }
if (aTrex.mTrackId && mTfhd.mTrackId != aTrex.mTrackId) { if (!aIsMultitrackParser && mTfhd.mTrackId != aTrex.mTrackId) {
return; return;
} }
// Now search for TRUN boxes. // Now search for TRUN boxes.

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

@ -227,7 +227,8 @@ struct SampleDescriptionEntry {
class Moof final : public Atom { class Moof final : public Atom {
public: public:
Moof(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, Moof(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts,
Sinf& aSinf, uint64_t* aDecoderTime, bool aIsAudio); Sinf& aSinf, uint64_t* aDecoderTime, bool aIsAudio,
bool aIsMultitrackParser);
bool GetAuxInfo(AtomType aType, FallibleTArray<MediaByteRange>* aByteRanges); bool GetAuxInfo(AtomType aType, FallibleTArray<MediaByteRange>* aByteRanges);
void FixRounding(const Moof& aMoof); void FixRounding(const Moof& aMoof);
@ -248,7 +249,8 @@ class Moof final : public Atom {
private: private:
// aDecodeTime is updated to the end of the parsed TRAF on return. // aDecodeTime is updated to the end of the parsed TRAF on return.
void ParseTraf(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts, void ParseTraf(Box& aBox, Trex& aTrex, Mvhd& aMvhd, Mdhd& aMdhd, Edts& aEdts,
Sinf& aSinf, uint64_t* aDecodeTime, bool aIsAudio); Sinf& aSinf, uint64_t* aDecodeTime, bool aIsAudio,
bool aIsMultitrackParser);
// aDecodeTime is updated to the end of the parsed TRUN on return. // aDecodeTime is updated to the end of the parsed TRUN on return.
Result<Ok, nsresult> ParseTrun(Box& aBox, Mvhd& aMvhd, Mdhd& aMdhd, Result<Ok, nsresult> ParseTrun(Box& aBox, Mvhd& aMvhd, Mdhd& aMdhd,
Edts& aEdts, uint64_t* aDecodeTime, Edts& aEdts, uint64_t* aDecodeTime,
@ -267,14 +269,18 @@ DDLoggedTypeDeclName(MoofParser);
class MoofParser : public DecoderDoctorLifeLogger<MoofParser> { class MoofParser : public DecoderDoctorLifeLogger<MoofParser> {
public: public:
MoofParser(ByteStream* aSource, uint32_t aTrackId, bool aIsAudio) MoofParser(ByteStream* aSource, uint32_t aTrackId, bool aIsAudio,
bool aIsMultitrackParser = false)
: mSource(aSource), : mSource(aSource),
mOffset(0), mOffset(0),
mTrex(aTrackId), mTrex(aTrackId),
mIsAudio(aIsAudio), mIsAudio(aIsAudio),
mLastDecodeTime(0) { mLastDecodeTime(0),
// Setting the mTrex.mTrackId to 0 is a nasty work around for calculating mIsMultitrackParser(aIsMultitrackParser) {
// the composition range for MSE. We need an array of tracks. // Setting mIsMultitrackParser is a nasty work around for calculating
// the composition range for MSE that causes the parser to parse multiple
// tracks. Ideally we'd store an array of tracks with different metadata
// for each.
DDLINKCHILD("source", aSource); DDLINKCHILD("source", aSource);
} }
bool RebuildFragmentedIndex(const mozilla::MediaByteRangeSet& aByteRanges); bool RebuildFragmentedIndex(const mozilla::MediaByteRangeSet& aByteRanges);
@ -326,6 +332,7 @@ class MoofParser : public DecoderDoctorLifeLogger<MoofParser> {
nsTArray<MediaByteRange> mMediaRanges; nsTArray<MediaByteRange> mMediaRanges;
bool mIsAudio; bool mIsAudio;
uint64_t mLastDecodeTime; uint64_t mLastDecodeTime;
bool mIsMultitrackParser;
}; };
} // namespace mozilla } // namespace mozilla

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

@ -605,8 +605,7 @@ nsresult MediaEngineWebRTCMicrophoneSource::Stop(
} }
RefPtr<MediaEngineWebRTCMicrophoneSource> that = this; RefPtr<MediaEngineWebRTCMicrophoneSource> that = this;
NS_DispatchToMainThread( NS_DispatchToMainThread(media::NewRunnableFrom([that, stream = mStream]() {
media::NewRunnableFrom([that, stream = mStream]() {
if (stream->IsDestroyed()) { if (stream->IsDestroyed()) {
return NS_OK; return NS_OK;
} }

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

@ -152,7 +152,8 @@ already_AddRefed<WakeLock> PowerManagerService::NewWakeLockOnBehalfOfProcess(
NS_DEFINE_NAMED_CID(NS_POWERMANAGERSERVICE_CID); NS_DEFINE_NAMED_CID(NS_POWERMANAGERSERVICE_CID);
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIPowerManagerService, NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(
nsIPowerManagerService,
mozilla::dom::power::PowerManagerService::GetInstance) mozilla::dom::power::PowerManagerService::GetInstance)
static const mozilla::Module::CIDEntry kPowerManagerCIDs[] = { static const mozilla::Module::CIDEntry kPowerManagerCIDs[] = {
@ -171,7 +172,8 @@ static const mozilla::Module::ContractIDEntry kPowerManagerContracts[] = {
// We mark the power module as being available in the GPU process because the // We mark the power module as being available in the GPU process because the
// appshell depends on the power manager service. // appshell depends on the power manager service.
static const mozilla::Module kPowerManagerModule = {mozilla::Module::kVersion, static const mozilla::Module kPowerManagerModule = {
mozilla::Module::kVersion,
kPowerManagerCIDs, kPowerManagerCIDs,
kPowerManagerContracts, kPowerManagerContracts,
nullptr, nullptr,

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

@ -40,9 +40,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(LoadedScript)
LoadedScript::LoadedScript(ScriptKind aKind, ScriptFetchOptions* aFetchOptions, LoadedScript::LoadedScript(ScriptKind aKind, ScriptFetchOptions* aFetchOptions,
nsIURI* aBaseURL) nsIURI* aBaseURL)
: mKind(aKind), : mKind(aKind), mFetchOptions(aFetchOptions), mBaseURL(aBaseURL) {
mFetchOptions(aFetchOptions),
mBaseURL(aBaseURL) {
MOZ_ASSERT(mFetchOptions); MOZ_ASSERT(mFetchOptions);
MOZ_ASSERT(mBaseURL); MOZ_ASSERT(mBaseURL);
} }

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

@ -2301,9 +2301,8 @@ nsresult ScriptLoader::FillCompileOptionsForRequest(
bool isScriptElement = bool isScriptElement =
!aRequest->IsModuleRequest() || aRequest->AsModuleRequest()->IsTopLevel(); !aRequest->IsModuleRequest() || aRequest->AsModuleRequest()->IsTopLevel();
aOptions->setIntroductionInfoToCaller(jsapi.cx(), aOptions->setIntroductionInfoToCaller(
isScriptElement ? "scriptElement" jsapi.cx(), isScriptElement ? "scriptElement" : "importedModule");
: "importedModule");
aOptions->setFileAndLine(aRequest->mURL.get(), aRequest->mLineNo); aOptions->setFileAndLine(aRequest->mURL.get(), aRequest->mLineNo);
aOptions->setIsRunOnce(true); aOptions->setIsRunOnce(true);
aOptions->setNoScriptRval(true); aOptions->setNoScriptRval(true);

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

@ -191,8 +191,7 @@ class SVGContentUtils {
/* /*
* Report a localized error message to the error console. * Report a localized error message to the error console.
*/ */
static nsresult ReportToConsole(dom::Document* doc, static nsresult ReportToConsole(dom::Document* doc, const char* aWarning,
const char* aWarning,
const char16_t** aParams, const char16_t** aParams,
uint32_t aParamsLength); uint32_t aParamsLength);

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

@ -46,7 +46,8 @@ bool SVGTests::HasExtension(const nsAString& aExtension) const {
if (aExtension.EqualsLiteral(str)) return true; if (aExtension.EqualsLiteral(str)) return true;
SVG_SUPPORTED_EXTENSION("http://www.w3.org/1999/xhtml") SVG_SUPPORTED_EXTENSION("http://www.w3.org/1999/xhtml")
nsNameSpaceManager* nameSpaceManager = nsNameSpaceManager::GetInstance(); nsNameSpaceManager* nameSpaceManager = nsNameSpaceManager::GetInstance();
if (AsSVGElement()->IsInChromeDocument() || !nameSpaceManager->mMathMLDisabled) { if (AsSVGElement()->IsInChromeDocument() ||
!nameSpaceManager->mMathMLDisabled) {
SVG_SUPPORTED_EXTENSION("http://www.w3.org/1998/Math/MathML") SVG_SUPPORTED_EXTENSION("http://www.w3.org/1998/Math/MathML")
} }
#undef SVG_SUPPORTED_EXTENSION #undef SVG_SUPPORTED_EXTENSION

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

@ -460,8 +460,7 @@ RefPtr<PerformanceInfoPromise> WorkerDebugger::ReportPerformanceInfo() {
RefPtr<nsIURI> scriptURI = mWorkerPrivate->GetResolvedScriptURI(); RefPtr<nsIURI> scriptURI = mWorkerPrivate->GetResolvedScriptURI();
if (NS_WARN_IF(!scriptURI)) { if (NS_WARN_IF(!scriptURI)) {
// This can happen at shutdown, let's stop here. // This can happen at shutdown, let's stop here.
return PerformanceInfoPromise::CreateAndReject(NS_ERROR_FAILURE, return PerformanceInfoPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
__func__);
} }
nsCString url = scriptURI->GetSpecOrDefault(); nsCString url = scriptURI->GetSpecOrDefault();

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

@ -35,9 +35,7 @@ DOMIterator::DOMIterator(nsINode& aNode MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
MOZ_ASSERT(NS_SUCCEEDED(rv)); MOZ_ASSERT(NS_SUCCEEDED(rv));
} }
nsresult DOMIterator::Init(nsRange& aRange) { nsresult DOMIterator::Init(nsRange& aRange) { return mIter->Init(&aRange); }
return mIter->Init(&aRange);
}
DOMIterator::DOMIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL) DOMIterator::DOMIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
: mIter(&mPostOrderIter) { : mIter(&mPostOrderIter) {

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

@ -29,7 +29,7 @@ class TextEditor;
namespace dom { namespace dom {
class Document; class Document;
class Element; class Element;
}; }; // namespace dom
/** /**
* The TextServicesDocument presents the document in as a bunch of flattened * The TextServicesDocument presents the document in as a bunch of flattened

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

@ -310,8 +310,7 @@ GLContextEGL::GLContextEGL(CreateContextFlags flags, const SurfaceCaps& caps,
#endif #endif
} }
void void GLContextEGL::OnMarkDestroyed() {
GLContextEGL::OnMarkDestroyed() {
if (mSurfaceOverride != EGL_NO_SURFACE) { if (mSurfaceOverride != EGL_NO_SURFACE) {
SetEGLSurfaceOverride(EGL_NO_SURFACE); SetEGLSurfaceOverride(EGL_NO_SURFACE);
} }

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

@ -17,7 +17,8 @@ void FrameMetrics::RecalculateLayoutViewportOffset() {
if (!mIsRootContent) { if (!mIsRootContent) {
return; return;
} }
KeepLayoutViewportEnclosingVisualViewport(GetVisualViewport(), mLayoutViewport); KeepLayoutViewportEnclosingVisualViewport(GetVisualViewport(),
mLayoutViewport);
} }
/* static */ void FrameMetrics::KeepLayoutViewportEnclosingVisualViewport( /* static */ void FrameMetrics::KeepLayoutViewportEnclosingVisualViewport(

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

@ -205,7 +205,8 @@ static ScreenMargin ScrollFrame(nsIContent* aContent,
aRequest, actualScrollOffset); aRequest, actualScrollOffset);
} }
} else if (aRequest.IsRootContent() && } else if (aRequest.IsRootContent() &&
aRequest.GetScrollOffset() != aRequest.GetLayoutViewport().TopLeft()) { aRequest.GetScrollOffset() !=
aRequest.GetLayoutViewport().TopLeft()) {
// APZ uses the visual viewport's offset to calculate where to place the // APZ uses the visual viewport's offset to calculate where to place the
// display port, so the display port is misplaced when a pinch zoom occurs. // display port, so the display port is misplaced when a pinch zoom occurs.
// //

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

@ -170,7 +170,8 @@ class CrossProcessCompositorBridgeParent final
void UpdatePaintTime(LayerTransactionParent* aLayerTree, void UpdatePaintTime(LayerTransactionParent* aLayerTree,
const TimeDuration& aPaintTime) override; const TimeDuration& aPaintTime) override;
void RegisterPayload(LayerTransactionParent* aLayerTree, void RegisterPayload(
LayerTransactionParent* aLayerTree,
const InfallibleTArray<CompositionPayload>& aPayload) override; const InfallibleTArray<CompositionPayload>& aPayload) override;
PWebRenderBridgeParent* AllocPWebRenderBridgeParent( PWebRenderBridgeParent* AllocPWebRenderBridgeParent(

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

@ -719,8 +719,7 @@ struct ParamTraits<mozilla::layers::CompositionPayloadType>
mozilla::layers::kHighestCompositionPayloadType> {}; mozilla::layers::kHighestCompositionPayloadType> {};
template <> template <>
struct ParamTraits<mozilla::layers::CompositionPayload> struct ParamTraits<mozilla::layers::CompositionPayload> {
{
typedef mozilla::layers::CompositionPayload paramType; typedef mozilla::layers::CompositionPayload paramType;
static void Write(Message* aMsg, const paramType& aParam) { static void Write(Message* aMsg, const paramType& aParam) {
@ -728,7 +727,8 @@ struct ParamTraits<mozilla::layers::CompositionPayload>
WriteParam(aMsg, aParam.mTimeStamp); WriteParam(aMsg, aParam.mTimeStamp);
} }
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) { static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
return ReadParam(aMsg, aIter, &aResult->mType) && return ReadParam(aMsg, aIter, &aResult->mType) &&
ReadParam(aMsg, aIter, &aResult->mTimeStamp); ReadParam(aMsg, aIter, &aResult->mTimeStamp);
} }

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

@ -20,7 +20,9 @@
//#define CLIP_LOG(...) printf_stderr("CLIP: " __VA_ARGS__) //#define CLIP_LOG(...) printf_stderr("CLIP: " __VA_ARGS__)
// clang-format off
//#define CLIP_LOG(...) if (XRE_IsContentProcess()) printf_stderr("CLIP: " __VA_ARGS__) //#define CLIP_LOG(...) if (XRE_IsContentProcess()) printf_stderr("CLIP: " __VA_ARGS__)
// clang-format on
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {

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

@ -11,71 +11,50 @@
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
RenderRootStateManager::RenderRootStateManager(WebRenderLayerManager* aLayerManager) RenderRootStateManager::RenderRootStateManager(
: mLayerManager(aLayerManager) WebRenderLayerManager* aLayerManager)
, mDestroyed(false) : mLayerManager(aLayerManager), mDestroyed(false) {}
{
}
RenderRootStateManager::~RenderRootStateManager() RenderRootStateManager::~RenderRootStateManager() {}
{}
// RenderRootStateManager shares its ref count with the WebRenderLayerManager that // RenderRootStateManager shares its ref count with the WebRenderLayerManager
// created it. You can think of the two classes as being one unit, except there // that created it. You can think of the two classes as being one unit, except
// are multiple RenderRootStateManagers per WebRenderLayerManager. Since we need // there are multiple RenderRootStateManagers per WebRenderLayerManager. Since
// to reference the WebRenderLayerManager and it needs to reference us, this // we need to reference the WebRenderLayerManager and it needs to reference us,
// avoids us needing to involve the cycle collector. // this avoids us needing to involve the cycle collector.
void void RenderRootStateManager::AddRef() { mLayerManager->AddRef(); }
RenderRootStateManager::AddRef()
{
mLayerManager->AddRef();
}
void void RenderRootStateManager::Release() { mLayerManager->Release(); }
RenderRootStateManager::Release()
{
mLayerManager->Release();
}
WebRenderBridgeChild* RenderRootStateManager::WrBridge() const {
WebRenderBridgeChild*
RenderRootStateManager::WrBridge() const
{
return mLayerManager->WrBridge(); return mLayerManager->WrBridge();
} }
WebRenderCommandBuilder& WebRenderCommandBuilder& RenderRootStateManager::CommandBuilder() {
RenderRootStateManager::CommandBuilder()
{
return mLayerManager->CommandBuilder(); return mLayerManager->CommandBuilder();
} }
RenderRootStateManager::WebRenderUserDataRefTable* RenderRootStateManager::WebRenderUserDataRefTable*
RenderRootStateManager::GetWebRenderUserDataTable() RenderRootStateManager::GetWebRenderUserDataTable() {
{
return mLayerManager->GetWebRenderUserDataTable(); return mLayerManager->GetWebRenderUserDataTable();
} }
wr::IpcResourceUpdateQueue& wr::IpcResourceUpdateQueue& RenderRootStateManager::AsyncResourceUpdates() {
RenderRootStateManager::AsyncResourceUpdates()
{
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
if (!mAsyncResourceUpdates) { if (!mAsyncResourceUpdates) {
mAsyncResourceUpdates.emplace(WrBridge()); mAsyncResourceUpdates.emplace(WrBridge());
RefPtr<Runnable> task = NewRunnableMethod( RefPtr<Runnable> task = NewRunnableMethod(
"RenderRootStateManager::FlushAsyncResourceUpdates", "RenderRootStateManager::FlushAsyncResourceUpdates", this,
this, &RenderRootStateManager::FlushAsyncResourceUpdates); &RenderRootStateManager::FlushAsyncResourceUpdates);
NS_DispatchToMainThread(task.forget()); NS_DispatchToMainThread(task.forget());
} }
return mAsyncResourceUpdates.ref(); return mAsyncResourceUpdates.ref();
} }
void void RenderRootStateManager::Destroy() {
RenderRootStateManager::Destroy()
{
ClearAsyncAnimations(); ClearAsyncAnimations();
if (WrBridge()) { if (WrBridge()) {
@ -90,9 +69,7 @@ RenderRootStateManager::Destroy()
mDestroyed = true; mDestroyed = true;
} }
void void RenderRootStateManager::FlushAsyncResourceUpdates() {
RenderRootStateManager::FlushAsyncResourceUpdates()
{
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
if (!mAsyncResourceUpdates) { if (!mAsyncResourceUpdates) {
@ -106,21 +83,16 @@ RenderRootStateManager::FlushAsyncResourceUpdates()
mAsyncResourceUpdates.reset(); mAsyncResourceUpdates.reset();
} }
void void RenderRootStateManager::AddImageKeyForDiscard(wr::ImageKey key) {
RenderRootStateManager::AddImageKeyForDiscard(wr::ImageKey key)
{
mImageKeysToDelete.AppendElement(key); mImageKeysToDelete.AppendElement(key);
} }
void void RenderRootStateManager::AddBlobImageKeyForDiscard(wr::BlobImageKey key) {
RenderRootStateManager::AddBlobImageKeyForDiscard(wr::BlobImageKey key)
{
mBlobImageKeysToDelete.AppendElement(key); mBlobImageKeysToDelete.AppendElement(key);
} }
void void RenderRootStateManager::DiscardImagesInTransaction(
RenderRootStateManager::DiscardImagesInTransaction(wr::IpcResourceUpdateQueue& aResources) wr::IpcResourceUpdateQueue& aResources) {
{
for (const auto& key : mImageKeysToDelete) { for (const auto& key : mImageKeysToDelete) {
aResources.DeleteImage(key); aResources.DeleteImage(key);
} }
@ -131,9 +103,7 @@ RenderRootStateManager::DiscardImagesInTransaction(wr::IpcResourceUpdateQueue& a
mBlobImageKeysToDelete.Clear(); mBlobImageKeysToDelete.Clear();
} }
void void RenderRootStateManager::DiscardLocalImages() {
RenderRootStateManager::DiscardLocalImages()
{
// Removes images but doesn't tell the parent side about them // Removes images but doesn't tell the parent side about them
// This is useful in empty / failed transactions where we created // This is useful in empty / failed transactions where we created
// image keys but didn't tell the parent about them yet. // image keys but didn't tell the parent about them yet.
@ -141,16 +111,12 @@ RenderRootStateManager::DiscardLocalImages()
mBlobImageKeysToDelete.Clear(); mBlobImageKeysToDelete.Clear();
} }
void void RenderRootStateManager::ClearCachedResources() {
RenderRootStateManager::ClearCachedResources()
{
mActiveCompositorAnimationIds.clear(); mActiveCompositorAnimationIds.clear();
mDiscardedCompositorAnimationsIds.Clear(); mDiscardedCompositorAnimationsIds.Clear();
} }
void void RenderRootStateManager::AddActiveCompositorAnimationId(uint64_t aId) {
RenderRootStateManager::AddActiveCompositorAnimationId(uint64_t aId)
{
// In layers-free mode we track the active compositor animation ids on the // In layers-free mode we track the active compositor animation ids on the
// client side so that we don't try to discard the same animation id multiple // client side so that we don't try to discard the same animation id multiple
// times. We could just ignore the multiple-discard on the parent side, but // times. We could just ignore the multiple-discard on the parent side, but
@ -158,53 +124,42 @@ RenderRootStateManager::AddActiveCompositorAnimationId(uint64_t aId)
mActiveCompositorAnimationIds.insert(aId); mActiveCompositorAnimationIds.insert(aId);
} }
void void RenderRootStateManager::AddCompositorAnimationsIdForDiscard(uint64_t aId) {
RenderRootStateManager::AddCompositorAnimationsIdForDiscard(uint64_t aId)
{
if (mActiveCompositorAnimationIds.erase(aId)) { if (mActiveCompositorAnimationIds.erase(aId)) {
// For layers-free ensure we don't try to discard an animation id that wasn't // For layers-free ensure we don't try to discard an animation id that
// active. We also remove it from mActiveCompositorAnimationIds so we don't // wasn't active. We also remove it from mActiveCompositorAnimationIds so we
// discard it again unless it gets re-activated. // don't discard it again unless it gets re-activated.
mDiscardedCompositorAnimationsIds.AppendElement(aId); mDiscardedCompositorAnimationsIds.AppendElement(aId);
} }
} }
void void RenderRootStateManager::DiscardCompositorAnimations() {
RenderRootStateManager::DiscardCompositorAnimations() if (WrBridge()->IPCOpen() && !mDiscardedCompositorAnimationsIds.IsEmpty()) {
{ WrBridge()->SendDeleteCompositorAnimations(
if (WrBridge()->IPCOpen() && mDiscardedCompositorAnimationsIds);
!mDiscardedCompositorAnimationsIds.IsEmpty()) {
WrBridge()->
SendDeleteCompositorAnimations(mDiscardedCompositorAnimationsIds);
} }
mDiscardedCompositorAnimationsIds.Clear(); mDiscardedCompositorAnimationsIds.Clear();
} }
void void RenderRootStateManager::RegisterAsyncAnimation(
RenderRootStateManager::RegisterAsyncAnimation(const wr::ImageKey& aKey, const wr::ImageKey& aKey, SharedSurfacesAnimation* aAnimation) {
SharedSurfacesAnimation* aAnimation)
{
mAsyncAnimations.insert(std::make_pair(wr::AsUint64(aKey), aAnimation)); mAsyncAnimations.insert(std::make_pair(wr::AsUint64(aKey), aAnimation));
} }
void void RenderRootStateManager::DeregisterAsyncAnimation(
RenderRootStateManager::DeregisterAsyncAnimation(const wr::ImageKey& aKey) const wr::ImageKey& aKey) {
{
mAsyncAnimations.erase(wr::AsUint64(aKey)); mAsyncAnimations.erase(wr::AsUint64(aKey));
} }
void void RenderRootStateManager::ClearAsyncAnimations() {
RenderRootStateManager::ClearAsyncAnimations()
{
for (const auto& i : mAsyncAnimations) { for (const auto& i : mAsyncAnimations) {
i.second->Invalidate(this); i.second->Invalidate(this);
} }
mAsyncAnimations.clear(); mAsyncAnimations.clear();
} }
void void RenderRootStateManager::WrReleasedImages(
RenderRootStateManager::WrReleasedImages(const nsTArray<wr::ExternalImageKeyPair>& aPairs) const nsTArray<wr::ExternalImageKeyPair>& aPairs) {
{
// A SharedSurfaceAnimation object's lifetime is tied to its owning // A SharedSurfaceAnimation object's lifetime is tied to its owning
// ImageContainer. When the ImageContainer is released, // ImageContainer. When the ImageContainer is released,
// SharedSurfaceAnimation::Destroy is called which should ensure it is removed // SharedSurfaceAnimation::Destroy is called which should ensure it is removed
@ -223,52 +178,39 @@ RenderRootStateManager::WrReleasedImages(const nsTArray<wr::ExternalImageKeyPair
} }
} }
void void RenderRootStateManager::AddWebRenderParentCommand(
RenderRootStateManager::AddWebRenderParentCommand(const WebRenderParentCommand& aCmd) const WebRenderParentCommand& aCmd) {
{
WrBridge()->AddWebRenderParentCommand(aCmd); WrBridge()->AddWebRenderParentCommand(aCmd);
} }
void void RenderRootStateManager::UpdateResources(
RenderRootStateManager::UpdateResources(wr::IpcResourceUpdateQueue& aResources) wr::IpcResourceUpdateQueue& aResources) {
{
WrBridge()->UpdateResources(aResources); WrBridge()->UpdateResources(aResources);
} }
void void RenderRootStateManager::AddPipelineIdForAsyncCompositable(
RenderRootStateManager::AddPipelineIdForAsyncCompositable(const wr::PipelineId& aPipelineId, const wr::PipelineId& aPipelineId, const CompositableHandle& aHandle) {
const CompositableHandle& aHandle)
{
WrBridge()->AddPipelineIdForAsyncCompositable(aPipelineId, aHandle); WrBridge()->AddPipelineIdForAsyncCompositable(aPipelineId, aHandle);
} }
void void RenderRootStateManager::AddPipelineIdForCompositable(
RenderRootStateManager::AddPipelineIdForCompositable(const wr::PipelineId& aPipelineId, const wr::PipelineId& aPipelineId, const CompositableHandle& aHandle) {
const CompositableHandle& aHandle)
{
WrBridge()->AddPipelineIdForCompositable(aPipelineId, aHandle); WrBridge()->AddPipelineIdForCompositable(aPipelineId, aHandle);
} }
void void RenderRootStateManager::RemovePipelineIdForCompositable(
RenderRootStateManager::RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId) const wr::PipelineId& aPipelineId) {
{
WrBridge()->RemovePipelineIdForCompositable(aPipelineId); WrBridge()->RemovePipelineIdForCompositable(aPipelineId);
} }
/// Release TextureClient that is bounded to ImageKey. /// Release TextureClient that is bounded to ImageKey.
/// It is used for recycling TextureClient. /// It is used for recycling TextureClient.
void void RenderRootStateManager::ReleaseTextureOfImage(const wr::ImageKey& aKey) {
RenderRootStateManager::ReleaseTextureOfImage(const wr::ImageKey& aKey)
{
WrBridge()->ReleaseTextureOfImage(aKey); WrBridge()->ReleaseTextureOfImage(aKey);
} }
wr::FontInstanceKey wr::FontInstanceKey RenderRootStateManager::GetFontKeyForScaledFont(
RenderRootStateManager::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont, gfx::ScaledFont* aScaledFont, wr::IpcResourceUpdateQueue* aResources) {
wr::IpcResourceUpdateQueue* aResources)
{
return WrBridge()->GetFontKeyForScaledFont(aScaledFont, aResources); return WrBridge()->GetFontKeyForScaledFont(aScaledFont, aResources);
} }
wr::FontKey wr::FontKey RenderRootStateManager::GetFontKeyForUnscaledFont(
RenderRootStateManager::GetFontKeyForUnscaledFont(gfx::UnscaledFont* aUnscaledFont, gfx::UnscaledFont* aUnscaledFont, wr::IpcResourceUpdateQueue* aResources) {
wr::IpcResourceUpdateQueue* aResources)
{
return WrBridge()->GetFontKeyForUnscaledFont(aUnscaledFont, aResources); return WrBridge()->GetFontKeyForUnscaledFont(aUnscaledFont, aResources);
} }

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

@ -16,9 +16,9 @@ namespace mozilla {
namespace layers { namespace layers {
class RenderRootStateManager class RenderRootStateManager {
{ typedef nsTHashtable<nsRefPtrHashKey<WebRenderUserData>>
typedef nsTHashtable<nsRefPtrHashKey<WebRenderUserData>> WebRenderUserDataRefTable; WebRenderUserDataRefTable;
public: public:
void AddRef(); void AddRef();
@ -32,10 +32,7 @@ public:
WebRenderBridgeChild* WrBridge() const; WebRenderBridgeChild* WrBridge() const;
WebRenderCommandBuilder& CommandBuilder(); WebRenderCommandBuilder& CommandBuilder();
WebRenderUserDataRefTable* GetWebRenderUserDataTable(); WebRenderUserDataRefTable* GetWebRenderUserDataTable();
WebRenderLayerManager* LayerManager() WebRenderLayerManager* LayerManager() { return mLayerManager; }
{
return mLayerManager;
}
void AddImageKeyForDiscard(wr::ImageKey key); void AddImageKeyForDiscard(wr::ImageKey key);
void AddBlobImageKeyForDiscard(wr::BlobImageKey key); void AddBlobImageKeyForDiscard(wr::BlobImageKey key);
@ -51,7 +48,8 @@ public:
void AddCompositorAnimationsIdForDiscard(uint64_t aId); void AddCompositorAnimationsIdForDiscard(uint64_t aId);
void DiscardCompositorAnimations(); void DiscardCompositorAnimations();
void RegisterAsyncAnimation(const wr::ImageKey& aKey, SharedSurfacesAnimation* aAnimation); void RegisterAsyncAnimation(const wr::ImageKey& aKey,
SharedSurfacesAnimation* aAnimation);
void DeregisterAsyncAnimation(const wr::ImageKey& aKey); void DeregisterAsyncAnimation(const wr::ImageKey& aKey);
void ClearAsyncAnimations(); void ClearAsyncAnimations();
void WrReleasedImages(const nsTArray<wr::ExternalImageKeyPair>& aPairs); void WrReleasedImages(const nsTArray<wr::ExternalImageKeyPair>& aPairs);
@ -66,19 +64,23 @@ public:
/// Release TextureClient that is bounded to ImageKey. /// Release TextureClient that is bounded to ImageKey.
/// It is used for recycling TextureClient. /// It is used for recycling TextureClient.
void ReleaseTextureOfImage(const wr::ImageKey& aKey); void ReleaseTextureOfImage(const wr::ImageKey& aKey);
wr::FontInstanceKey GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont, wr::FontInstanceKey GetFontKeyForScaledFont(
gfx::ScaledFont* aScaledFont,
wr::IpcResourceUpdateQueue* aResources = nullptr); wr::IpcResourceUpdateQueue* aResources = nullptr);
wr::FontKey GetFontKeyForUnscaledFont(gfx::UnscaledFont* aUnscaledFont, wr::FontKey GetFontKeyForUnscaledFont(
gfx::UnscaledFont* aUnscaledFont,
wr::IpcResourceUpdateQueue* aResources = nullptr); wr::IpcResourceUpdateQueue* aResources = nullptr);
void FlushAsyncResourceUpdates(); void FlushAsyncResourceUpdates();
private: private:
~RenderRootStateManager(); ~RenderRootStateManager();
WebRenderLayerManager* mLayerManager; WebRenderLayerManager* mLayerManager;
Maybe<wr::IpcResourceUpdateQueue> mAsyncResourceUpdates; Maybe<wr::IpcResourceUpdateQueue> mAsyncResourceUpdates;
nsTArray<wr::ImageKey> mImageKeysToDelete; nsTArray<wr::ImageKey> mImageKeysToDelete;
nsTArray<wr::BlobImageKey> mBlobImageKeysToDelete; nsTArray<wr::BlobImageKey> mBlobImageKeysToDelete;
std::unordered_map<uint64_t, RefPtr<SharedSurfacesAnimation>> mAsyncAnimations; std::unordered_map<uint64_t, RefPtr<SharedSurfacesAnimation>>
mAsyncAnimations;
// Set of compositor animation ids for which there are active animations (as // Set of compositor animation ids for which there are active animations (as
// of the last transaction) on the compositor side. // of the last transaction) on the compositor side.

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

@ -1067,7 +1067,8 @@ static bool IsItemProbablyActive(nsDisplayItem* aItem,
bool is2D = t.Is2D(&t2d); bool is2D = t.Is2D(&t2d);
GP("active: %d\n", transformItem->MayBeAnimated(aDisplayListBuilder)); GP("active: %d\n", transformItem->MayBeAnimated(aDisplayListBuilder));
return transformItem->MayBeAnimated(aDisplayListBuilder, false) || return transformItem->MayBeAnimated(aDisplayListBuilder, false) ||
!is2D || HasActiveChildren(*transformItem->GetChildren(), !is2D ||
HasActiveChildren(*transformItem->GetChildren(),
aDisplayListBuilder); aDisplayListBuilder);
} }
case DisplayItemType::TYPE_OPACITY: { case DisplayItemType::TYPE_OPACITY: {
@ -2303,8 +2304,7 @@ Maybe<wr::WrImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
recorder->FlushItem(IntRect(0, 0, size.width, size.height)); recorder->FlushItem(IntRect(0, 0, size.width, size.height));
TakeExternalSurfaces(recorder, maskData->mExternalSurfaces, TakeExternalSurfaces(recorder, maskData->mExternalSurfaces,
mManager->GetRenderRootStateManager(), mManager->GetRenderRootStateManager(), aResources);
aResources);
recorder->Finish(); recorder->Finish();
Range<uint8_t> bytes((uint8_t*)recorder->mOutputStream.mData, Range<uint8_t> bytes((uint8_t*)recorder->mOutputStream.mData,

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

@ -1940,9 +1940,7 @@ class gfxFont {
// The return value is interpreted as a horizontal advance in 16.16 fixed // The return value is interpreted as a horizontal advance in 16.16 fixed
// point format. // point format.
virtual int32_t GetGlyphWidth(uint16_t aGID) { virtual int32_t GetGlyphWidth(uint16_t aGID) { return -1; }
return -1;
}
bool IsSpaceGlyphInvisible(DrawTarget* aRefDrawTarget, bool IsSpaceGlyphInvisible(DrawTarget* aRefDrawTarget,
const gfxTextRun* aTextRun); const gfxTextRun* aTextRun);

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

@ -308,9 +308,9 @@ void nsWebPDecoder::ApplyColorProfile(const char* aProfile, size_t aLength) {
uint32_t profileSpace = qcms_profile_get_color_space(mInProfile); uint32_t profileSpace = qcms_profile_get_color_space(mInProfile);
if (profileSpace == icSigGrayData) { if (profileSpace == icSigGrayData) {
// WebP doesn't produce grayscale data, this must be corrupt. // WebP doesn't produce grayscale data, this must be corrupt.
MOZ_LOG( MOZ_LOG(sWebPLog, LogLevel::Error,
sWebPLog, LogLevel::Error, ("[this=%p] nsWebPDecoder::ApplyColorProfile -- ignoring grayscale "
("[this=%p] nsWebPDecoder::ApplyColorProfile -- ignoring grayscale color profile\n", "color profile\n",
this)); this));
return; return;
} }

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

@ -15,15 +15,13 @@ namespace base {
// thread-safe access, since it will only be modified in testing. // thread-safe access, since it will only be modified in testing.
static AtExitManager* g_top_manager = NULL; static AtExitManager* g_top_manager = NULL;
AtExitManager::AtExitManager() : lock_("AtExitManager"), AtExitManager::AtExitManager() : lock_("AtExitManager"), next_manager_(NULL) {
next_manager_(NULL) {
DCHECK(!g_top_manager); DCHECK(!g_top_manager);
g_top_manager = this; g_top_manager = this;
} }
AtExitManager::AtExitManager(bool shadow) : lock_("AtExitManager"), AtExitManager::AtExitManager(bool shadow)
next_manager_(g_top_manager) : lock_("AtExitManager"), next_manager_(g_top_manager) {
{
DCHECK(shadow || !g_top_manager); DCHECK(shadow || !g_top_manager);
g_top_manager = this; g_top_manager = this;
} }

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

@ -243,11 +243,9 @@ class NowSingleton {
private: private:
explicit NowSingleton(mozilla::StaticMutex& aMutex) explicit NowSingleton(mozilla::StaticMutex& aMutex)
: lock_(aMutex) : lock_(aMutex),
, rollover_(TimeDelta::FromMilliseconds(0)) rollover_(TimeDelta::FromMilliseconds(0)),
, last_seen_(0) last_seen_(0) {}
{
}
~NowSingleton() = default; ~NowSingleton() = default;
mozilla::StaticMutex& lock_; // To protected last_seen_ and rollover_. mozilla::StaticMutex& lock_; // To protected last_seen_ and rollover_.

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

@ -150,9 +150,7 @@ class PipeMap {
} }
private: private:
explicit PipeMap(mozilla::StaticMutex& aMutex) explicit PipeMap(mozilla::StaticMutex& aMutex) : lock_(aMutex) {}
: lock_(aMutex)
{}
~PipeMap() = default; ~PipeMap() = default;
mozilla::StaticMutex& lock_; mozilla::StaticMutex& lock_;

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

@ -20,15 +20,20 @@
// in the code below. Making them equal also ensures that if new process // in the code below. Making them equal also ensures that if new process
// types are added, people will know they may need to add crash reporting // types are added, people will know they may need to add crash reporting
// support in various places because compilation errors will be triggered here. // support in various places because compilation errors will be triggered here.
static_assert(nsICrashService::PROCESS_TYPE_MAIN == (int)GeckoProcessType_Default, static_assert(nsICrashService::PROCESS_TYPE_MAIN ==
(int)GeckoProcessType_Default,
"GeckoProcessType enum is out of sync with nsICrashService!"); "GeckoProcessType enum is out of sync with nsICrashService!");
static_assert(nsICrashService::PROCESS_TYPE_PLUGIN == (int)GeckoProcessType_Plugin, static_assert(nsICrashService::PROCESS_TYPE_PLUGIN ==
(int)GeckoProcessType_Plugin,
"GeckoProcessType enum is out of sync with nsICrashService!"); "GeckoProcessType enum is out of sync with nsICrashService!");
static_assert(nsICrashService::PROCESS_TYPE_CONTENT == (int)GeckoProcessType_Content, static_assert(nsICrashService::PROCESS_TYPE_CONTENT ==
(int)GeckoProcessType_Content,
"GeckoProcessType enum is out of sync with nsICrashService!"); "GeckoProcessType enum is out of sync with nsICrashService!");
static_assert(nsICrashService::PROCESS_TYPE_IPDLUNITTEST == (int)GeckoProcessType_IPDLUnitTest, static_assert(nsICrashService::PROCESS_TYPE_IPDLUNITTEST ==
(int)GeckoProcessType_IPDLUnitTest,
"GeckoProcessType enum is out of sync with nsICrashService!"); "GeckoProcessType enum is out of sync with nsICrashService!");
static_assert(nsICrashService::PROCESS_TYPE_GMPLUGIN == (int)GeckoProcessType_GMPlugin, static_assert(nsICrashService::PROCESS_TYPE_GMPLUGIN ==
(int)GeckoProcessType_GMPlugin,
"GeckoProcessType enum is out of sync with nsICrashService!"); "GeckoProcessType enum is out of sync with nsICrashService!");
static_assert(nsICrashService::PROCESS_TYPE_GPU == (int)GeckoProcessType_GPU, static_assert(nsICrashService::PROCESS_TYPE_GPU == (int)GeckoProcessType_GPU,
"GeckoProcessType enum is out of sync with nsICrashService!"); "GeckoProcessType enum is out of sync with nsICrashService!");
@ -36,14 +41,15 @@ static_assert(nsICrashService::PROCESS_TYPE_VR == (int)GeckoProcessType_VR,
"GeckoProcessType enum is out of sync with nsICrashService!"); "GeckoProcessType enum is out of sync with nsICrashService!");
static_assert(nsICrashService::PROCESS_TYPE_RDD == (int)GeckoProcessType_RDD, static_assert(nsICrashService::PROCESS_TYPE_RDD == (int)GeckoProcessType_RDD,
"GeckoProcessType enum is out of sync with nsICrashService!"); "GeckoProcessType enum is out of sync with nsICrashService!");
static_assert(nsICrashService::PROCESS_TYPE_SOCKET == (int)GeckoProcessType_Socket, static_assert(nsICrashService::PROCESS_TYPE_SOCKET ==
(int)GeckoProcessType_Socket,
"GeckoProcessType enum is out of sync with nsICrashService!"); "GeckoProcessType enum is out of sync with nsICrashService!");
// Add new static asserts here if you add more process types. // Add new static asserts here if you add more process types.
// Update this static assert as well. // Update this static assert as well.
static_assert(nsICrashService::PROCESS_TYPE_SOCKET + 1 == (int)GeckoProcessType_End, static_assert(nsICrashService::PROCESS_TYPE_SOCKET + 1 ==
(int)GeckoProcessType_End,
"GeckoProcessType enum is out of sync with nsICrashService!"); "GeckoProcessType enum is out of sync with nsICrashService!");
namespace mozilla { namespace mozilla {
namespace ipc { namespace ipc {
@ -193,8 +199,8 @@ bool CrashReporterHost::FinalizeCrashReport() {
break; break;
#include "mozilla/GeckoProcessTypes.h" #include "mozilla/GeckoProcessTypes.h"
#undef GECKO_PROCESS_TYPE #undef GECKO_PROCESS_TYPE
// We can't really hit this, thanks to the above switch, but having it here // We can't really hit this, thanks to the above switch, but having it
// will placate the compiler. // here will placate the compiler.
default: default:
NS_ERROR("unknown process type"); NS_ERROR("unknown process type");
return; return;

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

@ -381,7 +381,8 @@ bool IndirectBindingMap::lookup(jsid name, ModuleEnvironmentObject** envOut,
} }
SetProxyReservedSlot(object, ExportsSlot, ObjectValue(*exports)); SetProxyReservedSlot(object, ExportsSlot, ObjectValue(*exports));
SetProxyReservedSlot(object, BindingsSlot, PrivateValue(rootedBindings.release())); SetProxyReservedSlot(object, BindingsSlot,
PrivateValue(rootedBindings.release()));
return &object->as<ModuleNamespaceObject>(); return &object->as<ModuleNamespaceObject>();
} }

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

@ -985,8 +985,8 @@ class NameResolver {
MOZ_ASSERT(parents[initialParents] == cur, MOZ_ASSERT(parents[initialParents] == cur,
"pushed child shouldn't change underneath us"); "pushed child shouldn't change underneath us");
AlwaysPoison(&parents[initialParents], 0xFF, sizeof(parents[initialParents]), AlwaysPoison(&parents[initialParents], 0xFF,
MemCheckKind::MakeUndefined); sizeof(parents[initialParents]), MemCheckKind::MakeUndefined);
return true; return true;
} }

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

@ -3587,8 +3587,8 @@ void GCRuntime::sweepFromBackgroundThread(AutoLockHelperThreadState& lock) {
AutoUnlockHelperThreadState unlock(lock); AutoUnlockHelperThreadState unlock(lock);
sweepBackgroundThings(zones, freeLifoAlloc); sweepBackgroundThings(zones, freeLifoAlloc);
// The main thread may call queueZonesAndStartBackgroundSweep() while this is // The main thread may call queueZonesAndStartBackgroundSweep() while this
// running so we must check there is no more work after releasing the // is running so we must check there is no more work after releasing the
// lock. // lock.
} while (!backgroundSweepZones.ref().isEmpty()); } while (!backgroundSweepZones.ref().isEmpty());
} }
@ -3642,8 +3642,7 @@ void GCRuntime::startBackgroundFree() {
} }
void BackgroundFreeTask::run() { void BackgroundFreeTask::run() {
AutoTraceLog logFreeing(TraceLoggerForCurrentThread(), AutoTraceLog logFreeing(TraceLoggerForCurrentThread(), TraceLogger_GCFree);
TraceLogger_GCFree);
AutoLockHelperThreadState lock; AutoLockHelperThreadState lock;
@ -3666,16 +3665,15 @@ void GCRuntime::freeFromBackgroundThread(AutoLockHelperThreadState& lock) {
lifoBlocks.freeAll(); lifoBlocks.freeAll();
for (Nursery::BufferSet::Range r = buffers.all(); !r.empty(); r.popFront()) { for (Nursery::BufferSet::Range r = buffers.all(); !r.empty();
r.popFront()) {
rt->defaultFreeOp()->free_(r.front()); rt->defaultFreeOp()->free_(r.front());
} }
} while (!lifoBlocksToFree.ref().isEmpty() || } while (!lifoBlocksToFree.ref().isEmpty() ||
!buffersToFreeAfterMinorGC.ref().empty()); !buffersToFreeAfterMinorGC.ref().empty());
} }
void GCRuntime::waitBackgroundFreeEnd() { void GCRuntime::waitBackgroundFreeEnd() { freeTask.join(); }
freeTask.join();
}
struct IsAboutToBeFinalizedFunctor { struct IsAboutToBeFinalizedFunctor {
template <typename T> template <typename T>
@ -6935,8 +6933,8 @@ static bool ShouldCleanUpEverything(JS::gcreason::Reason reason,
} }
static bool ShouldSweepOnBackgroundThread(JS::gcreason::Reason reason) { static bool ShouldSweepOnBackgroundThread(JS::gcreason::Reason reason) {
return reason != JS::gcreason::DESTROY_RUNTIME && return reason != JS::gcreason::DESTROY_RUNTIME && !gcTracer.traceEnabled() &&
!gcTracer.traceEnabled() && CanUseExtraThreads(); CanUseExtraThreads();
} }
void GCRuntime::incrementalSlice(SliceBudget& budget, void GCRuntime::incrementalSlice(SliceBudget& budget,

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

@ -166,8 +166,9 @@ class FreeSpan {
return nullptr; // The span is empty. return nullptr; // The span is empty.
} }
checkSpan(arena); checkSpan(arena);
DebugOnlyPoison(reinterpret_cast<void*>(thing), JS_ALLOCATED_TENURED_PATTERN, DebugOnlyPoison(reinterpret_cast<void*>(thing),
thingSize, MemCheckKind::MakeUndefined); JS_ALLOCATED_TENURED_PATTERN, thingSize,
MemCheckKind::MakeUndefined);
return reinterpret_cast<TenuredCell*>(thing); return reinterpret_cast<TenuredCell*>(thing);
} }

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

@ -72,8 +72,7 @@ inline void js::NurseryChunk::poisonAndInit(JSRuntime* rt, size_t extent) {
MOZ_ASSERT(extent <= ChunkSize); MOZ_ASSERT(extent <= ChunkSize);
MOZ_MAKE_MEM_UNDEFINED(this, extent); MOZ_MAKE_MEM_UNDEFINED(this, extent);
Poison(this, JS_FRESH_NURSERY_PATTERN, extent, Poison(this, JS_FRESH_NURSERY_PATTERN, extent, MemCheckKind::MakeUndefined);
MemCheckKind::MakeUndefined);
new (&trailer) gc::ChunkTrailer(rt, &rt->gc.storeBuffer()); new (&trailer) gc::ChunkTrailer(rt, &rt->gc.storeBuffer());
} }
@ -182,9 +181,7 @@ bool js::Nursery::init(uint32_t maxNurseryBytes, AutoLockGCBgAlloc& lock) {
return true; return true;
} }
js::Nursery::~Nursery() { js::Nursery::~Nursery() { disable(); }
disable();
}
void js::Nursery::enable() { void js::Nursery::enable() {
MOZ_ASSERT(isEmpty()); MOZ_ASSERT(isEmpty());

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

@ -312,8 +312,7 @@ class Nursery {
} }
size_t sizeOfMallocedBuffers(mozilla::MallocSizeOf mallocSizeOf) const { size_t sizeOfMallocedBuffers(mozilla::MallocSizeOf mallocSizeOf) const {
size_t total = 0; size_t total = 0;
for (BufferSet::Range r = mallocedBuffers.all(); !r.empty(); for (BufferSet::Range r = mallocedBuffers.all(); !r.empty(); r.popFront()) {
r.popFront()) {
total += mallocSizeOf(r.front()); total += mallocSizeOf(r.front());
} }
total += mallocedBuffers.shallowSizeOfExcludingThis(mallocSizeOf); total += mallocedBuffers.shallowSizeOfExcludingThis(mallocSizeOf);

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

@ -181,7 +181,8 @@ Phase Statistics::lookupChildPhase(PhaseKind phaseKind) const {
} }
if (phase == Phase::NONE) { if (phase == Phase::NONE) {
MOZ_CRASH_UNSAFE_PRINTF("Child phase kind %u not found under current phase kind %u", MOZ_CRASH_UNSAFE_PRINTF(
"Child phase kind %u not found under current phase kind %u",
unsigned(phaseKind), unsigned(currentPhaseKind())); unsigned(phaseKind), unsigned(currentPhaseKind()));
} }

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

@ -1,3 +1,4 @@
// |jit-test| --more-compartments
const dbg = new Debugger(); const dbg = new Debugger();
const g = evalcx("lazy"); const g = evalcx("lazy");
dbg.addDebuggee(g); dbg.addDebuggee(g);

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

@ -78,3 +78,10 @@ function testTypedArrayLazyBuffer(global) {
} }
testTypedArrayLazyBuffer(newGlobal()); testTypedArrayLazyBuffer(newGlobal());
testTypedArrayLazyBuffer(newGlobal({sameCompartmentAs: this})); testTypedArrayLazyBuffer(newGlobal({sameCompartmentAs: this}));
function testEvalcx() {
var g = newGlobal();
evalcx("this.x = 7", g);
assertEq(g.x, 7);
}
testEvalcx();

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

@ -1740,8 +1740,8 @@ bool BaselineCodeGen<Handler>::emit_JSOP_FUNCTIONTHIS() {
frame.pushThis(); frame.pushThis();
// In strict mode code or self-hosted functions, |this| is left alone. // In strict mode code, |this| is left alone.
if (script->strict() || (function() && function()->isSelfHostedBuiltin())) { if (script->strict()) {
return true; return true;
} }

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

@ -12852,8 +12852,8 @@ AbortReasonOr<Ok> IonBuilder::jsop_functionthis() {
MOZ_ASSERT(info().funMaybeLazy()); MOZ_ASSERT(info().funMaybeLazy());
MOZ_ASSERT(!info().funMaybeLazy()->isArrow()); MOZ_ASSERT(!info().funMaybeLazy()->isArrow());
if (script()->strict() || info().funMaybeLazy()->isSelfHostedBuiltin()) { if (script()->strict()) {
// No need to wrap primitive |this| in strict mode or self-hosted code. // No need to wrap primitive |this| in strict mode.
current->pushSlot(info().thisSlot()); current->pushSlot(info().thisSlot());
return Ok(); return Ok();
} }

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

@ -150,8 +150,7 @@ class IonTryNoteFilter {
class TryNoteIterIon : public TryNoteIter<IonTryNoteFilter> { class TryNoteIterIon : public TryNoteIter<IonTryNoteFilter> {
public: public:
TryNoteIterIon(JSContext* cx, const InlineFrameIterator& frame) TryNoteIterIon(JSContext* cx, const InlineFrameIterator& frame)
: TryNoteIter(cx, frame.script(), frame.pc(), : TryNoteIter(cx, frame.script(), frame.pc(), IonTryNoteFilter(frame)) {}
IonTryNoteFilter(frame)) {}
}; };
static void HandleExceptionIon(JSContext* cx, const InlineFrameIterator& frame, static void HandleExceptionIon(JSContext* cx, const InlineFrameIterator& frame,
@ -323,8 +322,7 @@ class BaselineTryNoteFilter {
class TryNoteIterBaseline : public TryNoteIter<BaselineTryNoteFilter> { class TryNoteIterBaseline : public TryNoteIter<BaselineTryNoteFilter> {
public: public:
TryNoteIterBaseline(JSContext* cx, BaselineFrame* frame, jsbytecode* pc) TryNoteIterBaseline(JSContext* cx, BaselineFrame* frame, jsbytecode* pc)
: TryNoteIter(cx, frame->script(), pc, BaselineTryNoteFilter(frame)) { : TryNoteIter(cx, frame->script(), pc, BaselineTryNoteFilter(frame)) {}
}
}; };
// Close all live iterators on a BaselineFrame due to exception unwinding. The // Close all live iterators on a BaselineFrame due to exception unwinding. The

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

@ -493,10 +493,10 @@ void MacroAssembler::storeRegsInMask(LiveRegisterSet set, Address dest,
} else { } else {
MOZ_CRASH("Unknown register type."); MOZ_CRASH("Unknown register type.");
} }
} }
MOZ_ASSERT(numFpu == 0); MOZ_ASSERT(numFpu == 0);
// Padding to keep the stack aligned, taken from the x64 and mips64 implementations. // Padding to keep the stack aligned, taken from the x64 and mips64
// implementations.
diffF -= diffF % sizeof(uintptr_t); diffF -= diffF % sizeof(uintptr_t);
MOZ_ASSERT(diffF == 0); MOZ_ASSERT(diffF == 0);
} }

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

@ -3557,8 +3557,8 @@ CompileOptions& CompileOptions::setIntroductionInfoToCaller(
DescribeScriptedCallerForCompilation(cx, &maybeScript, &filename, &lineno, DescribeScriptedCallerForCompilation(cx, &maybeScript, &filename, &lineno,
&pcOffset, &mutedErrors); &pcOffset, &mutedErrors);
if (filename) { if (filename) {
return setIntroductionInfo(filename, introductionType, lineno, return setIntroductionInfo(filename, introductionType, lineno, maybeScript,
maybeScript, pcOffset); pcOffset);
} else { } else {
return setIntroductionType(introductionType); return setIntroductionType(introductionType);
} }

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

@ -1328,9 +1328,11 @@ JS_FRIEND_API void js::SetWindowProxy(JSContext* cx, HandleObject global,
CHECK_THREAD(cx); CHECK_THREAD(cx);
cx->check(global, windowProxy); cx->check(global, windowProxy);
MOZ_ASSERT(IsWindowProxy(windowProxy)); MOZ_ASSERT(IsWindowProxy(windowProxy));
global->as<GlobalObject>().setWindowProxy(windowProxy);
GlobalObject& globalObj = global->as<GlobalObject>();
globalObj.setWindowProxy(windowProxy);
globalObj.lexicalEnvironment().setWindowProxyThisValue(windowProxy);
} }
JS_FRIEND_API JSObject* js::ToWindowIfWindowProxy(JSObject* obj) { JS_FRIEND_API JSObject* js::ToWindowIfWindowProxy(JSObject* obj) {

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

@ -3767,6 +3767,13 @@ static void SetStandardRealmOptions(JS::RealmOptions& options) {
static JSObject* NewSandbox(JSContext* cx, bool lazy) { static JSObject* NewSandbox(JSContext* cx, bool lazy) {
JS::RealmOptions options; JS::RealmOptions options;
SetStandardRealmOptions(options); SetStandardRealmOptions(options);
if (defaultToSameCompartment) {
options.creationOptions().setExistingCompartment(cx->global());
} else {
options.creationOptions().setNewCompartmentAndZone();
}
RootedObject obj(cx, RootedObject obj(cx,
JS_NewGlobalObject(cx, &sandbox_class, nullptr, JS_NewGlobalObject(cx, &sandbox_class, nullptr,
JS::DontFireOnNewGlobalHook, options)); JS::DontFireOnNewGlobalHook, options));
@ -3848,17 +3855,13 @@ static bool EvalInContext(JSContext* cx, unsigned argc, Value* vp) {
DescribeScriptedCaller(cx, &filename, &lineno); DescribeScriptedCaller(cx, &filename, &lineno);
{ {
Maybe<JSAutoRealm> ar; sobj = UncheckedUnwrap(sobj, true);
unsigned flags;
JSObject* unwrapped = UncheckedUnwrap(sobj, true, &flags); JSAutoRealm ar(cx, sobj);
if (flags & Wrapper::CROSS_COMPARTMENT) {
sobj = unwrapped;
ar.emplace(cx, sobj);
}
sobj = ToWindowIfWindowProxy(sobj); sobj = ToWindowIfWindowProxy(sobj);
if (!(sobj->getClass()->flags & JSCLASS_IS_GLOBAL)) { if (!JS_IsGlobalObject(sobj)) {
JS_ReportErrorASCII(cx, "Invalid scope argument to evalcx"); JS_ReportErrorASCII(cx, "Invalid scope argument to evalcx");
return false; return false;
} }

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

@ -4213,8 +4213,8 @@ static T* findDebuggerInVector(Debugger* dbg,
// a ReadBarriered version for findDebuggerInVector // a ReadBarriered version for findDebuggerInVector
// TODO: Bug 1515934 - findDebuggerInVector<T> triggers read barriers. // TODO: Bug 1515934 - findDebuggerInVector<T> triggers read barriers.
static ReadBarriered<Debugger*>* static ReadBarriered<Debugger*>* findDebuggerInVector(
findDebuggerInVector(Debugger* dbg, Debugger* dbg,
Vector<ReadBarriered<Debugger*>, 0, js::SystemAllocPolicy>* vec) { Vector<ReadBarriered<Debugger*>, 0, js::SystemAllocPolicy>* vec) {
ReadBarriered<Debugger*>* p; ReadBarriered<Debugger*>* p;
for (p = vec->begin(); p != vec->end(); p++) { for (p = vec->begin(); p != vec->end(); p++) {

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

@ -1133,17 +1133,20 @@ bool LexicalEnvironmentObject::isExtensible() const {
Value LexicalEnvironmentObject::thisValue() const { Value LexicalEnvironmentObject::thisValue() const {
MOZ_ASSERT(isExtensible()); MOZ_ASSERT(isExtensible());
Value v = getReservedSlot(THIS_VALUE_OR_SCOPE_SLOT); Value v = getReservedSlot(THIS_VALUE_OR_SCOPE_SLOT);
if (v.isObject()) {
// A WindowProxy may have been attached after this environment was // Windows must never be exposed to script. setWindowProxyThisValue should
// created so check ToWindowProxyIfWindow again. For example, // have set this to the WindowProxy.
// GlobalObject::createInternal will construct its lexical environment MOZ_ASSERT_IF(v.isObject(), !IsWindow(&v.toObject()));
// before SetWindowProxy can be called.
// See also: js::GetThisValue / js::GetThisValueOfLexical
return ObjectValue(*ToWindowProxyIfWindow(&v.toObject()));
}
return v; return v;
} }
void LexicalEnvironmentObject::setWindowProxyThisValue(JSObject* obj) {
MOZ_ASSERT(isGlobal());
MOZ_ASSERT(IsWindowProxy(obj));
setReservedSlot(THIS_VALUE_OR_SCOPE_SLOT, ObjectValue(*obj));
}
const Class LexicalEnvironmentObject::class_ = { const Class LexicalEnvironmentObject::class_ = {
"LexicalEnvironment", "LexicalEnvironment",
JSCLASS_HAS_RESERVED_SLOTS(LexicalEnvironmentObject::RESERVED_SLOTS) | JSCLASS_HAS_RESERVED_SLOTS(LexicalEnvironmentObject::RESERVED_SLOTS) |

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

@ -567,6 +567,8 @@ class LexicalEnvironmentObject : public EnvironmentObject {
return enclosingEnvironment().as<GlobalObject>(); return enclosingEnvironment().as<GlobalObject>();
} }
void setWindowProxyThisValue(JSObject* obj);
// Global and non-syntactic lexical scopes are extensible. All other // Global and non-syntactic lexical scopes are extensible. All other
// lexical scopes are not. // lexical scopes are not.
bool isExtensible() const; bool isExtensible() const;

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

@ -119,12 +119,14 @@ bool js::GetFunctionThis(JSContext* cx, AbstractFramePtr frame,
MOZ_ASSERT(frame.isFunctionFrame()); MOZ_ASSERT(frame.isFunctionFrame());
MOZ_ASSERT(!frame.callee()->isArrow()); MOZ_ASSERT(!frame.callee()->isArrow());
if (frame.thisArgument().isObject() || frame.callee()->strict() || if (frame.thisArgument().isObject() || frame.callee()->strict()) {
frame.callee()->isSelfHostedBuiltin()) {
res.set(frame.thisArgument()); res.set(frame.thisArgument());
return true; return true;
} }
MOZ_ASSERT(!frame.callee()->isSelfHostedBuiltin(),
"Self-hosted builtins must be strict");
RootedValue thisv(cx, frame.thisArgument()); RootedValue thisv(cx, frame.thisArgument());
// If there is a NSVO on environment chain, use it as basis for fallback // If there is a NSVO on environment chain, use it as basis for fallback
@ -1105,8 +1107,7 @@ class InterpreterTryNoteFilter {
} }
}; };
class TryNoteIterInterpreter class TryNoteIterInterpreter : public TryNoteIter<InterpreterTryNoteFilter> {
: public TryNoteIter<InterpreterTryNoteFilter> {
public: public:
TryNoteIterInterpreter(JSContext* cx, const InterpreterRegs& regs) TryNoteIterInterpreter(JSContext* cx, const InterpreterRegs& regs)
: TryNoteIter(cx, regs.fp()->script(), regs.pc, : TryNoteIter(cx, regs.fp()->script(), regs.pc,

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

@ -415,7 +415,6 @@ class MOZ_STACK_CLASS TryNoteIter {
uint32_t start = tn_->start; uint32_t start = tn_->start;
uint32_t length = tn_->length; uint32_t length = tn_->length;
return offset - start < length; return offset - start < length;
} }
bool done() const { return tn_ == tnEnd_; } bool done() const { return tn_ == tnEnd_; }
const JSTryNote* operator*() const { return tn_; } const JSTryNote* operator*() const { return tn_; }

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

@ -1382,7 +1382,8 @@ ScriptSourceObject* ScriptSourceObject::createInternal(JSContext* cx,
obj->initReservedSlot(ELEMENT_SLOT, MagicValue(JS_GENERIC_MAGIC)); obj->initReservedSlot(ELEMENT_SLOT, MagicValue(JS_GENERIC_MAGIC));
obj->initReservedSlot(ELEMENT_PROPERTY_SLOT, MagicValue(JS_GENERIC_MAGIC)); obj->initReservedSlot(ELEMENT_PROPERTY_SLOT, MagicValue(JS_GENERIC_MAGIC));
obj->initReservedSlot(INTRODUCTION_SCRIPT_SLOT, MagicValue(JS_GENERIC_MAGIC)); obj->initReservedSlot(INTRODUCTION_SCRIPT_SLOT, MagicValue(JS_GENERIC_MAGIC));
obj->initReservedSlot(INTRODUCTION_SOURCE_OBJECT_SLOT, MagicValue(JS_GENERIC_MAGIC)); obj->initReservedSlot(INTRODUCTION_SOURCE_OBJECT_SLOT,
MagicValue(JS_GENERIC_MAGIC));
return obj; return obj;
} }

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

@ -1677,8 +1677,8 @@ bool SavedStacks::getLocation(JSContext* cx, const FrameIter& iter,
} }
void SavedStacks::chooseSamplingProbability(Realm* realm) { void SavedStacks::chooseSamplingProbability(Realm* realm) {
// Use unbarriered version to prevent triggering read barrier while collecting, // Use unbarriered version to prevent triggering read barrier while
// this is safe as long as global does not escape. // collecting, this is safe as long as global does not escape.
GlobalObject* global = realm->unsafeUnbarrieredMaybeGlobal(); GlobalObject* global = realm->unsafeUnbarrieredMaybeGlobal();
if (!global) { if (!global) {
return; return;
@ -1703,8 +1703,7 @@ void SavedStacks::chooseSamplingProbability(Realm* realm) {
if (dbgp->trackingAllocationSites && dbgp->enabled) { if (dbgp->trackingAllocationSites && dbgp->enabled) {
foundAnyDebuggers = true; foundAnyDebuggers = true;
probability = probability = std::max(dbgp->allocationSamplingProbability, probability);
std::max(dbgp->allocationSamplingProbability, probability);
} }
} }
MOZ_ASSERT(foundAnyDebuggers); MOZ_ASSERT(foundAnyDebuggers);

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

@ -3347,6 +3347,7 @@ bool JSRuntime::cloneSelfHostedFunctionScript(JSContext* cx,
MOZ_ASSERT(sourceFun->nargs() == targetFun->nargs()); MOZ_ASSERT(sourceFun->nargs() == targetFun->nargs());
MOZ_ASSERT(sourceScript->hasRest() == targetFun->nonLazyScript()->hasRest()); MOZ_ASSERT(sourceScript->hasRest() == targetFun->nonLazyScript()->hasRest());
MOZ_ASSERT(targetFun->strict(), "Self-hosted builtins must be strict");
// The target function might have been relazified after its flags changed. // The target function might have been relazified after its flags changed.
targetFun->setFlags(targetFun->flags() | sourceFun->flags()); targetFun->setFlags(targetFun->flags() | sourceFun->flags());

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

@ -259,8 +259,10 @@ static const double arm64IonBytecodesPerMs = 750; // Estimate
static const double x64DesktopTierCutoff = x64IonBytecodesPerMs * tierCutoffMs; static const double x64DesktopTierCutoff = x64IonBytecodesPerMs * tierCutoffMs;
static const double x86DesktopTierCutoff = x86IonBytecodesPerMs * tierCutoffMs; static const double x86DesktopTierCutoff = x86IonBytecodesPerMs * tierCutoffMs;
static const double x86MobileTierCutoff = x86DesktopTierCutoff / 2; // Guess static const double x86MobileTierCutoff = x86DesktopTierCutoff / 2; // Guess
static const double arm32MobileTierCutoff = arm32IonBytecodesPerMs * tierCutoffMs; static const double arm32MobileTierCutoff =
static const double arm64MobileTierCutoff = arm64IonBytecodesPerMs * tierCutoffMs; arm32IonBytecodesPerMs * tierCutoffMs;
static const double arm64MobileTierCutoff =
arm64IonBytecodesPerMs * tierCutoffMs;
static double CodesizeCutoff(SystemClass cls) { static double CodesizeCutoff(SystemClass cls) {
switch (cls) { switch (cls) {

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

@ -701,12 +701,9 @@ static void LayoutModuleDtor() {
xpcModuleDtor(); xpcModuleDtor();
} }
static const mozilla::Module kLayoutModule = {mozilla::Module::kVersion, static const mozilla::Module kLayoutModule = {
kLayoutCIDs, mozilla::Module::kVersion, kLayoutCIDs, kLayoutContracts,
kLayoutContracts, kLayoutCategories, nullptr, Initialize,
kLayoutCategories,
nullptr,
Initialize,
LayoutModuleDtor}; LayoutModuleDtor};
NSMODULE_DEFN(nsLayoutModule) = &kLayoutModule; NSMODULE_DEFN(nsLayoutModule) = &kLayoutModule;

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

@ -14,29 +14,30 @@
#endif #endif
#if (defined(XP_WIN) && !defined(HAVE_64BIT_BUILD)) || defined(ANDROID) #if (defined(XP_WIN) && !defined(HAVE_64BIT_BUILD)) || defined(ANDROID)
// Blink's magic depth limit from its HTML parser (513) plus as much as fits in the // Blink's magic depth limit from its HTML parser (513) plus as much as fits in
// default run-time stack on armv7 Android on Dalvik when using display: block minus // the default run-time stack on armv7 Android on Dalvik when using display:
// a bit just to be sure. The Dalvik default stack crashes at 588. ART can do a few // block minus a bit just to be sure. The Dalvik default stack crashes at 588.
// frames more. Using the same number for 32-bit Windows for consistency. Over there, // ART can do a few frames more. Using the same number for 32-bit Windows for
// Blink's magic depth of 513 doesn't fit in the default stack of 1 MB, but this magic // consistency. Over there, Blink's magic depth of 513 doesn't fit in the
// depth fits when the default is grown by mere 192 KB (tested in 64 KB increments). // default stack of 1 MB, but this magic depth fits when the default is grown by
// mere 192 KB (tested in 64 KB increments).
// //
// 32-bit Windows has a different limit compared to 64-bit desktop, because the // 32-bit Windows has a different limit compared to 64-bit desktop, because the
// default stack size affects all threads and consumes address space. Fixing that // default stack size affects all threads and consumes address space. Fixing
// is bug 1257522. // that is bug 1257522.
// //
// 32-bit Android on ARM already happens to have defaults that are close enough to // 32-bit Android on ARM already happens to have defaults that are close enough
// what makes sense as a temporary measure on Windows, so adjusting the Android // to what makes sense as a temporary measure on Windows, so adjusting the
// stack can be a follow-up. The stack on 64-bit ARM needs adjusting in any case // Android stack can be a follow-up. The stack on 64-bit ARM needs adjusting in
// before 64-bit ARM can become tier-1. See bug 1400811. // any case before 64-bit ARM can become tier-1. See bug 1400811.
// //
// Ideally, we'd get rid of this smaller limit and make 32-bit Windows and Android // Ideally, we'd get rid of this smaller limit and make 32-bit Windows and
// capable of working with the Linux/Mac/Win64 number below. // Android capable of working with the Linux/Mac/Win64 number below.
#define MAX_REFLOW_DEPTH 585 #define MAX_REFLOW_DEPTH 585
#else #else
// Blink's magic depth limit from its HTML parser times two. Also just about fits // Blink's magic depth limit from its HTML parser times two. Also just about
// within the system default runtime stack limit of 8 MB on 64-bit Mac and Linux with // fits within the system default runtime stack limit of 8 MB on 64-bit Mac and
// display: table-cell. // Linux with display: table-cell.
#define MAX_REFLOW_DEPTH 1026 #define MAX_REFLOW_DEPTH 1026
#endif #endif

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

@ -33,7 +33,7 @@ class Rule;
namespace dom { namespace dom {
class Document; class Document;
class Element; class Element;
} } // namespace dom
struct MutationClosureData { struct MutationClosureData {
MutationClosureData() : mClosure(nullptr), mElement(nullptr), mModType(0) {} MutationClosureData() : mClosure(nullptr), mElement(nullptr), mModType(0) {}

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

@ -21,10 +21,7 @@ CFLAGS += [
'-I%s/dist/include/dav1d/' % TOPOBJDIR, '-I%s/dist/include/dav1d/' % TOPOBJDIR,
] ]
if CONFIG['CC_TYPE'] == 'clang': # This is Linux only for now
CFLAGS += ['-mstack-alignment=32']
elif CONFIG['CC_TYPE'] == 'gcc':
CFLAGS += ['-mpreferred-stack-boundary=5']
# Attaching config.asm file # Attaching config.asm file
if CONFIG['CPU_ARCH'] == 'x86': if CONFIG['CPU_ARCH'] == 'x86':
@ -32,6 +29,12 @@ if CONFIG['CPU_ARCH'] == 'x86':
SOURCES += ['x86_32/config.asm'] SOURCES += ['x86_32/config.asm']
if CONFIG['CPU_ARCH'] == 'x86_64': if CONFIG['CPU_ARCH'] == 'x86_64':
# Change the default stack aligment (16) to 32
if CONFIG['CC_TYPE'] == 'clang':
CFLAGS += ['-mstack-alignment=32']
elif CONFIG['CC_TYPE'] == 'gcc':
CFLAGS += ['-mpreferred-stack-boundary=5']
if CONFIG['OS_TARGET'] == 'Darwin': if CONFIG['OS_TARGET'] == 'Darwin':
ASFLAGS += ['-I%s/media/libdav1d/asm/x86_64/osx/' % TOPSRCDIR] ASFLAGS += ['-I%s/media/libdav1d/asm/x86_64/osx/' % TOPSRCDIR]
SOURCES += ['x86_64/osx/config.asm'] SOURCES += ['x86_64/osx/config.asm']

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

@ -5,5 +5,7 @@
%define ARCH_X86_64 0 %define ARCH_X86_64 0
%define STACK_ALIGNMENT 32 %define PIC 1
%define STACK_ALIGNMENT 16

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

@ -5,7 +5,5 @@
%define ARCH_X86_64 1 %define ARCH_X86_64 1
%define PIC 1
%define STACK_ALIGNMENT 32 %define STACK_ALIGNMENT 32

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

@ -36,7 +36,8 @@
#define CONFIG_8BPC 1 #define CONFIG_8BPC 1
// Enable asm // Enable asm
#if ARCH_X86_64 == 1 && defined(__linux__) && !defined(__ANDROID__) #if (ARCH_x86_32 == 1 || ARCH_X86_64 == 1) && defined(__linux__) && \
!defined(__ANDROID__)
#define HAVE_ASM 1 #define HAVE_ASM 1
#else #else
#define HAVE_ASM 0 #define HAVE_ASM 0
@ -53,7 +54,7 @@
#endif #endif
// unistd.h is used by tools, which we do not // unistd.h is used by tools, which we do not
// built, so we do not really care. // build, so we do not really care.
#define HAVE_UNISTD_H 1 #define HAVE_UNISTD_H 1
// Important when asm is enabled // Important when asm is enabled
@ -61,5 +62,8 @@
#define PREFIX 1 #define PREFIX 1
#endif #endif
// aligment is 32 in evry case #if ARCH_X86_32 == 1 && defined(__linux__) && !defined(__ANDROID__)
#define STACK_ALIGNMENT 16
#else
#define STACK_ALIGNMENT 32 #define STACK_ALIGNMENT 32
#endif

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

@ -25,8 +25,11 @@ SOURCES += [
] ]
# Enable ASM on Linux for now. # Enable ASM on Linux for now.
if CONFIG['OS_TARGET'] == 'Linux' and CONFIG['CPU_ARCH'] == 'x86_64': if CONFIG['OS_TARGET'] == 'Linux' and (CONFIG['CPU_ARCH'] in ('x86', 'x86_64')):
# Default stack aligment is 16 bytes
DIRS += ['asm'] DIRS += ['asm']
if CONFIG['CPU_ARCH'] == 'x86_64':
# Update stack aligment to 32 bytes
if CONFIG['CC_TYPE'] == 'clang': if CONFIG['CC_TYPE'] == 'clang':
CFLAGS += ['-mstack-alignment=32'] CFLAGS += ['-mstack-alignment=32']
SOURCES['../../third_party/dav1d/src/lib.c'].flags += ['-mstackrealign'] SOURCES['../../third_party/dav1d/src/lib.c'].flags += ['-mstackrealign']

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

@ -20,7 +20,7 @@ origin:
# Human-readable identifier for this version/release # Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS" # Generally "version NNN", "tag SSS", "bookmark SSS"
release: commit b53a99b97f93d0eb15d1f532739ca062fe44b4ca release: commit f813285c1d1a5421e0180efbb7cbdd377cd31c69 (2019-01-13T22:08:25.000Z).
# The package's license, where possible using the mnemonic from # The package's license, where possible using the mnemonic from
# https://spdx.org/licenses/ # https://spdx.org/licenses/

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

@ -21,7 +21,7 @@ namespace mozilla {
namespace dom { namespace dom {
class Document; class Document;
} }
} } // namespace mozilla
struct VisitedURI { struct VisitedURI {
nsCOMPtr<nsIURI> mURI; nsCOMPtr<nsIURI> mURI;

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

@ -1905,11 +1905,10 @@ pref("network.http.rcwn.max_wait_before_racing_ms", 500);
// all available active connections. // all available active connections.
pref("network.http.focused_window_transaction_ratio", "0.9"); pref("network.http.focused_window_transaction_ratio", "0.9");
// XXX Disable for intranet downloading issue.
// This is the size of the flow control window (KB) (i.e., the amount of data // This is the size of the flow control window (KB) (i.e., the amount of data
// that the parent can send to the child before getting an ack). 0 for disable // that the parent can send to the child before getting an ack). 0 for disable
// the flow control. // the flow control.
pref("network.http.send_window_size", 0); pref("network.http.send_window_size", 1024);
// Whether or not we give more priority to active tab. // Whether or not we give more priority to active tab.
// Note that this requires restart for changes to take effect. // Note that this requires restart for changes to take effect.

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

@ -449,7 +449,8 @@ void nsIOService::NotifySocketProcessPrefsChanged(const char *aName) {
dom::Pref pref(nsCString(aName), /* isLocked */ false, null_t(), null_t()); dom::Pref pref(nsCString(aName), /* isLocked */ false, null_t(), null_t());
Preferences::GetPreference(&pref); Preferences::GetPreference(&pref);
auto sendPrefUpdate = [pref]() { auto sendPrefUpdate = [pref]() {
Unused << gIOService->mSocketProcess->GetActor()->SendPreferenceUpdate(pref); Unused << gIOService->mSocketProcess->GetActor()->SendPreferenceUpdate(
pref);
}; };
CallOrWaitForSocketProcess(sendPrefUpdate); CallOrWaitForSocketProcess(sendPrefUpdate);
} }
@ -475,7 +476,8 @@ void nsIOService::OnProcessLaunchComplete(SocketProcessHost *aHost,
} }
} }
void nsIOService::CallOrWaitForSocketProcess(const std::function<void()>& aFunc) { void nsIOService::CallOrWaitForSocketProcess(
const std::function<void()> &aFunc) {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
if (IsSocketProcessLaunchComplete() && SocketProcessReady()) { if (IsSocketProcessLaunchComplete() && SocketProcessReady()) {
aFunc(); aFunc();
@ -499,9 +501,9 @@ void nsIOService::OnProcessUnexpectedShutdown(SocketProcessHost *aHost) {
RefPtr<MemoryReportingProcess> nsIOService::GetSocketProcessMemoryReporter() { RefPtr<MemoryReportingProcess> nsIOService::GetSocketProcessMemoryReporter() {
// Check the prefs here again, since we don't want to create // Check the prefs here again, since we don't want to create
// SocketProcessMemoryReporter for some tests. // SocketProcessMemoryReporter for some tests.
if (!Preferences::GetBool("network.process.enabled") || !SocketProcessReady()) { if (!Preferences::GetBool("network.process.enabled") ||
!SocketProcessReady()) {
return nullptr; return nullptr;
} }
return new SocketProcessMemoryReporter(); return new SocketProcessMemoryReporter();

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

@ -880,7 +880,11 @@ void HttpChannelChild::OnTransportAndData(const nsresult& channelStatus,
bool HttpChannelChild::NeedToReportBytesRead() { bool HttpChannelChild::NeedToReportBytesRead() {
if (mCacheNeedToReportBytesReadInitialized) { if (mCacheNeedToReportBytesReadInitialized) {
return mNeedToReportBytesRead; // No need to send SendRecvBytes when diversion starts since the parent
// process will suspend for diversion triggered in during OnStrartRequest at
// child side, which is earlier. Parent will take over the flow control
// after the diverting starts. Sending |SendBytesRead| is redundant.
return mNeedToReportBytesRead && !mDivertingToParent;
} }
// Might notify parent for partial cache, and the IPC message is ignored by // Might notify parent for partial cache, and the IPC message is ignored by

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

@ -1609,6 +1609,7 @@ HttpChannelParent::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
// We're going to run out of sending window size // We're going to run out of sending window size
if (mSendWindowSize > 0 && mSendWindowSize <= count) { if (mSendWindowSize > 0 && mSendWindowSize <= count) {
MOZ_ASSERT(!mSuspendedForFlowControl); MOZ_ASSERT(!mSuspendedForFlowControl);
LOG((" suspend the channel due to e10s backpressure"));
Unused << mChannel->Suspend(); Unused << mChannel->Suspend();
mSuspendedForFlowControl = true; mSuspendedForFlowControl = true;
mHasSuspendedByBackPressure = true; mHasSuspendedByBackPressure = true;
@ -1652,7 +1653,8 @@ bool HttpChannelParent::NeedFlowControl() {
mozilla::ipc::IPCResult HttpChannelParent::RecvBytesRead( mozilla::ipc::IPCResult HttpChannelParent::RecvBytesRead(
const int32_t& aCount) { const int32_t& aCount) {
if (!NeedFlowControl()) { // no more flow control after diviersion starts
if (!NeedFlowControl() || mDivertingFromChild) {
return IPC_OK(); return IPC_OK();
} }
@ -1661,6 +1663,7 @@ mozilla::ipc::IPCResult HttpChannelParent::RecvBytesRead(
if (mSendWindowSize <= 0 && mSendWindowSize + aCount > 0) { if (mSendWindowSize <= 0 && mSendWindowSize + aCount > 0) {
MOZ_ASSERT(mSuspendedForFlowControl); MOZ_ASSERT(mSuspendedForFlowControl);
LOG((" resume the channel due to e10s backpressure relief"));
Unused << mChannel->Resume(); Unused << mChannel->Resume();
mSuspendedForFlowControl = false; mSuspendedForFlowControl = false;
@ -2076,6 +2079,14 @@ nsresult HttpChannelParent::SuspendForDiversion() {
rv = mParentListener->SuspendForDiversion(); rv = mParentListener->SuspendForDiversion();
MOZ_ASSERT(NS_SUCCEEDED(rv)); MOZ_ASSERT(NS_SUCCEEDED(rv));
// After we suspend for diversion, we don't need the flow control since the
// channel is suspended until all the data is consumed and no more e10s later.
// No point to have another redundant suspension.
if (mSuspendedForFlowControl) {
Unused << mChannel->Resume();
mSuspendedForFlowControl = false;
}
// Once this is set, no more OnStart/OnData/OnStop callbacks should be sent // Once this is set, no more OnStart/OnData/OnStop callbacks should be sent
// to the child. // to the child.
mDivertingFromChild = true; mDivertingFromChild = true;

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

@ -15,8 +15,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsParser)
NS_DEFINE_NAMED_CID(NS_PARSER_CID); NS_DEFINE_NAMED_CID(NS_PARSER_CID);
static const mozilla::Module::CIDEntry kParserCIDs[] = { static const mozilla::Module::CIDEntry kParserCIDs[] = {
{&kNS_PARSER_CID, false, nullptr, nsParserConstructor}, {&kNS_PARSER_CID, false, nullptr, nsParserConstructor}, {nullptr}};
{nullptr}};
static nsresult Initialize() { static nsresult Initialize() {
nsresult rv = nsHTMLTags::AddRefTable(); nsresult rv = nsHTMLTags::AddRefTable();

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

@ -150,6 +150,27 @@ And once done:
#. Wait for Firefox to pick-up the changes for your settings key #. Wait for Firefox to pick-up the changes for your settings key
Global Notifications
====================
The polling for changes process sends two notifications that observers can register to:
* ``remote-settings:changes-poll-start``: Polling for changes is starting. triggered either by the scheduled timer or a push broadcast.
* ``remote-settings:changes-poll-end``: Polling for changes has ended
.. code-block:: javascript
const observer = {
observe(aSubject, aTopic, aData) {
Services.obs.removeObserver(this, "remote-settings:changes-poll-start");
const { expectedTimestamp } = JSON.parse(aData);
console.log("Polling started", expectedTimestamp ? "from push broadcast" : "by scheduled trigger");
},
};
Services.obs.addObserver(observer, "remote-settings:changes-poll-start");
Advanced Options Advanced Options
================ ================

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

@ -168,6 +168,8 @@ function remoteSettingsFunction() {
} }
} }
Services.obs.notifyObservers(null, "remote-settings:changes-poll-start", JSON.stringify({ expectedTimestamp }));
const lastEtag = gPrefs.getCharPref(PREF_SETTINGS_LAST_ETAG, ""); const lastEtag = gPrefs.getCharPref(PREF_SETTINGS_LAST_ETAG, "");
let pollResult; let pollResult;
@ -226,6 +228,7 @@ function remoteSettingsFunction() {
// the one in the local database. // the one in the local database.
try { try {
await client.maybeSync(last_modified, { loadDump }); await client.maybeSync(last_modified, { loadDump });
// Save last time this client was successfully synced. // Save last time this client was successfully synced.
Services.prefs.setIntPref(client.lastCheckTimePref, checkedServerTimeInSeconds); Services.prefs.setIntPref(client.lastCheckTimePref, checkedServerTimeInSeconds);
} catch (e) { } catch (e) {
@ -245,7 +248,7 @@ function remoteSettingsFunction() {
gPrefs.setCharPref(PREF_SETTINGS_LAST_ETAG, currentEtag); gPrefs.setCharPref(PREF_SETTINGS_LAST_ETAG, currentEtag);
} }
Services.obs.notifyObservers(null, "remote-settings-changes-polled"); Services.obs.notifyObservers(null, "remote-settings:changes-poll-end");
}; };
/** /**

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

@ -60,6 +60,30 @@ function run_test() {
add_task(clear_state); add_task(clear_state);
add_task(async function test_an_event_is_sent_on_start() {
server.registerPathHandler(CHANGES_PATH, (request, response) => {
response.write(JSON.stringify({ data: [] }));
response.setHeader("ETag", '"42"');
response.setHeader("Date", (new Date()).toUTCString());
response.setStatusLine(null, 200, "OK");
});
let notificationObserved = null;
const observer = {
observe(aSubject, aTopic, aData) {
Services.obs.removeObserver(this, "remote-settings:changes-poll-start");
notificationObserved = JSON.parse(aData);
},
};
Services.obs.addObserver(observer, "remote-settings:changes-poll-start");
await RemoteSettings.pollChanges({ expectedTimestamp: 13 });
Assert.equal(notificationObserved.expectedTimestamp, 13, "start notification should have been observed");
});
add_task(clear_state);
add_task(async function test_check_success() { add_task(async function test_check_success() {
const startHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY); const startHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
const serverTime = 8000; const serverTime = 8000;
@ -86,15 +110,15 @@ add_task(async function test_check_success() {
let maybeSyncCalled = false; let maybeSyncCalled = false;
c.maybeSync = () => { maybeSyncCalled = true; }; c.maybeSync = () => { maybeSyncCalled = true; };
// Ensure that the remote-settings-changes-polled notification works // Ensure that the remote-settings:changes-poll-end notification works
let notificationObserved = false; let notificationObserved = false;
const observer = { const observer = {
observe(aSubject, aTopic, aData) { observe(aSubject, aTopic, aData) {
Services.obs.removeObserver(this, "remote-settings-changes-polled"); Services.obs.removeObserver(this, "remote-settings:changes-poll-end");
notificationObserved = true; notificationObserved = true;
}, },
}; };
Services.obs.addObserver(observer, "remote-settings-changes-polled"); Services.obs.addObserver(observer, "remote-settings:changes-poll-end");
await RemoteSettings.pollChanges(); await RemoteSettings.pollChanges();
@ -131,7 +155,7 @@ add_task(async function test_update_timer_interface() {
}])); }]));
await new Promise((resolve) => { await new Promise((resolve) => {
const e = "remote-settings-changes-polled"; const e = "remote-settings:changes-poll-end";
const changesPolledObserver = { const changesPolledObserver = {
observe(aSubject, aTopic, aData) { observe(aSubject, aTopic, aData) {
Services.obs.removeObserver(this, e); Services.obs.removeObserver(this, e);
@ -164,15 +188,15 @@ add_task(async function test_check_up_to_date() {
Services.prefs.setCharPref(PREF_LAST_ETAG, '"1100"'); Services.prefs.setCharPref(PREF_LAST_ETAG, '"1100"');
// Ensure that the remote-settings-changes-polled notification is sent. // Ensure that the remote-settings:changes-poll-end notification is sent.
let notificationObserved = false; let notificationObserved = false;
const observer = { const observer = {
observe(aSubject, aTopic, aData) { observe(aSubject, aTopic, aData) {
Services.obs.removeObserver(this, "remote-settings-changes-polled"); Services.obs.removeObserver(this, "remote-settings:changes-poll-end");
notificationObserved = true; notificationObserved = true;
}, },
}; };
Services.obs.addObserver(observer, "remote-settings-changes-polled"); Services.obs.addObserver(observer, "remote-settings:changes-poll-end");
// If server has no change, a 304 is received, maybeSync() is not called. // If server has no change, a 304 is received, maybeSync() is not called.
let maybeSyncCalled = false; let maybeSyncCalled = false;
@ -257,6 +281,7 @@ add_task(async function test_client_last_check_is_saved() {
}); });
add_task(clear_state); add_task(clear_state);
add_task(async function test_success_with_partial_list() { add_task(async function test_success_with_partial_list() {
function partialList(request, response) { function partialList(request, response) {
const entries = [{ const entries = [{
@ -353,11 +378,11 @@ add_task(async function test_server_error() {
let notificationObserved = false; let notificationObserved = false;
const observer = { const observer = {
observe(aSubject, aTopic, aData) { observe(aSubject, aTopic, aData) {
Services.obs.removeObserver(this, "remote-settings-changes-polled"); Services.obs.removeObserver(this, "remote-settings:changes-poll-end");
notificationObserved = true; notificationObserved = true;
}, },
}; };
Services.obs.addObserver(observer, "remote-settings-changes-polled"); Services.obs.addObserver(observer, "remote-settings:changes-poll-end");
Services.prefs.setIntPref(PREF_LAST_UPDATE, 42); Services.prefs.setIntPref(PREF_LAST_UPDATE, 42);
// pollChanges() fails with adequate error and no notification. // pollChanges() fails with adequate error and no notification.

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

@ -603,8 +603,10 @@ nsresult Connection::initialize() {
} }
#ifdef MOZ_SQLITE_FTS3_TOKENIZER #ifdef MOZ_SQLITE_FTS3_TOKENIZER
srv = ::sqlite3_db_config(mDBConn, SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0); srv =
MOZ_ASSERT(srv == SQLITE_OK, "SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER should be enabled"); ::sqlite3_db_config(mDBConn, SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0);
MOZ_ASSERT(srv == SQLITE_OK,
"SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER should be enabled");
#endif #endif
// Do not set mDatabaseFile or mFileURL here since this is a "memory" // Do not set mDatabaseFile or mFileURL here since this is a "memory"
@ -642,8 +644,10 @@ nsresult Connection::initialize(nsIFile *aDatabaseFile) {
} }
#ifdef MOZ_SQLITE_FTS3_TOKENIZER #ifdef MOZ_SQLITE_FTS3_TOKENIZER
srv = ::sqlite3_db_config(mDBConn, SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0); srv =
MOZ_ASSERT(srv == SQLITE_OK, "SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER should be enabled"); ::sqlite3_db_config(mDBConn, SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0);
MOZ_ASSERT(srv == SQLITE_OK,
"SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER should be enabled");
#endif #endif
// Do not set mFileURL here since this is database does not have an associated // Do not set mFileURL here since this is database does not have an associated
@ -676,8 +680,10 @@ nsresult Connection::initialize(nsIFileURL *aFileURL) {
} }
#ifdef MOZ_SQLITE_FTS3_TOKENIZER #ifdef MOZ_SQLITE_FTS3_TOKENIZER
srv = ::sqlite3_db_config(mDBConn, SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0); srv =
MOZ_ASSERT(srv == SQLITE_OK, "SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER should be enabled"); ::sqlite3_db_config(mDBConn, SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0);
MOZ_ASSERT(srv == SQLITE_OK,
"SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER should be enabled");
#endif #endif
// Set both mDatabaseFile and mFileURL here. // Set both mDatabaseFile and mFileURL here.

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

@ -20,10 +20,10 @@ use std::sync::Mutex;
use std::thread; use std::thread;
use std::time; use std::time;
use webdriver::capabilities::CapabilitiesMatching; use webdriver::capabilities::CapabilitiesMatching;
use webdriver::command::WebDriverCommand::{AcceptAlert, AddCookie, CloseWindow, DeleteCookie, use webdriver::command::WebDriverCommand::{AcceptAlert, AddCookie, NewWindow, CloseWindow,
DeleteCookies, DeleteSession, DismissAlert, DeleteCookie, DeleteCookies, DeleteSession,
ElementClear, ElementClick, ElementSendKeys, DismissAlert, ElementClear, ElementClick,
ExecuteAsyncScript, ExecuteScript, ElementSendKeys, ExecuteAsyncScript, ExecuteScript,
Extension, FindElement, FindElementElement, Extension, FindElement, FindElementElement,
FindElementElements, FindElements, FullscreenWindow, FindElementElements, FindElements, FullscreenWindow,
Get, GetActiveElement, GetAlertText, GetCSSValue, Get, GetActiveElement, GetAlertText, GetCSSValue,
@ -41,11 +41,11 @@ use webdriver::command::WebDriverCommand::{AcceptAlert, AddCookie, CloseWindow,
use webdriver::command::{ActionsParameters, AddCookieParameters, GetNamedCookieParameters, use webdriver::command::{ActionsParameters, AddCookieParameters, GetNamedCookieParameters,
GetParameters, JavascriptCommandParameters, LocatorParameters, GetParameters, JavascriptCommandParameters, LocatorParameters,
NewSessionParameters, SwitchToFrameParameters, SwitchToWindowParameters, NewSessionParameters, SwitchToFrameParameters, SwitchToWindowParameters,
TimeoutsParameters, WindowRectParameters}; TimeoutsParameters, WindowRectParameters, NewWindowParameters};
use webdriver::command::{WebDriverCommand, WebDriverMessage}; use webdriver::command::{WebDriverCommand, WebDriverMessage};
use webdriver::common::{Cookie, FrameId, WebElement, ELEMENT_KEY, FRAME_KEY, WINDOW_KEY}; use webdriver::common::{Cookie, FrameId, WebElement, ELEMENT_KEY, FRAME_KEY, WINDOW_KEY};
use webdriver::error::{ErrorStatus, WebDriverError, WebDriverResult}; use webdriver::error::{ErrorStatus, WebDriverError, WebDriverResult};
use webdriver::response::{CloseWindowResponse, CookieResponse, CookiesResponse, use webdriver::response::{NewWindowResponse, CloseWindowResponse, CookieResponse, CookiesResponse,
ElementRectResponse, NewSessionResponse, TimeoutsResponse, ElementRectResponse, NewSessionResponse, TimeoutsResponse,
ValueResponse, WebDriverResponse, WindowRectResponse}; ValueResponse, WebDriverResponse, WindowRectResponse};
use webdriver::server::{Session, WebDriverHandler}; use webdriver::server::{Session, WebDriverHandler};
@ -522,6 +522,28 @@ impl MarionetteSession {
} }
Status => panic!("Got status command that should already have been handled"), Status => panic!("Got status command that should already have been handled"),
GetWindowHandles => WebDriverResponse::Generic(resp.to_value_response(false)?), GetWindowHandles => WebDriverResponse::Generic(resp.to_value_response(false)?),
NewWindow(_) => {
let handle: String = try_opt!(
try_opt!(
resp.result.get("handle"),
ErrorStatus::UnknownError,
"Failed to find handle field"
).as_str(),
ErrorStatus::UnknownError,
"Failed to interpret handle as string"
).into();
let typ: String = try_opt!(
try_opt!(
resp.result.get("type"),
ErrorStatus::UnknownError,
"Failed to find type field"
).as_str(),
ErrorStatus::UnknownError,
"Failed to interpret type as string"
).into();
WebDriverResponse::NewWindow(NewWindowResponse { handle, typ })
}
CloseWindow => { CloseWindow => {
let data = try_opt!( let data = try_opt!(
resp.result.as_array(), resp.result.as_array(),
@ -788,6 +810,7 @@ impl MarionetteCommand {
(Some("WebDriver:AcceptDialog"), None) (Some("WebDriver:AcceptDialog"), None)
} }
AddCookie(ref x) => (Some("WebDriver:AddCookie"), Some(x.to_marionette())), AddCookie(ref x) => (Some("WebDriver:AddCookie"), Some(x.to_marionette())),
NewWindow(ref x) => (Some("WebDriver:NewWindow"), Some(x.to_marionette())),
CloseWindow => (Some("WebDriver:CloseWindow"), None), CloseWindow => (Some("WebDriver:CloseWindow"), None),
DeleteCookie(ref x) => { DeleteCookie(ref x) => {
let mut data = Map::new(); let mut data = Map::new();
@ -1425,6 +1448,16 @@ impl ToMarionette for LocatorParameters {
} }
} }
impl ToMarionette for NewWindowParameters {
fn to_marionette(&self) -> WebDriverResult<Map<String, Value>> {
let mut data = Map::new();
if let Some(ref x) = self.type_hint {
data.insert("type".to_string(), serde_json::to_value(x)?);
}
Ok(data)
}
}
impl ToMarionette for SwitchToFrameParameters { impl ToMarionette for SwitchToFrameParameters {
fn to_marionette(&self) -> WebDriverResult<Map<String, Value>> { fn to_marionette(&self) -> WebDriverResult<Map<String, Value>> {
let mut data = Map::new(); let mut data = Map::new();

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

@ -8,6 +8,12 @@
[Default "camera;microphone" feature policy ["self"\] disallows cross-origin iframes.] [Default "camera;microphone" feature policy ["self"\] disallows cross-origin iframes.]
expected: FAIL expected: FAIL
[Feature policy "microphone" can be enabled in cross-origin iframes using "allow" attribute.]
expected: FAIL
[Feature policy "camera" can be enabled in cross-origin iframes using "allow" attribute.]
expected: FAIL
[MediaStream-default-feature-policy.https.html] [MediaStream-default-feature-policy.https.html]
[Default "microphone" feature policy ["self"\] disallows cross-origin iframes.] [Default "microphone" feature policy ["self"\] disallows cross-origin iframes.]
@ -19,3 +25,8 @@
[Default "camera;microphone" feature policy ["self"\] disallows cross-origin iframes.] [Default "camera;microphone" feature policy ["self"\] disallows cross-origin iframes.]
expected: FAIL expected: FAIL
[Feature policy "microphone" can be enabled in cross-origin iframes using "allow" attribute.]
expected: FAIL
[Feature policy "camera" can be enabled in cross-origin iframes using "allow" attribute.]
expected: FAIL

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

@ -0,0 +1,2 @@
[new_window.py]
disabled: os == "android": Fennec doesn't support opening new windows

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

@ -82,7 +82,7 @@ function test_feature_availability_with_post_message_result(
// tests the feature availability and posts the result back to the parent. // tests the feature availability and posts the result back to the parent.
// Otherwise, does nothing. // Otherwise, does nothing.
function test_feature_in_iframe(feature_name, feature_promise_factory) { function test_feature_in_iframe(feature_name, feature_promise_factory) {
if (location.hash.includes(feature_name)) { if (location.hash.endsWith(`#${feature_name}`)) {
feature_promise_factory().then( feature_promise_factory().then(
() => window.parent.postMessage('#OK', '*'), () => window.parent.postMessage('#OK', '*'),
(e) => window.parent.postMessage('#' + e.name, '*')); (e) => window.parent.postMessage('#' + e.name, '*'));

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

@ -7,56 +7,73 @@
<script> <script>
'use strict'; 'use strict';
// The promise_factory must return a promise that runs the feature and async function gUM({audio, video}) {
// resolves if feature usage is successful, otherwise rejects. Using let stream;
// getUserMedia is successful if at least one mic/camera is returned when try {
// mic/camera has been explicitly allowed by feature policy. stream = await navigator.mediaDevices.getUserMedia({audio, video});
function promise_factory(allowed_features) { // getUserMedia must guarantee the number of tracks requested or fail.
return new Promise((resolve, reject) => { if ((audio && stream.getAudioTracks().length == 0) ||
navigator.mediaDevices.getUserMedia({video: true, audio: true}).then( (video && stream.getVideoTracks().length == 0)) {
function(stream) { throw {name: `All requested devices must be present with ` +
// If microphone is allowed, there should be at least one microphone `audio ${audio} and video ${video}, or fail`};
// in the result. If camera is allowed, there should be at least one }
// camera in the result. } finally {
if ((allowed_features.includes('microphone') && if (stream) {
stream.getAudioTracks().length == 0) || stream.getTracks().forEach(track => track.stop());
(allowed_features.includes('camera') && }
stream.getVideoTracks().length == 0)) { }
reject('Feature policy allowed feature but devices not ' +
'present.');
} else {
// Otherwise the result is expected.
resolve();
} }
},
function(error) { reject(error); });
});
};
var cross_domain = get_host_info().HTTPS_REMOTE_ORIGIN; async function must_disallow_gUM({audio, video}) {
try {
await gUM({audio, video});
} catch (e) {
if (e.name == 'NotAllowedError') {
return;
}
throw e;
}
throw {name: `audio ${audio} and video ${video} constraints must not be ` +
`allowed.`};
}
const cross_domain = get_host_info().HTTPS_REMOTE_ORIGIN;
run_all_fp_tests_allow_self( run_all_fp_tests_allow_self(
cross_domain, cross_domain,
'microphone', 'microphone',
'NotAllowedError', 'NotAllowedError',
function() { async () => {
return promise_factory('microphone'); await gUM({audio: true});
}); if (window.location.href.includes(cross_domain)) {
await must_disallow_gUM({video: true});
await must_disallow_gUM({audio: true, video: true});
}
}
);
run_all_fp_tests_allow_self( run_all_fp_tests_allow_self(
cross_domain, cross_domain,
'camera', 'camera',
'NotAllowedError', 'NotAllowedError',
function() { async () => {
return promise_factory('camera'); await gUM({video: true});
}); if (window.location.href.includes(cross_domain)) {
await must_disallow_gUM({audio: true});
await must_disallow_gUM({audio: true, video: true});
}
}
);
run_all_fp_tests_allow_self( run_all_fp_tests_allow_self(
cross_domain, cross_domain,
'camera;microphone', 'camera;microphone',
'NotAllowedError', 'NotAllowedError',
function() { async () => {
return promise_factory('camera; microphone'); await gUM({audio: true, video: true});
}); await gUM({audio: true});
await gUM({video: true});
}
);
</script> </script>
</body> </body>

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

@ -0,0 +1,10 @@
def opener(session):
return session.execute_script("""
return window.opener;
""")
def window_name(session):
return session.execute_script("""
return window.name;
""")

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

@ -0,0 +1,52 @@
import pytest
from webdriver.transport import Response
from tests.support.asserts import assert_error, assert_success
def new_window(session, type_hint=None):
return session.transport.send(
"POST", "session/{session_id}/window/new".format(**vars(session)),
{"type": type_hint})
def test_null_parameter_value(session, http):
path = "/session/{session_id}/window/new".format(**vars(session))
with http.post(path, None) as response:
assert_error(Response.from_http(response), "invalid argument")
def test_no_browsing_context(session, closed_window):
response = new_window(session)
assert_error(response, "no such window")
@pytest.mark.parametrize("type_hint", [True, 42, 4.2, [], {}])
def test_type_with_invalid_type(session, type_hint):
response = new_window(session, type_hint)
assert_error(response, "invalid argument")
def test_type_with_null_value(session):
original_handles = session.handles
response = new_window(session, type_hint=None)
value = assert_success(response)
handles = session.handles
assert len(handles) == len(original_handles) + 1
assert value["handle"] in handles
assert value["handle"] not in original_handles
assert value["type"] in ["tab", "window"]
def test_type_with_unknown_value(session):
original_handles = session.handles
response = new_window(session, type_hint="foo")
value = assert_success(response)
handles = session.handles
assert len(handles) == len(original_handles) + 1
assert value["handle"] in handles
assert value["handle"] not in original_handles
assert value["type"] in ["tab", "window"]

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

@ -0,0 +1,48 @@
from tests.support.asserts import assert_success
from . import opener, window_name
def new_window(session, type_hint=None):
return session.transport.send(
"POST", "session/{session_id}/window/new".format(**vars(session)),
{"type": type_hint})
def test_new_tab(session):
original_handles = session.handles
response = new_window(session, type_hint="tab")
value = assert_success(response)
handles = session.handles
assert len(handles) == len(original_handles) + 1
assert value["handle"] in handles
assert value["handle"] not in original_handles
assert value["type"] == "tab"
def test_new_tab_opens_about_blank(session):
response = new_window(session, type_hint="tab")
value = assert_success(response)
assert value["type"] == "tab"
session.handle = value["handle"]
assert session.url == "about:blank"
def test_new_tab_sets_no_window_name(session):
response = new_window(session, type_hint="tab")
value = assert_success(response)
assert value["type"] == "tab"
session.handle = value["handle"]
assert window_name(session) == ""
def test_new_tab_sets_no_opener(session):
response = new_window(session, type_hint="tab")
value = assert_success(response)
assert value["type"] == "tab"
session.handle = value["handle"]
assert opener(session) is None

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

@ -0,0 +1,48 @@
from tests.support.asserts import assert_success
from . import opener, window_name
def new_window(session, type_hint=None):
return session.transport.send(
"POST", "session/{session_id}/window/new".format(**vars(session)),
{"type": type_hint})
def test_type_with_window(session):
original_handles = session.handles
response = new_window(session, type_hint="window")
value = assert_success(response)
handles = session.handles
assert len(handles) == len(original_handles) + 1
assert value["handle"] in handles
assert value["handle"] not in original_handles
assert value["type"] == "window"
def test_new_window_opens_about_blank(session):
response = new_window(session, type_hint="window")
value = assert_success(response)
assert value["type"] == "window"
session.handle = value["handle"]
assert session.url == "about:blank"
def test_new_window_sets_no_window_name(session):
response = new_window(session, type_hint="window")
value = assert_success(response)
assert value["type"] == "window"
session.handle = value["handle"]
assert window_name(session) == ""
def test_new_window_sets_no_opener(session):
response = new_window(session, type_hint="window")
value = assert_success(response)
assert value["type"] == "window"
session.handle = value["handle"]
assert opener(session) is None

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

@ -0,0 +1,121 @@
# META: timeout=long
import pytest
from tests.support.asserts import assert_dialog_handled, assert_error, assert_success
def new_window(session, type_hint=None):
return session.transport.send(
"POST", "session/{session_id}/window/new".format(**vars(session)),
{"type": type_hint})
@pytest.fixture
def check_user_prompt_closed_without_exception(session, create_dialog):
def check_user_prompt_closed_without_exception(dialog_type, retval):
original_handles = session.handles
create_dialog(dialog_type, text=dialog_type)
response = new_window(session)
value = assert_success(response)
handles = session.handles
assert len(handles) == len(original_handles) + 1
assert value["handle"] in handles
assert value["handle"] not in original_handles
assert_dialog_handled(session, expected_text=dialog_type, expected_retval=retval)
return check_user_prompt_closed_without_exception
@pytest.fixture
def check_user_prompt_closed_with_exception(session, create_dialog):
def check_user_prompt_closed_with_exception(dialog_type, retval):
original_handles = session.handles
create_dialog(dialog_type, text=dialog_type)
response = new_window(session)
assert_error(response, "unexpected alert open")
assert_dialog_handled(session, expected_text=dialog_type, expected_retval=retval)
assert len(session.handles) == len(original_handles)
return check_user_prompt_closed_with_exception
@pytest.fixture
def check_user_prompt_not_closed_but_exception(session, create_dialog):
def check_user_prompt_not_closed_but_exception(dialog_type):
original_handles = session.handles
create_dialog(dialog_type, text=dialog_type)
response = new_window(session)
assert_error(response, "unexpected alert open")
assert session.alert.text == dialog_type
session.alert.dismiss()
assert len(session.handles) == len(original_handles)
return check_user_prompt_not_closed_but_exception
@pytest.mark.capabilities({"unhandledPromptBehavior": "accept"})
@pytest.mark.parametrize("dialog_type, retval", [
("alert", None),
("confirm", True),
("prompt", ""),
])
def test_accept(check_user_prompt_closed_without_exception, dialog_type, retval):
check_user_prompt_closed_without_exception(dialog_type, retval)
@pytest.mark.capabilities({"unhandledPromptBehavior": "accept and notify"})
@pytest.mark.parametrize("dialog_type, retval", [
("alert", None),
("confirm", True),
("prompt", ""),
])
def test_accept_and_notify(check_user_prompt_closed_with_exception, dialog_type, retval):
check_user_prompt_closed_with_exception(dialog_type, retval)
@pytest.mark.capabilities({"unhandledPromptBehavior": "dismiss"})
@pytest.mark.parametrize("dialog_type, retval", [
("alert", None),
("confirm", False),
("prompt", None),
])
def test_dismiss(check_user_prompt_closed_without_exception, dialog_type, retval):
check_user_prompt_closed_without_exception(dialog_type, retval)
@pytest.mark.capabilities({"unhandledPromptBehavior": "dismiss and notify"})
@pytest.mark.parametrize("dialog_type, retval", [
("alert", None),
("confirm", False),
("prompt", None),
])
def test_dismiss_and_notify(check_user_prompt_closed_with_exception, dialog_type, retval):
check_user_prompt_closed_with_exception(dialog_type, retval)
@pytest.mark.capabilities({"unhandledPromptBehavior": "ignore"})
@pytest.mark.parametrize("dialog_type", ["alert", "confirm", "prompt"])
def test_ignore(check_user_prompt_not_closed_but_exception, dialog_type):
check_user_prompt_not_closed_but_exception(dialog_type)
@pytest.mark.parametrize("dialog_type, retval", [
("alert", None),
("confirm", False),
("prompt", None),
])
def test_default(check_user_prompt_closed_with_exception, dialog_type, retval):
check_user_prompt_closed_with_exception(dialog_type, retval)

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

@ -23,6 +23,7 @@ pub enum WebDriverCommand<T: WebDriverExtensionCommand> {
GetPageSource, GetPageSource,
GetWindowHandle, GetWindowHandle,
GetWindowHandles, GetWindowHandles,
NewWindow(NewWindowParameters),
CloseWindow, CloseWindow,
GetWindowRect, GetWindowRect,
SetWindowRect(WindowRectParameters), SetWindowRect(WindowRectParameters),
@ -120,6 +121,7 @@ impl<U: WebDriverExtensionRoute> WebDriverMessage<U> {
Route::GetPageSource => WebDriverCommand::GetPageSource, Route::GetPageSource => WebDriverCommand::GetPageSource,
Route::GetWindowHandle => WebDriverCommand::GetWindowHandle, Route::GetWindowHandle => WebDriverCommand::GetWindowHandle,
Route::GetWindowHandles => WebDriverCommand::GetWindowHandles, Route::GetWindowHandles => WebDriverCommand::GetWindowHandles,
Route::NewWindow => WebDriverCommand::NewWindow(serde_json::from_str(raw_body)?),
Route::CloseWindow => WebDriverCommand::CloseWindow, Route::CloseWindow => WebDriverCommand::CloseWindow,
Route::GetTimeouts => WebDriverCommand::GetTimeouts, Route::GetTimeouts => WebDriverCommand::GetTimeouts,
Route::SetTimeouts => WebDriverCommand::SetTimeouts(serde_json::from_str(raw_body)?), Route::SetTimeouts => WebDriverCommand::SetTimeouts(serde_json::from_str(raw_body)?),
@ -469,6 +471,12 @@ impl CapabilitiesMatching for NewSessionParameters {
} }
} }
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct NewWindowParameters {
#[serde(rename = "type")]
pub type_hint: Option<String>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct SendKeysParameters { pub struct SendKeysParameters {
pub text: String, pub text: String,
@ -939,6 +947,45 @@ mod tests {
check_deserialize(&json, &data); check_deserialize(&json, &data);
} }
#[test]
fn test_json_new_window_parameters_without_type() {
let json = r#"{}"#;
let data = NewWindowParameters { type_hint: None };
check_deserialize(&json, &data);
}
#[test]
fn test_json_new_window_parameters_with_optional_null_type() {
let json = r#"{"type":null}"#;
let data = NewWindowParameters { type_hint: None };
check_deserialize(&json, &data);
}
#[test]
fn test_json_new_window_parameters_with_supported_type() {
let json = r#"{"type":"tab"}"#;
let data = NewWindowParameters { type_hint: Some("tab".into()) };
check_deserialize(&json, &data);
}
#[test]
fn test_json_new_window_parameters_with_unknown_type() {
let json = r#"{"type":"foo"}"#;
let data = NewWindowParameters { type_hint: Some("foo".into()) };
check_deserialize(&json, &data);
}
#[test]
fn test_json_new_window_parameters_with_invalid_type() {
let json = r#"{"type":3}"#;
assert!(serde_json::from_str::<NewWindowParameters>(&json).is_err());
}
#[test] #[test]
fn test_json_send_keys_parameters_with_value() { fn test_json_send_keys_parameters_with_value() {
let json = r#"{"text":"foo"}"#; let json = r#"{"text":"foo"}"#;

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

@ -25,6 +25,7 @@ fn standard_routes<U: WebDriverExtensionRoute>() -> Vec<(Method, &'static str, R
"/session/{sessionId}/window/handles", "/session/{sessionId}/window/handles",
Route::GetWindowHandles, Route::GetWindowHandles,
), ),
(Method::POST, "/session/{sessionId}/window/new", Route::NewWindow),
(Method::DELETE, "/session/{sessionId}/window", Route::CloseWindow), (Method::DELETE, "/session/{sessionId}/window", Route::CloseWindow),
( (
Method::GET, Method::GET,
@ -229,6 +230,7 @@ pub enum Route<U: WebDriverExtensionRoute> {
GetPageSource, GetPageSource,
GetWindowHandle, GetWindowHandle,
GetWindowHandles, GetWindowHandles,
NewWindow,
CloseWindow, CloseWindow,
GetWindowSize, // deprecated GetWindowSize, // deprecated
SetWindowSize, // deprecated SetWindowSize, // deprecated

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