diff --git a/accessible/interfaces/ia2/moz.build b/accessible/interfaces/ia2/moz.build index 471c74656f1..24542820825 100644 --- a/accessible/interfaces/ia2/moz.build +++ b/accessible/interfaces/ia2/moz.build @@ -13,7 +13,6 @@ DEFFILE = SRCDIR + '/IA2Marshal.def' OS_LIBS += [ 'uuid', 'kernel32', - 'rpcns4', 'rpcrt4', 'ole32', 'oleaut32', diff --git a/accessible/interfaces/msaa/moz.build b/accessible/interfaces/msaa/moz.build index e555fabd3cc..68b2203b465 100644 --- a/accessible/interfaces/msaa/moz.build +++ b/accessible/interfaces/msaa/moz.build @@ -22,7 +22,6 @@ DEFFILE = SRCDIR + '/AccessibleMarshal.def' OS_LIBS += [ 'kernel32', - 'rpcns4', 'rpcrt4', 'oleaut32', ] diff --git a/addon-sdk/source/examples/debug-client/data/client.js b/addon-sdk/source/examples/debug-client/data/client.js index baec0910532..022f9a1c35c 100644 --- a/addon-sdk/source/examples/debug-client/data/client.js +++ b/addon-sdk/source/examples/debug-client/data/client.js @@ -202,7 +202,7 @@ var Connection = Class({ }, poolFor: function(id) { for (let pool of this.pools.values()) { - if pool.has(id) + if (pool.has(id)) return pool; } }, @@ -797,7 +797,7 @@ var Tab = Client.from({ "storageActor": "storage", "gcliActor": "gcli", "memoryActor": "memory", - "eventLoopLag": "eventLoopLag" + "eventLoopLag": "eventLoopLag", "trace": "trace", // missing } diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index 9acfe369231..4402d03c539 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -322,7 +322,6 @@ pref("media.fragmented-mp4.gonk.enabled", true); pref("media.video-queue.default-size", 3); // optimize images' memory usage -pref("image.downscale-during-decode.enabled", true); pref("image.mem.decodeondraw", true); pref("image.mem.allow_locking_in_content_processes", false); /* don't allow image locking */ // Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller. diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 389c31f56ee..8e4e7071fed 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + @@ -138,7 +138,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 03630ef4cd3..0fd5890abf9 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 47587bc2b83..b2f763d109b 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index dfd6eb77c78..a9fab1cb0e6 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 9fb90115ade..66d91bbc360 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + @@ -124,7 +124,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 03630ef4cd3..0fd5890abf9 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 7712167ece2..58e2e8731a5 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 21e478aa8a8..ace40fc51fc 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index afb734df345..9fd413c5da5 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "66558ce7f36809a20d1c721fd4d457913b09c5c7", + "git_revision": "c8aecdd05ddc11013945923b8d5fa4df077e56a0", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "73b67adb48cdfbba7a520d3499e9759757c8b3c5", + "revision": "78b760e2859cb7504f864aa96a5b98748ae1bbb6", "repo_path": "integration/gaia-central" } diff --git a/b2g/config/mozconfigs/linux32_gecko/nightly b/b2g/config/mozconfigs/linux32_gecko/nightly index 66e785ab3d7..7b38c318933 100644 --- a/b2g/config/mozconfigs/linux32_gecko/nightly +++ b/b2g/config/mozconfigs/linux32_gecko/nightly @@ -1,6 +1,7 @@ MOZ_AUTOMATION_L10N_CHECK=0 MOZ_AUTOMATION_UPLOAD_SYMBOLS=0 MOZ_AUTOMATION_UPDATE_PACKAGING=0 +MOZ_AUTOMATION_SDK=0 . "$topsrcdir/b2g/config/mozconfigs/common" . "$topsrcdir/build/unix/mozconfig.linux32" diff --git a/b2g/config/mozconfigs/linux64_gecko/nightly b/b2g/config/mozconfigs/linux64_gecko/nightly index 13dccdf85d1..f098f711065 100644 --- a/b2g/config/mozconfigs/linux64_gecko/nightly +++ b/b2g/config/mozconfigs/linux64_gecko/nightly @@ -1,6 +1,7 @@ MOZ_AUTOMATION_L10N_CHECK=0 MOZ_AUTOMATION_UPLOAD_SYMBOLS=0 MOZ_AUTOMATION_UPDATE_PACKAGING=0 +MOZ_AUTOMATION_SDK=0 . "$topsrcdir/b2g/config/mozconfigs/common" . "$topsrcdir/build/unix/mozconfig.linux" diff --git a/b2g/config/mozconfigs/macosx64_gecko/nightly b/b2g/config/mozconfigs/macosx64_gecko/nightly index aead3abddc8..05eb3c9e877 100644 --- a/b2g/config/mozconfigs/macosx64_gecko/nightly +++ b/b2g/config/mozconfigs/macosx64_gecko/nightly @@ -1,5 +1,6 @@ MOZ_AUTOMATION_UPLOAD_SYMBOLS=0 MOZ_AUTOMATION_UPDATE_PACKAGING=0 +MOZ_AUTOMATION_SDK=0 . "$topsrcdir/b2g/config/mozconfigs/common" # Use sccache diff --git a/b2g/config/mozconfigs/win32_gecko/nightly b/b2g/config/mozconfigs/win32_gecko/nightly index 5dd636d428a..7fc27a5f831 100644 --- a/b2g/config/mozconfigs/win32_gecko/nightly +++ b/b2g/config/mozconfigs/win32_gecko/nightly @@ -1,6 +1,7 @@ MOZ_AUTOMATION_L10N_CHECK=0 MOZ_AUTOMATION_UPLOAD_SYMBOLS=0 MOZ_AUTOMATION_UPDATE_PACKAGING=0 +MOZ_AUTOMATION_SDK=0 . "$topsrcdir/b2g/config/mozconfigs/common" ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 4b148d9c2ea..f3608c81bf1 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index d729cbcab84..096720d5cd6 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + @@ -124,7 +124,7 @@ - + diff --git a/b2g/dev/config/mozconfigs/linux64/mulet b/b2g/dev/config/mozconfigs/linux64/mulet index 9d8739b81f9..72170696a62 100644 --- a/b2g/dev/config/mozconfigs/linux64/mulet +++ b/b2g/dev/config/mozconfigs/linux64/mulet @@ -1,6 +1,7 @@ MOZ_AUTOMATION_L10N_CHECK=0 MOZ_AUTOMATION_UPLOAD_SYMBOLS=0 MOZ_AUTOMATION_UPDATE_PACKAGING=0 +MOZ_AUTOMATION_SDK=0 . "$topsrcdir/browser/config/mozconfigs/linux64/nightly" ac_add_options --enable-application=b2g/dev diff --git a/b2g/dev/config/mozconfigs/macosx64/mulet b/b2g/dev/config/mozconfigs/macosx64/mulet index 73a2ddd7ec1..2d459a23278 100644 --- a/b2g/dev/config/mozconfigs/macosx64/mulet +++ b/b2g/dev/config/mozconfigs/macosx64/mulet @@ -2,6 +2,7 @@ MOZ_AUTOMATION_BUILD_SYMBOLS=0 MOZ_AUTOMATION_PACKAGE_TESTS=0 MOZ_AUTOMATION_UPLOAD_SYMBOLS=0 MOZ_AUTOMATION_UPDATE_PACKAGING=0 +MOZ_AUTOMATION_SDK=0 . $topsrcdir/build/macosx/mozconfig.common ac_add_options --enable-application=b2g/dev diff --git a/b2g/dev/config/mozconfigs/win32/mulet b/b2g/dev/config/mozconfigs/win32/mulet index 8bfaf55f272..4cfdf801183 100644 --- a/b2g/dev/config/mozconfigs/win32/mulet +++ b/b2g/dev/config/mozconfigs/win32/mulet @@ -4,6 +4,7 @@ MOZ_AUTOMATION_PACKAGE_TESTS=0 MOZ_AUTOMATION_INSTALLER=0 MOZ_AUTOMATION_UPLOAD_SYMBOLS=0 MOZ_AUTOMATION_UPDATE_PACKAGING=0 +MOZ_AUTOMATION_SDK=0 . "$topsrcdir/browser/config/mozconfigs/win32/nightly" ac_add_options --enable-application=b2g/dev diff --git a/browser/base/content/sanitizeDialog.js b/browser/base/content/sanitizeDialog.js index bd7dc4643fd..538b179cab6 100644 --- a/browser/base/content/sanitizeDialog.js +++ b/browser/base/content/sanitizeDialog.js @@ -266,7 +266,7 @@ var gSanitizePromptDialog = { this.showItemList(); else this.hideItemList(); - } + }, #ifdef CRH_DIALOG_TREE_VIEW // A duration value; used in the same context as Sanitizer.TIMESPAN_HOUR, diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index 667ac2c2b19..e473459f111 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -83,6 +83,9 @@ (Components.utils.import("resource://gre/modules/PlacesUtils.jsm", {})).PlacesUtils; + + (Components.utils.import("resource://gre/modules/AppConstants.jsm", {})).AppConstants; + document.getAnonymousElementByAttribute(this, "anonid", "tabbox"); @@ -120,11 +123,7 @@ new Map(); -#ifdef XP_MACOSX - true -#else - false -#endif + this.AppConstants.platform == "macosx"; @@ -2722,18 +2721,19 @@ -#ifdef E10S_TESTING_ONLY -#endif @@ -3094,14 +3094,14 @@ } } -#ifndef XP_MACOSX - if (aEvent.ctrlKey && !aEvent.shiftKey && !aEvent.metaKey && - aEvent.keyCode == KeyEvent.DOM_VK_F4 && - !this.mCurrentTab.pinned) { - this.removeCurrentTab({animate: true}); - aEvent.preventDefault(); + if (this.AppConstants.platform != "macosx") { + if (aEvent.ctrlKey && !aEvent.shiftKey && !aEvent.metaKey && + aEvent.keyCode == KeyEvent.DOM_VK_F4 && + !this.mCurrentTab.pinned) { + this.removeCurrentTab({animate: true}); + aEvent.preventDefault(); + } } -#endif ]]> @@ -3133,21 +3133,21 @@ } } -#ifdef XP_MACOSX - if (!aEvent.metaKey) - return; + if (this.AppConstants.platform == "macosx") { + if (!aEvent.metaKey) + return; - var offset = 1; - switch (aEvent.charCode) { - case '}'.charCodeAt(0): - offset = -1; - case '{'.charCodeAt(0): - if (window.getComputedStyle(this, null).direction == "ltr") - offset *= -1; - this.tabContainer.advanceSelectedTab(offset, true); - aEvent.preventDefault(); + var offset = 1; + switch (aEvent.charCode) { + case '}'.charCodeAt(0): + offset = -1; + case '{'.charCodeAt(0): + if (window.getComputedStyle(this, null).direction == "ltr") + offset *= -1; + this.tabContainer.advanceSelectedTab(offset, true); + aEvent.preventDefault(); + } } -#endif ]]> @@ -3755,15 +3755,16 @@ -# This is a hack to circumvent bug 472020, otherwise the tabs show up on the -# right of the newtab button. + -# This is to ensure anything extensions put here will go before the newtab -# button, necessary due to the previous hack. + diff --git a/browser/base/jar.mn b/browser/base/jar.mn index 00f0c8ab771..90a5295734e 100644 --- a/browser/base/jar.mn +++ b/browser/base/jar.mn @@ -141,7 +141,7 @@ browser.jar: content/browser/searchSuggestionUI.js (content/searchSuggestionUI.js) content/browser/searchSuggestionUI.css (content/searchSuggestionUI.css) content/browser/tabbrowser.css (content/tabbrowser.css) -* content/browser/tabbrowser.xml (content/tabbrowser.xml) + content/browser/tabbrowser.xml (content/tabbrowser.xml) * content/browser/urlbarBindings.xml (content/urlbarBindings.xml) * content/browser/utilityOverlay.js (content/utilityOverlay.js) content/browser/web-panels.js (content/web-panels.js) diff --git a/browser/components/downloads/DownloadsViewUI.jsm b/browser/components/downloads/DownloadsViewUI.jsm old mode 100755 new mode 100644 diff --git a/browser/components/downloads/content/downloads.js b/browser/components/downloads/content/downloads.js old mode 100755 new mode 100644 diff --git a/browser/components/loop/content/shared/libs/sdk.js b/browser/components/loop/content/shared/libs/sdk.js old mode 100755 new mode 100644 diff --git a/build/gen_mach_buildprops.py b/build/gen_mach_buildprops.py index 37ebbb4a721..4f33dc3af58 100644 --- a/build/gen_mach_buildprops.py +++ b/build/gen_mach_buildprops.py @@ -55,6 +55,7 @@ def getUrlProperties(filename): ('completeMarUrl', lambda m: m.endswith('.complete.mar')), ('partialMarUrl', lambda m: m.endswith('.mar') and '.partial.' in m), ('codeCoverageURL', lambda m: m.endswith('code-coverage-gcno.zip')), + ('sdkUrl', lambda m: m.endswith(('sdk.tar.bz2', 'sdk.zip'))), # packageUrl must be last! ('packageUrl', lambda m: True), ] diff --git a/build/macosx/mozconfig.common b/build/macosx/mozconfig.common index 37722f3062c..b0fac141c98 100644 --- a/build/macosx/mozconfig.common +++ b/build/macosx/mozconfig.common @@ -8,6 +8,7 @@ if [ "x$IS_NIGHTLY" = "xyes" ]; then # Some nightlies (eg: Mulet) don't want these set. MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-1} MOZ_AUTOMATION_UPDATE_PACKAGING=${MOZ_AUTOMATION_UPDATE_PACKAGING-1} + MOZ_AUTOMATION_SDK=${MOZ_AUTOMATION_SDK-1} fi . "$topsrcdir/build/mozconfig.common" diff --git a/build/mozconfig.win-common b/build/mozconfig.win-common index abcde186318..8b38f52e493 100644 --- a/build/mozconfig.win-common +++ b/build/mozconfig.win-common @@ -6,6 +6,7 @@ if [ "x$IS_NIGHTLY" = "xyes" ]; then # Some nightlies (eg: Mulet) don't want these set. MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-1} MOZ_AUTOMATION_UPDATE_PACKAGING=${MOZ_AUTOMATION_UPDATE_PACKAGING-1} + MOZ_AUTOMATION_SDK=${MOZ_AUTOMATION_SDK-1} fi # Some builds (eg: Mulet) don't want the installer, so only set this if it diff --git a/build/unix/mozconfig.linux b/build/unix/mozconfig.linux index 841af1e7bb4..30f4a556f9b 100644 --- a/build/unix/mozconfig.linux +++ b/build/unix/mozconfig.linux @@ -2,6 +2,7 @@ if [ "x$IS_NIGHTLY" = "xyes" ]; then # Some nightlies (eg: Mulet) don't want these set. MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-1} MOZ_AUTOMATION_UPDATE_PACKAGING=${MOZ_AUTOMATION_UPDATE_PACKAGING-1} + MOZ_AUTOMATION_SDK=${MOZ_AUTOMATION_SDK-1} fi . "$topsrcdir/build/mozconfig.common" diff --git a/configure.in b/configure.in index 2b298f3d92c..a877bfc29ea 100644 --- a/configure.in +++ b/configure.in @@ -3629,7 +3629,7 @@ MOZ_ARG_WITH_BOOL(system-nss, _USE_SYSTEM_NSS=1 ) if test -n "$_USE_SYSTEM_NSS"; then - AM_PATH_NSS(3.17.4, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])]) + AM_PATH_NSS(3.18, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])]) fi if test -n "$MOZ_NATIVE_NSS"; then diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index e677fb915b2..cc6fcefd753 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -859,6 +859,7 @@ nsDocShell::nsDocShell() , mAllowDNSPrefetch(true) , mAllowWindowControl(true) , mAllowContentRetargeting(true) + , mAllowContentRetargetingOnChildren(true) , mCreatingDocument(false) , mUseErrorPages(false) , mObserveErrorPages(true) @@ -2587,10 +2588,25 @@ nsDocShell::GetAllowContentRetargeting(bool* aAllowContentRetargeting) NS_IMETHODIMP nsDocShell::SetAllowContentRetargeting(bool aAllowContentRetargeting) { + mAllowContentRetargetingOnChildren = aAllowContentRetargeting; mAllowContentRetargeting = aAllowContentRetargeting; return NS_OK; } +NS_IMETHODIMP +nsDocShell::GetAllowContentRetargetingOnChildren(bool* aAllowContentRetargetingOnChildren) +{ + *aAllowContentRetargetingOnChildren = mAllowContentRetargetingOnChildren; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::SetAllowContentRetargetingOnChildren(bool aAllowContentRetargetingOnChildren) +{ + mAllowContentRetargetingOnChildren = aAllowContentRetargetingOnChildren; + return NS_OK; +} + NS_IMETHODIMP nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed) { @@ -3461,7 +3477,7 @@ nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) if (NS_SUCCEEDED(parentAsDocShell->GetAllowWindowControl(&value))) { SetAllowWindowControl(value); } - SetAllowContentRetargeting(parentAsDocShell->GetAllowContentRetargeting()); + SetAllowContentRetargeting(parentAsDocShell->GetAllowContentRetargetingOnChildren()); if (NS_SUCCEEDED(parentAsDocShell->GetIsActive(&value))) { SetIsActive(value); } @@ -8738,6 +8754,7 @@ nsDocShell::RestoreFromHistory() childShell->GetAllowDNSPrefetch(&allowDNSPrefetch); bool allowContentRetargeting = childShell->GetAllowContentRetargeting(); + bool allowContentRetargetingOnChildren = childShell->GetAllowContentRetargetingOnChildren(); uint32_t defaultLoadFlags; childShell->GetDefaultLoadFlags(&defaultLoadFlags); @@ -8756,6 +8773,7 @@ nsDocShell::RestoreFromHistory() childShell->SetAllowMedia(allowMedia); childShell->SetAllowDNSPrefetch(allowDNSPrefetch); childShell->SetAllowContentRetargeting(allowContentRetargeting); + childShell->SetAllowContentRetargetingOnChildren(allowContentRetargetingOnChildren); childShell->SetDefaultLoadFlags(defaultLoadFlags); rv = childShell->BeginRestore(nullptr, false); diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 44d192bb2be..15b5954fb04 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -883,6 +883,7 @@ protected: bool mAllowDNSPrefetch; bool mAllowWindowControl; bool mAllowContentRetargeting; + bool mAllowContentRetargetingOnChildren; bool mCreatingDocument; // (should be) debugging only bool mUseErrorPages; bool mObserveErrorPages; diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index 5b100f25e7f..b247a232dc3 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -54,7 +54,7 @@ interface nsITabParent; typedef unsigned long nsLoadFlags; -[scriptable, builtinclass, uuid(f84b1ae4-2f78-4bad-b36a-6a8516ee6e40)] +[scriptable, builtinclass, uuid(68ba7610-e33d-47ce-8fa2-af07af2422bc)] interface nsIDocShell : nsIDocShellTreeItem { /** @@ -289,6 +289,12 @@ interface nsIDocShell : nsIDocShellTreeItem */ [infallible] attribute boolean allowContentRetargeting; + /** + * True if new child docshells should allow content retargeting. + * Setting allowContentRetargeting also overwrites this value. + */ + [infallible] attribute boolean allowContentRetargetingOnChildren; + /** * Get an enumerator over this docShell and its children. * diff --git a/dom/animation/Animation.cpp b/dom/animation/Animation.cpp index 5916f838ef5..458c7496270 100644 --- a/dom/animation/Animation.cpp +++ b/dom/animation/Animation.cpp @@ -252,16 +252,16 @@ Animation::IsInEffect() const return computedTiming.mTimeFraction != ComputedTiming::kNullTimeFraction; } -bool -Animation::HasAnimationOfProperty(nsCSSProperty aProperty) const +const AnimationProperty* +Animation::GetAnimationOfProperty(nsCSSProperty aProperty) const { for (size_t propIdx = 0, propEnd = mProperties.Length(); propIdx != propEnd; ++propIdx) { if (aProperty == mProperties[propIdx].mProperty) { - return true; + return &mProperties[propIdx]; } } - return false; + return nullptr; } void @@ -297,6 +297,16 @@ Animation::ComposeStyle(nsRefPtr& aStyleRule, continue; } + if (!prop.mWinsInCascade) { + // This isn't the winning declaration, so don't add it to style. + // For transitions, this is important, because it's how we + // implement the rule that CSS transitions don't run when a CSS + // animation is running on the same property and element. For + // animations, this is only skipping things that will otherwise be + // overridden. + continue; + } + aSetProperties.AddProperty(prop.mProperty); MOZ_ASSERT(prop.mSegments.Length() > 0, diff --git a/dom/animation/Animation.h b/dom/animation/Animation.h index 3e38b8ae23d..b6c60738c7b 100644 --- a/dom/animation/Animation.h +++ b/dom/animation/Animation.h @@ -150,10 +150,25 @@ struct AnimationPropertySegment struct AnimationProperty { nsCSSProperty mProperty; + + // Does this property win in the CSS Cascade? + // + // For CSS transitions, this is true as long as a CSS animation on the + // same property and element is not running, in which case we set this + // to false so that the animation (lower in the cascade) can win. We + // then use this to decide whether to apply the style both in the CSS + // cascade and for OMTA. + // + // FIXME (bug 847287): For CSS Animations, which are overridden by + // !important rules in the cascade, we actually determine this from + // the CSS cascade computations, and then use it for OMTA. + bool mWinsInCascade; + InfallibleTArray mSegments; bool operator==(const AnimationProperty& aOther) const { return mProperty == aOther.mProperty && + mWinsInCascade == aOther.mWinsInCascade && mSegments == aOther.mSegments; } bool operator!=(const AnimationProperty& aOther) const { @@ -290,7 +305,11 @@ public: bool IsCurrent() const; bool IsInEffect() const; - bool HasAnimationOfProperty(nsCSSProperty aProperty) const; + const AnimationProperty* + GetAnimationOfProperty(nsCSSProperty aProperty) const; + bool HasAnimationOfProperty(nsCSSProperty aProperty) const { + return GetAnimationOfProperty(aProperty) != nullptr; + } const InfallibleTArray& Properties() const { return mProperties; } diff --git a/dom/animation/AnimationPlayer.cpp b/dom/animation/AnimationPlayer.cpp index a9166819d65..33b0f64c4ef 100644 --- a/dom/animation/AnimationPlayer.cpp +++ b/dom/animation/AnimationPlayer.cpp @@ -54,10 +54,9 @@ AnimationPlayer::SetStartTime(const Nullable& aNewStartTime) Nullable previousCurrentTime = GetCurrentTime(); mStartTime = aNewStartTime; if (!aNewStartTime.IsNull()) { - // Until bug 1127380 (playbackRate) is implemented, the rate is essentially - // one. Once that bug is fixed we should only SetNull() if the rate is not - // zero. - mHoldTime.SetNull(); + if (mPlaybackRate != 0.0) { + mHoldTime.SetNull(); + } } else { mHoldTime = previousCurrentTime; } @@ -89,7 +88,8 @@ AnimationPlayer::GetCurrentTime() const if (!mStartTime.IsNull()) { Nullable timelineTime = mTimeline->GetCurrentTime(); if (!timelineTime.IsNull()) { - result.SetValue(timelineTime.Value() - mStartTime.Value()); + result.SetValue((timelineTime.Value() - mStartTime.Value()) + .MultDouble(mPlaybackRate)); } } return result; @@ -101,15 +101,16 @@ AnimationPlayer::SilentlySetCurrentTime(const TimeDuration& aSeekTime) { if (!mHoldTime.IsNull() || !mTimeline || - mTimeline->GetCurrentTime().IsNull() - /*or, once supported, playback rate is 0, or have pending pause task*/) { + mTimeline->GetCurrentTime().IsNull() || + mPlaybackRate == 0.0 + /*or, once supported, if we have a pending pause task*/) { mHoldTime.SetValue(aSeekTime); if (!mTimeline || mTimeline->GetCurrentTime().IsNull()) { mStartTime.SetNull(); } } else { - // once playback rate is supported, need to account for that here - mStartTime.SetValue(mTimeline->GetCurrentTime().Value() - aSeekTime); + mStartTime.SetValue(mTimeline->GetCurrentTime().Value() - + (aSeekTime / mPlaybackRate)); } // Once AnimationPlayers store a previous current time, set that to @@ -132,6 +133,30 @@ AnimationPlayer::SetCurrentTime(const TimeDuration& aSeekTime) // http://w3c.github.io/web-animations/#update-a-players-finished-state } +void +AnimationPlayer::SetPlaybackRate(double aPlaybackRate) +{ + Nullable previousTime = GetCurrentTime(); + mPlaybackRate = aPlaybackRate; + if (!previousTime.IsNull()) { + ErrorResult rv; + SetCurrentTime(previousTime.Value()); + MOZ_ASSERT(!rv.Failed(), "Should not assert for non-null time"); + } +} + +void +AnimationPlayer::SilentlySetPlaybackRate(double aPlaybackRate) +{ + Nullable previousTime = GetCurrentTime(); + mPlaybackRate = aPlaybackRate; + if (!previousTime.IsNull()) { + ErrorResult rv; + SilentlySetCurrentTime(previousTime.Value()); + MOZ_ASSERT(!rv.Failed(), "Should not assert for non-null time"); + } +} + AnimationPlayState AnimationPlayer::PlayState() const { @@ -148,7 +173,8 @@ AnimationPlayer::PlayState() const return AnimationPlayState::Paused; } - if (currentTime.Value() >= SourceContentEnd()) { + if ((mPlaybackRate > 0.0 && currentTime.Value() >= SourceContentEnd()) || + (mPlaybackRate < 0.0 && currentTime.Value().ToMilliseconds() <= 0.0)) { return AnimationPlayState::Finished; } @@ -399,10 +425,17 @@ AnimationPlayer::DoPlay() // animation-play-state we *don't* trigger finishing behavior. Nullable currentTime = GetCurrentTime(); - if (currentTime.IsNull()) { + if (mPlaybackRate > 0.0 && + (currentTime.IsNull())) { mHoldTime.SetValue(TimeDuration(0)); - } else if (mHoldTime.IsNull()) { - // If the hold time is null, we are already playing normally + } else if (mPlaybackRate < 0.0 && + (currentTime.IsNull())) { + mHoldTime.SetValue(TimeDuration(SourceContentEnd())); + } else if (mPlaybackRate == 0.0 && currentTime.IsNull()) { + mHoldTime.SetValue(TimeDuration(0)); + } + + if (mHoldTime.IsNull()) { return; } @@ -460,8 +493,12 @@ AnimationPlayer::ResumeAt(const TimeDuration& aResumeTime) MOZ_ASSERT(!mHoldTime.IsNull(), "A player in the pending state should have a resolved hold time"); - mStartTime.SetValue(aResumeTime - mHoldTime.Value()); - mHoldTime.SetNull(); + if (mPlaybackRate != 0) { + mStartTime.SetValue(aResumeTime - (mHoldTime.Value() / mPlaybackRate)); + mHoldTime.SetNull(); + } else { + mStartTime.SetValue(aResumeTime); + } mIsPending = false; UpdateSourceContent(); diff --git a/dom/animation/AnimationPlayer.h b/dom/animation/AnimationPlayer.h index 09e680ebdc7..97e9a995f21 100644 --- a/dom/animation/AnimationPlayer.h +++ b/dom/animation/AnimationPlayer.h @@ -53,6 +53,7 @@ protected: public: explicit AnimationPlayer(AnimationTimeline* aTimeline) : mTimeline(aTimeline) + , mPlaybackRate(1.0) , mIsPending(false) , mIsRunningOnCompositor(false) , mIsPreviousStateFinished(false) @@ -77,6 +78,9 @@ public: Nullable GetCurrentTime() const; void SilentlySetCurrentTime(const TimeDuration& aNewCurrentTime); void SetCurrentTime(const TimeDuration& aNewCurrentTime); + double PlaybackRate() const { return mPlaybackRate; } + void SetPlaybackRate(double aPlaybackRate); + void SilentlySetPlaybackRate(double aPlaybackRate); AnimationPlayState PlayState() const; virtual Promise* GetReady(ErrorResult& aRv); virtual void Play(); @@ -241,6 +245,7 @@ protected: Nullable mStartTime; // Timeline timescale Nullable mHoldTime; // Player timescale Nullable mPendingReadyTime; // Timeline timescale + double mPlaybackRate; // A Promise that is replaced on each call to Play() (and in future Pause()) // and fulfilled when Play() is successfully completed. diff --git a/dom/apps/AppsUtils.jsm b/dom/apps/AppsUtils.jsm index b2983167691..8374b1396ec 100644 --- a/dom/apps/AppsUtils.jsm +++ b/dom/apps/AppsUtils.jsm @@ -785,7 +785,7 @@ this.AppsUtils = { /** * Helper object to access manifest information with locale support */ -this.ManifestHelper = function(aManifest, aOrigin, aManifestURL) { +this.ManifestHelper = function(aManifest, aOrigin, aManifestURL, aLang) { // If the app is packaged, we resolve uris against the origin. // If it's not, against the manifest url. @@ -801,10 +801,15 @@ this.ManifestHelper = function(aManifest, aOrigin, aManifestURL) { this._manifestURL = Services.io.newURI(aManifestURL, null, null); this._manifest = aManifest; - let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"] - .getService(Ci.nsIXULChromeRegistry) - .QueryInterface(Ci.nsIToolkitChromeRegistry); - let locale = chrome.getSelectedLocale("global").toLowerCase(); + + let locale = aLang; + if (!locale) { + let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"] + .getService(Ci.nsIXULChromeRegistry) + .QueryInterface(Ci.nsIToolkitChromeRegistry); + locale = chrome.getSelectedLocale("global").toLowerCase(); + } + this._localeRoot = this._manifest; if (this._manifest.locales && this._manifest.locales[locale]) { diff --git a/dom/apps/Langpacks.jsm b/dom/apps/Langpacks.jsm index b2e1769163c..c3dfd4aa567 100644 --- a/dom/apps/Langpacks.jsm +++ b/dom/apps/Langpacks.jsm @@ -245,7 +245,7 @@ this.Langpacks = { // We need to get the app with the manifest since the version is only // available in the manifest. - this._appFromManifestURL(aData.manifestURL, aData.entryPoint) + this._appFromManifestURL(aData.manifestURL, aData.entryPoint, aData.lang) .then(aApp => { let manifest = aApp.manifest; diff --git a/dom/apps/Webapps.jsm b/dom/apps/Webapps.jsm old mode 100755 new mode 100644 index 022f468f15b..8682d897f20 --- a/dom/apps/Webapps.jsm +++ b/dom/apps/Webapps.jsm @@ -4674,7 +4674,7 @@ this.DOMApplicationRegistry = { }, // Returns a promise that resolves to the app object with the manifest. - getFullAppByManifestURL: function(aManifestURL, aEntryPoint) { + getFullAppByManifestURL: function(aManifestURL, aEntryPoint, aLang) { let app = this.getAppByManifestURL(aManifestURL); if (!app) { return Promise.reject("NoSuchApp"); @@ -4692,7 +4692,8 @@ this.DOMApplicationRegistry = { manifest.version = aManifest.version; } - app.manifest = new ManifestHelper(manifest, app.origin, app.manifestURL); + app.manifest = + new ManifestHelper(manifest, app.origin, app.manifestURL, aLang); return app; }); }, diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 87306a3de38..de6d09ed1d9 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -408,28 +408,43 @@ Element::GetBindingURL(nsIDocument *aDocument, css::URLValue **aResult) JSObject* Element::WrapObject(JSContext *aCx, JS::Handle aGivenProto) { - JS::Rooted obj(aCx, nsINode::WrapObject(aCx, aGivenProto)); + JS::Rooted givenProto(aCx, aGivenProto); + JS::Rooted customProto(aCx); + + if (!givenProto) { + // Custom element prototype swizzling. + CustomElementData* data = GetCustomElementData(); + if (data) { + // If this is a registered custom element then fix the prototype. + nsDocument* document = static_cast(OwnerDoc()); + document->GetCustomPrototype(NodeInfo()->NamespaceID(), data->mType, &customProto); + if (customProto && + NodePrincipal()->SubsumesConsideringDomain(nsContentUtils::ObjectPrincipal(customProto))) { + // Just go ahead and create with the right proto up front. Set + // customProto to null to flag that we don't need to do any post-facto + // proto fixups here. + givenProto = customProto; + customProto = nullptr; + } + } + } + + JS::Rooted obj(aCx, nsINode::WrapObject(aCx, givenProto)); if (!obj) { return nullptr; } - // Custom element prototype swizzling. - CustomElementData* data = GetCustomElementData(); - if (obj && data) { - // If this is a registered custom element then fix the prototype. - nsDocument* document = static_cast(OwnerDoc()); - JS::Rooted prototype(aCx); - document->GetCustomPrototype(NodeInfo()->NamespaceID(), data->mType, &prototype); - if (prototype) { - // We want to set the custom prototype in the compartment where it was - // registered. In the case that |obj| and |prototype| are in different - // compartments, this will set the prototype on the |obj|'s wrapper and - // thus only visible in the wrapper's compartment. - JSAutoCompartment ac(aCx, prototype); - if (!JS_WrapObject(aCx, &obj) || !JS_SetPrototype(aCx, obj, prototype)) { - dom::Throw(aCx, NS_ERROR_FAILURE); - return nullptr; - } + if (customProto) { + // We want to set the custom prototype in the compartment where it was + // registered. In the case that |obj| and |prototype| are in different + // compartments, this will set the prototype on the |obj|'s wrapper and + // thus only visible in the wrapper's compartment, since we know obj's + // principal does not subsume customProto's in this case. + JSAutoCompartment ac(aCx, customProto); + JS::Rooted wrappedObj(aCx, obj); + if (!JS_WrapObject(aCx, &wrappedObj) || + !JS_SetPrototype(aCx, wrappedObj, customProto)) { + return nullptr; } } diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index 1bfd69e5615..70f78c63c6a 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -1982,8 +1982,8 @@ Navigator::OnNavigation() } #ifdef MOZ_MEDIA_NAVIGATOR - // Inform MediaManager in case there are live streams or pending callbacks. - MediaManager *manager = MediaManager::Get(); + // If MediaManager is open let it inform any live streams or pending callbacks + MediaManager *manager = MediaManager::GetIfExists(); if (manager) { manager->OnNavigation(mWindow->WindowID()); } diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp index bee88842a9d..c5cc5d37d06 100644 --- a/dom/base/nsFrameMessageManager.cpp +++ b/dom/base/nsFrameMessageManager.cpp @@ -1557,7 +1557,7 @@ nsMessageManagerScriptExecutor::LoadScriptInternal(const nsAString& aURL, JSContext* cx = aes.cx(); if (script) { if (aRunInGlobalScope) { - JS::CloneAndExecuteScript(cx, global, script); + JS::CloneAndExecuteScript(cx, script); } else { JS::Rooted scope(cx); bool ok = js::ExecuteInGlobalAndReturnScope(cx, global, script, &scope); @@ -1644,8 +1644,9 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript( return; } } else { - // We can't clone compile-and-go scripts. - options.setCompileAndGo(false); + // We're going to run these against some non-global scope. + options.setCompileAndGo(false) + .setHasPollutedScope(true); if (!JS::Compile(cx, options, srcBuf, &script)) { return; } diff --git a/dom/cache/CacheStreamControlChild.cpp b/dom/cache/CacheStreamControlChild.cpp index c0cd043378d..f5a34ecc99e 100644 --- a/dom/cache/CacheStreamControlChild.cpp +++ b/dom/cache/CacheStreamControlChild.cpp @@ -9,13 +9,22 @@ #include "mozilla/DebugOnly.h" #include "mozilla/unused.h" #include "mozilla/dom/cache/ActorUtils.h" +#include "mozilla/dom/cache/PCacheTypes.h" #include "mozilla/dom/cache/ReadStream.h" +#include "mozilla/ipc/FileDescriptorSetChild.h" +#include "mozilla/ipc/PBackgroundChild.h" +#include "mozilla/ipc/PFileDescriptorSetChild.h" #include "nsISupportsImpl.h" namespace mozilla { namespace dom { namespace cache { +using mozilla::ipc::FileDescriptor; +using mozilla::ipc::FileDescriptorSetChild; +using mozilla::ipc::OptionalFileDescriptorSet; +using mozilla::ipc::PFileDescriptorSetChild; + // declared in ActorUtils.h PCacheStreamControlChild* AllocPCacheStreamControlChild() @@ -42,30 +51,6 @@ CacheStreamControlChild::~CacheStreamControlChild() MOZ_COUNT_DTOR(cache::CacheStreamControlChild); } -void -CacheStreamControlChild::AddListener(ReadStream* aListener) -{ - NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild); - MOZ_ASSERT(aListener); - MOZ_ASSERT(!mListeners.Contains(aListener)); - mListeners.AppendElement(aListener); -} - -void -CacheStreamControlChild::RemoveListener(ReadStream* aListener) -{ - NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild); - MOZ_ASSERT(aListener); - MOZ_ALWAYS_TRUE(mListeners.RemoveElement(aListener)); -} - -void -CacheStreamControlChild::NoteClosed(const nsID& aId) -{ - NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild); - unused << SendNoteClosed(aId); -} - void CacheStreamControlChild::StartDestroy() { @@ -83,19 +68,73 @@ CacheStreamControlChild::StartDestroy() RecvCloseAll(); } +void +CacheStreamControlChild::SerializeControl(PCacheReadStream* aReadStreamOut) +{ + NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild); + aReadStreamOut->controlParent() = nullptr; + aReadStreamOut->controlChild() = this; +} + +void +CacheStreamControlChild::SerializeFds(PCacheReadStream* aReadStreamOut, + const nsTArray& aFds) +{ + NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild); + PFileDescriptorSetChild* fdSet = nullptr; + if (!aFds.IsEmpty()) { + fdSet = Manager()->SendPFileDescriptorSetConstructor(aFds[0]); + for (uint32_t i = 1; i < aFds.Length(); ++i) { + unused << fdSet->SendAddFileDescriptor(aFds[i]); + } + } + + if (fdSet) { + aReadStreamOut->fds() = fdSet; + } else { + aReadStreamOut->fds() = void_t(); + } +} + +void +CacheStreamControlChild::DeserializeFds(const PCacheReadStream& aReadStream, + nsTArray& aFdsOut) +{ + if (aReadStream.fds().type() != + OptionalFileDescriptorSet::TPFileDescriptorSetChild) { + return; + } + + auto fdSetActor = static_cast( + aReadStream.fds().get_PFileDescriptorSetChild()); + MOZ_ASSERT(fdSetActor); + + fdSetActor->ForgetFileDescriptors(aFdsOut); + MOZ_ASSERT(!aFdsOut.IsEmpty()); + + unused << fdSetActor->Send__delete__(fdSetActor); +} + +void +CacheStreamControlChild::NoteClosedAfterForget(const nsID& aId) +{ + NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild); + unused << SendNoteClosed(aId); +} + +#ifdef DEBUG +void +CacheStreamControlChild::AssertOwningThread() +{ + NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild); +} +#endif + void CacheStreamControlChild::ActorDestroy(ActorDestroyReason aReason) { NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild); - // Note, we cannot trigger IPC traffic here. So use - // CloseStreamWithoutReporting(). - ReadStreamList::ForwardIterator iter(mListeners); - while (iter.HasMore()) { - nsRefPtr stream = iter.GetNext(); - stream->CloseStreamWithoutReporting(); - } - mListeners.Clear(); - + CloseAllReadStreamsWithoutReporting(); RemoveFeature(); } @@ -103,20 +142,7 @@ bool CacheStreamControlChild::RecvClose(const nsID& aId) { NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild); - DebugOnly closedCount = 0; - - ReadStreamList::ForwardIterator iter(mListeners); - while (iter.HasMore()) { - nsRefPtr stream = iter.GetNext(); - // note, multiple streams may exist for same ID - if (stream->MatchId(aId)) { - stream->CloseStream(); - closedCount += 1; - } - } - - MOZ_ASSERT(closedCount > 0); - + CloseReadStreams(aId); return true; } @@ -124,11 +150,7 @@ bool CacheStreamControlChild::RecvCloseAll() { NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild); - ReadStreamList::ForwardIterator iter(mListeners); - while (iter.HasMore()) { - nsRefPtr stream = iter.GetNext(); - stream->CloseStream(); - } + CloseAllReadStreams(); return true; } diff --git a/dom/cache/CacheStreamControlChild.h b/dom/cache/CacheStreamControlChild.h index 63efdc1b790..d8cec5a2153 100644 --- a/dom/cache/CacheStreamControlChild.h +++ b/dom/cache/CacheStreamControlChild.h @@ -9,6 +9,7 @@ #include "mozilla/dom/cache/ActorChild.h" #include "mozilla/dom/cache/PCacheStreamControlChild.h" +#include "mozilla/dom/cache/StreamControl.h" #include "nsTObserverArray.h" namespace mozilla { @@ -18,29 +19,42 @@ namespace cache { class ReadStream; class CacheStreamControlChild MOZ_FINAL : public PCacheStreamControlChild + , public StreamControl , public ActorChild { public: CacheStreamControlChild(); ~CacheStreamControlChild(); - void AddListener(ReadStream* aListener); - void RemoveListener(ReadStream* aListener); - - void NoteClosed(const nsID& aId); - // ActorChild methods virtual void StartDestroy() MOZ_OVERRIDE; + // StreamControl methods + virtual void + SerializeControl(PCacheReadStream* aReadStreamOut) MOZ_OVERRIDE; + + virtual void + SerializeFds(PCacheReadStream* aReadStreamOut, + const nsTArray& aFds) MOZ_OVERRIDE; + + virtual void + DeserializeFds(const PCacheReadStream& aReadStream, + nsTArray& aFdsOut) MOZ_OVERRIDE; + private: + virtual void + NoteClosedAfterForget(const nsID& aId) MOZ_OVERRIDE; + +#ifdef DEBUG + virtual void + AssertOwningThread() MOZ_OVERRIDE; +#endif + // PCacheStreamControlChild methods virtual void ActorDestroy(ActorDestroyReason aReason) MOZ_OVERRIDE; virtual bool RecvClose(const nsID& aId) MOZ_OVERRIDE; virtual bool RecvCloseAll() MOZ_OVERRIDE; - typedef nsTObserverArray ReadStreamList; - ReadStreamList mListeners; - bool mDestroyStarted; NS_DECL_OWNINGTHREAD diff --git a/dom/cache/CacheStreamControlParent.cpp b/dom/cache/CacheStreamControlParent.cpp index e39790e43c3..4e4e4c5aa09 100644 --- a/dom/cache/CacheStreamControlParent.cpp +++ b/dom/cache/CacheStreamControlParent.cpp @@ -8,14 +8,23 @@ #include "mozilla/DebugOnly.h" #include "mozilla/unused.h" +#include "mozilla/dom/cache/PCacheTypes.h" #include "mozilla/dom/cache/ReadStream.h" #include "mozilla/dom/cache/StreamList.h" +#include "mozilla/ipc/FileDescriptorSetParent.h" +#include "mozilla/ipc/PBackgroundParent.h" +#include "mozilla/ipc/PFileDescriptorSetParent.h" #include "nsISupportsImpl.h" namespace mozilla { namespace dom { namespace cache { +using mozilla::ipc::FileDescriptor; +using mozilla::ipc::FileDescriptorSetParent; +using mozilla::ipc::OptionalFileDescriptorSet; +using mozilla::ipc::PFileDescriptorSetParent; + // declared in ActorUtils.h void DeallocPCacheStreamControlParent(PCacheStreamControlParent* aActor) @@ -36,33 +45,75 @@ CacheStreamControlParent::~CacheStreamControlParent() } void -CacheStreamControlParent::AddListener(ReadStream* aListener) +CacheStreamControlParent::SerializeControl(PCacheReadStream* aReadStreamOut) { NS_ASSERT_OWNINGTHREAD(CacheStreamControlParent); - MOZ_ASSERT(aListener); - MOZ_ASSERT(!mListeners.Contains(aListener)); - mListeners.AppendElement(aListener); + aReadStreamOut->controlChild() = nullptr; + aReadStreamOut->controlParent() = this; } void -CacheStreamControlParent::RemoveListener(ReadStream* aListener) +CacheStreamControlParent::SerializeFds(PCacheReadStream* aReadStreamOut, + const nsTArray& aFds) { NS_ASSERT_OWNINGTHREAD(CacheStreamControlParent); - MOZ_ASSERT(aListener); - DebugOnly removed = mListeners.RemoveElement(aListener); - MOZ_ASSERT(removed); + PFileDescriptorSetParent* fdSet = nullptr; + if (!aFds.IsEmpty()) { + fdSet = Manager()->SendPFileDescriptorSetConstructor(aFds[0]); + for (uint32_t i = 1; i < aFds.Length(); ++i) { + unused << fdSet->SendAddFileDescriptor(aFds[i]); + } + } + + if (fdSet) { + aReadStreamOut->fds() = fdSet; + } else { + aReadStreamOut->fds() = void_t(); + } } +void +CacheStreamControlParent::DeserializeFds(const PCacheReadStream& aReadStream, + nsTArray& aFdsOut) +{ + if (aReadStream.fds().type() != + OptionalFileDescriptorSet::TPFileDescriptorSetParent) { + return; + } + + FileDescriptorSetParent* fdSetActor = + static_cast(aReadStream.fds().get_PFileDescriptorSetParent()); + MOZ_ASSERT(fdSetActor); + + fdSetActor->ForgetFileDescriptors(aFdsOut); + MOZ_ASSERT(!aFdsOut.IsEmpty()); + + if (!fdSetActor->Send__delete__(fdSetActor)) { + // child process is gone, warn and allow actor to clean up normally + NS_WARNING("Cache failed to delete fd set actor."); + } +} + +void +CacheStreamControlParent::NoteClosedAfterForget(const nsID& aId) +{ + NS_ASSERT_OWNINGTHREAD(CacheStreamControlParent); + RecvNoteClosed(aId); +} + +#ifdef DEBUG +void +CacheStreamControlParent::AssertOwningThread() +{ + NS_ASSERT_OWNINGTHREAD(CacheStreamControlParent); +} +#endif + void CacheStreamControlParent::ActorDestroy(ActorDestroyReason aReason) { NS_ASSERT_OWNINGTHREAD(CacheStreamControlParent); - MOZ_ASSERT(mStreamList); - ReadStreamList::ForwardIterator iter(mListeners); - while (iter.HasMore()) { - nsRefPtr stream = iter.GetNext(); - stream->CloseStreamWithoutReporting(); - } + CloseAllReadStreamsWithoutReporting(); mStreamList->RemoveStreamControl(this); mStreamList->NoteClosedAll(); mStreamList = nullptr; @@ -116,30 +167,14 @@ void CacheStreamControlParent::NotifyClose(const nsID& aId) { NS_ASSERT_OWNINGTHREAD(CacheStreamControlParent); - DebugOnly closedCount = 0; - - ReadStreamList::ForwardIterator iter(mListeners); - while (iter.HasMore()) { - nsRefPtr stream = iter.GetNext(); - // note, multiple streams may exist for same ID - if (stream->MatchId(aId)) { - stream->CloseStream(); - closedCount += 1; - } - } - - MOZ_ASSERT(closedCount > 0); + CloseReadStreams(aId); } void CacheStreamControlParent::NotifyCloseAll() { NS_ASSERT_OWNINGTHREAD(CacheStreamControlParent); - ReadStreamList::ForwardIterator iter(mListeners); - while (iter.HasMore()) { - nsRefPtr stream = iter.GetNext(); - stream->CloseStream(); - } + CloseAllReadStreams(); } } // namespace cache diff --git a/dom/cache/CacheStreamControlParent.h b/dom/cache/CacheStreamControlParent.h index b45992b86c6..2f4868fd30d 100644 --- a/dom/cache/CacheStreamControlParent.h +++ b/dom/cache/CacheStreamControlParent.h @@ -8,6 +8,7 @@ #define mozilla_dom_cache_CacheStreamControlParent_h #include "mozilla/dom/cache/PCacheStreamControlParent.h" +#include "mozilla/dom/cache/StreamControl.h" #include "nsTObserverArray.h" namespace mozilla { @@ -18,24 +19,42 @@ class ReadStream; class StreamList; class CacheStreamControlParent : public PCacheStreamControlParent + , public StreamControl { public: CacheStreamControlParent(); ~CacheStreamControlParent(); - void AddListener(ReadStream* aListener); - void RemoveListener(ReadStream* aListener); - void SetStreamList(StreamList* aStreamList); void Close(const nsID& aId); void CloseAll(); void Shutdown(); + // StreamControl methods + virtual void + SerializeControl(PCacheReadStream* aReadStreamOut) MOZ_OVERRIDE; + + virtual void + SerializeFds(PCacheReadStream* aReadStreamOut, + const nsTArray& aFds) MOZ_OVERRIDE; + + virtual void + DeserializeFds(const PCacheReadStream& aReadStream, + nsTArray& aFdsOut) MOZ_OVERRIDE; + +private: + virtual void + NoteClosedAfterForget(const nsID& aId) MOZ_OVERRIDE; + +#ifdef DEBUG + virtual void + AssertOwningThread() MOZ_OVERRIDE; +#endif + // PCacheStreamControlParent methods virtual void ActorDestroy(ActorDestroyReason aReason) MOZ_OVERRIDE; virtual bool RecvNoteClosed(const nsID& aId) MOZ_OVERRIDE; -private: void NotifyClose(const nsID& aId); void NotifyCloseAll(); @@ -44,9 +63,6 @@ private: // StreamList::RemoveStreamControl() to clear the weak ref. nsRefPtr mStreamList; - typedef nsTObserverArray ReadStreamList; - ReadStreamList mListeners; - NS_DECL_OWNINGTHREAD }; diff --git a/dom/cache/ReadStream.cpp b/dom/cache/ReadStream.cpp index 2dec48d8c63..75a37b851bb 100644 --- a/dom/cache/ReadStream.cpp +++ b/dom/cache/ReadStream.cpp @@ -9,234 +9,121 @@ #include "mozilla/unused.h" #include "mozilla/dom/cache/CacheStreamControlChild.h" #include "mozilla/dom/cache/CacheStreamControlParent.h" -#include "mozilla/dom/cache/PCacheStreamControlChild.h" -#include "mozilla/dom/cache/PCacheStreamControlParent.h" #include "mozilla/dom/cache/PCacheTypes.h" #include "mozilla/ipc/FileDescriptor.h" -#include "mozilla/ipc/FileDescriptorSetChild.h" -#include "mozilla/ipc/FileDescriptorSetParent.h" -#include "mozilla/ipc/InputStreamParams.h" #include "mozilla/ipc/InputStreamUtils.h" -#include "mozilla/ipc/PBackgroundChild.h" -#include "mozilla/ipc/PBackgroundParent.h" -#include "mozilla/ipc/PFileDescriptorSetChild.h" -#include "mozilla/ipc/PFileDescriptorSetParent.h" #include "mozilla/SnappyUncompressInputStream.h" #include "nsIAsyncInputStream.h" #include "nsTArray.h" -namespace { - -using mozilla::unused; -using mozilla::void_t; -using mozilla::dom::cache::CacheStreamControlChild; -using mozilla::dom::cache::CacheStreamControlParent; -using mozilla::dom::cache::PCacheReadStream; -using mozilla::dom::cache::PCacheStreamControlChild; -using mozilla::dom::cache::PCacheStreamControlParent; -using mozilla::dom::cache::ReadStream; -using mozilla::ipc::FileDescriptor; -using mozilla::ipc::PFileDescriptorSetChild; -using mozilla::ipc::PFileDescriptorSetParent; - -// There are separate concrete implementations of ReadStream for the child -// and parent processes. This is unfortunately necessary because the -// actor types are distinct for these two cases. Also, the interface for -// reporting the close event differs slightly for the child and parent -// StreamControl actors. - -// ---------------------------------------------------------------------------- - -class ReadStreamChild MOZ_FINAL : public ReadStream -{ -public: - ReadStreamChild(PCacheStreamControlChild* aControl, const nsID& aId, - nsIInputStream* aStream) - : ReadStream(aId, aStream) - , mControl(static_cast(aControl)) - { - MOZ_ASSERT(mControl); - mControl->AddListener(this); - } - - virtual ~ReadStreamChild() - { - NS_ASSERT_OWNINGTHREAD(ReadStream); - - NoteClosed(); - } - - virtual void NoteClosedOnOwningThread() MOZ_OVERRIDE - { - NS_ASSERT_OWNINGTHREAD(ReadStream); - - if (mClosed) { - return; - } - - mClosed = true; - mControl->RemoveListener(this); - mControl->NoteClosed(mId); - } - - virtual void ForgetOnOwningThread() MOZ_OVERRIDE - { - NS_ASSERT_OWNINGTHREAD(ReadStream); - - if (mClosed) { - return; - } - - mClosed = true; - mControl->RemoveListener(this); - } - - virtual void SerializeControl(PCacheReadStream* aReadStreamOut) MOZ_OVERRIDE - { - MOZ_ASSERT(aReadStreamOut); - MOZ_ASSERT(!mClosed); - aReadStreamOut->controlParent() = nullptr; - aReadStreamOut->controlChild() = mControl; - } - - virtual void - SerializeFds(PCacheReadStream* aReadStreamOut, - const nsTArray& fds) MOZ_OVERRIDE - { - MOZ_ASSERT(!mClosed); - PFileDescriptorSetChild* fdSet = nullptr; - if (!fds.IsEmpty()) { - fdSet = mControl->Manager()->SendPFileDescriptorSetConstructor(fds[0]); - for (uint32_t i = 1; i < fds.Length(); ++i) { - unused << fdSet->SendAddFileDescriptor(fds[i]); - } - } - - if (fdSet) { - aReadStreamOut->fds() = fdSet; - } else { - aReadStreamOut->fds() = void_t(); - } - } - -private: - CacheStreamControlChild* mControl; -}; - -// ---------------------------------------------------------------------------- - -class ReadStreamParent MOZ_FINAL : public ReadStream -{ -public: - ReadStreamParent(PCacheStreamControlParent* aControl, const nsID& aId, - nsIInputStream* aStream) - : ReadStream(aId, aStream) - , mControl(static_cast(aControl)) - { - MOZ_ASSERT(mControl); - mControl->AddListener(this); - } - - virtual ~ReadStreamParent() - { - NS_ASSERT_OWNINGTHREAD(ReadStream); - - NoteClosed(); - } - - virtual void NoteClosedOnOwningThread() MOZ_OVERRIDE - { - NS_ASSERT_OWNINGTHREAD(ReadStream); - - if (mClosed) { - return; - } - - mClosed = true; - mControl->RemoveListener(this); - // This can cause mControl to be destructed - mControl->RecvNoteClosed(mId); - mControl = nullptr; - } - - virtual void ForgetOnOwningThread() MOZ_OVERRIDE - { - NS_ASSERT_OWNINGTHREAD(ReadStream); - - if (mClosed) { - return; - } - - mClosed = true; - // This can cause mControl to be destroyed - mControl->RemoveListener(this); - mControl = nullptr; - } - - virtual void SerializeControl(PCacheReadStream* aReadStreamOut) MOZ_OVERRIDE - { - MOZ_ASSERT(aReadStreamOut); - MOZ_ASSERT(!mClosed); - MOZ_ASSERT(mControl); - aReadStreamOut->controlChild() = nullptr; - aReadStreamOut->controlParent() = mControl; - } - - virtual void - SerializeFds(PCacheReadStream* aReadStreamOut, - const nsTArray& fds) MOZ_OVERRIDE - { - MOZ_ASSERT(!mClosed); - MOZ_ASSERT(mControl); - PFileDescriptorSetParent* fdSet = nullptr; - if (!fds.IsEmpty()) { - fdSet = mControl->Manager()->SendPFileDescriptorSetConstructor(fds[0]); - for (uint32_t i = 1; i < fds.Length(); ++i) { - unused << fdSet->SendAddFileDescriptor(fds[i]); - } - } - - if (fdSet) { - aReadStreamOut->fds() = fdSet; - } else { - aReadStreamOut->fds() = void_t(); - } - } - -private: - CacheStreamControlParent* mControl; -}; - -// ---------------------------------------------------------------------------- - -} // anonymous namespace - namespace mozilla { namespace dom { namespace cache { using mozilla::unused; using mozilla::ipc::FileDescriptor; -using mozilla::ipc::FileDescriptorSetChild; -using mozilla::ipc::FileDescriptorSetParent; -using mozilla::ipc::InputStreamParams; -using mozilla::ipc::OptionalFileDescriptorSet; -using mozilla::ipc::PFileDescriptorSetChild; + +// ---------------------------------------------------------------------------- + +// The inner stream class. This is where all of the real work is done. As +// an invariant Inner::Close() must be called before ~Inner(). This is +// guaranteed by our outer ReadStream class. +class ReadStream::Inner MOZ_FINAL : public ReadStream::Controllable +{ +public: + Inner(StreamControl* aControl, const nsID& aId, + nsIInputStream* aStream); + + void + Serialize(PCacheReadStreamOrVoid* aReadStreamOut); + + void + Serialize(PCacheReadStream* aReadStreamOut); + + // ReadStream::Controllable methods + virtual void + CloseStream() MOZ_OVERRIDE; + + virtual void + CloseStreamWithoutReporting() MOZ_OVERRIDE; + + virtual bool + MatchId(const nsID& aId) const MOZ_OVERRIDE; + + // Simulate nsIInputStream methods, but we don't actually inherit from it + NS_METHOD + Close(); + + NS_METHOD + Available(uint64_t *aNumAvailableOut); + + NS_METHOD + Read(char *aBuf, uint32_t aCount, uint32_t *aNumReadOut); + + NS_METHOD + ReadSegments(nsWriteSegmentFun aWriter, void *aClosure, uint32_t aCount, + uint32_t *aNumReadOut); + + NS_METHOD + IsNonBlocking(bool *aNonBlockingOut); + +private: + class NoteClosedRunnable; + class ForgetRunnable; + + ~Inner(); + + void + NoteClosed(); + + void + Forget(); + + void + NoteClosedOnOwningThread(); + + void + ForgetOnOwningThread(); + + // Weak ref to the stream control actor. The actor will always call either + // CloseStream() or CloseStreamWithoutReporting() before it's destroyed. The + // weak ref is cleared in the resulting NoteClosedOnOwningThread() or + // ForgetOnOwningThread() method call. + StreamControl* mControl; + + const nsID mId; + nsCOMPtr mStream; + nsCOMPtr mSnappyStream; + nsCOMPtr mOwningThread; + + enum State + { + Open, + Closed, + NumStates + }; + Atomic mState; + + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(cache::ReadStream::Inner, MOZ_OVERRIDE) +}; + +// ---------------------------------------------------------------------------- // Runnable to notify actors that the ReadStream has closed. This must // be done on the thread associated with the PBackground actor. Must be // cancelable to execute on Worker threads (which can occur when the // ReadStream is constructed on a child process Worker thread). -class ReadStream::NoteClosedRunnable MOZ_FINAL : public nsCancelableRunnable +class ReadStream::Inner::NoteClosedRunnable MOZ_FINAL : public nsCancelableRunnable { public: - explicit NoteClosedRunnable(ReadStream* aStream) + explicit NoteClosedRunnable(ReadStream::Inner* aStream) : mStream(aStream) { } NS_IMETHOD Run() { mStream->NoteClosedOnOwningThread(); + mStream = nullptr; return NS_OK; } @@ -251,24 +138,27 @@ public: private: ~NoteClosedRunnable() { } - nsRefPtr mStream; + nsRefPtr mStream; }; +// ---------------------------------------------------------------------------- + // Runnable to clear actors without reporting that the ReadStream has // closed. Since this can trigger actor destruction, we need to do // it on the thread associated with the PBackground actor. Must be // cancelable to execute on Worker threads (which can occur when the // ReadStream is constructed on a child process Worker thread). -class ReadStream::ForgetRunnable MOZ_FINAL : public nsCancelableRunnable +class ReadStream::Inner::ForgetRunnable MOZ_FINAL : public nsCancelableRunnable { public: - explicit ForgetRunnable(ReadStream* aStream) + explicit ForgetRunnable(ReadStream::Inner* aStream) : mStream(aStream) { } NS_IMETHOD Run() { mStream->ForgetOnOwningThread(); + mStream = nullptr; return NS_OK; } @@ -283,11 +173,216 @@ public: private: ~ForgetRunnable() { } - nsRefPtr mStream; + nsRefPtr mStream; }; -NS_IMPL_ISUPPORTS(mozilla::dom::cache::ReadStream, nsIInputStream, - ReadStream); +// ---------------------------------------------------------------------------- + +ReadStream::Inner::Inner(StreamControl* aControl, const nsID& aId, + nsIInputStream* aStream) + : mControl(aControl) + , mId(aId) + , mStream(aStream) + , mSnappyStream(new SnappyUncompressInputStream(aStream)) + , mOwningThread(NS_GetCurrentThread()) + , mState(Open) +{ + MOZ_ASSERT(mStream); + MOZ_ASSERT(mControl); + mControl->AddReadStream(this); +} + +void +ReadStream::Inner::Serialize(PCacheReadStreamOrVoid* aReadStreamOut) +{ + MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread); + MOZ_ASSERT(aReadStreamOut); + PCacheReadStream stream; + Serialize(&stream); + *aReadStreamOut = stream; +} + +void +ReadStream::Inner::Serialize(PCacheReadStream* aReadStreamOut) +{ + MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread); + MOZ_ASSERT(aReadStreamOut); + MOZ_ASSERT(mState == Open); + MOZ_ASSERT(mControl); + + aReadStreamOut->id() = mId; + mControl->SerializeControl(aReadStreamOut); + + nsAutoTArray fds; + SerializeInputStream(mStream, aReadStreamOut->params(), fds); + + mControl->SerializeFds(aReadStreamOut, fds); + + // We're passing ownership across the IPC barrier with the control, so + // do not signal that the stream is closed here. + Forget(); +} + +void +ReadStream::Inner::CloseStream() +{ + MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread); + Close(); +} + +void +ReadStream::Inner::CloseStreamWithoutReporting() +{ + MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread); + Forget(); +} + +bool +ReadStream::Inner::MatchId(const nsID& aId) const +{ + MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread); + return mId.Equals(aId); +} + +NS_IMETHODIMP +ReadStream::Inner::Close() +{ + // stream ops can happen on any thread + nsresult rv = mStream->Close(); + NoteClosed(); + return rv; +} + +NS_IMETHODIMP +ReadStream::Inner::Available(uint64_t* aNumAvailableOut) +{ + // stream ops can happen on any thread + nsresult rv = mSnappyStream->Available(aNumAvailableOut); + + if (NS_FAILED(rv)) { + Close(); + } + + return rv; +} + +NS_IMETHODIMP +ReadStream::Inner::Read(char* aBuf, uint32_t aCount, uint32_t* aNumReadOut) +{ + // stream ops can happen on any thread + MOZ_ASSERT(aNumReadOut); + + nsresult rv = mSnappyStream->Read(aBuf, aCount, aNumReadOut); + + if ((NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) || + *aNumReadOut == 0) { + Close(); + } + + return rv; +} + +NS_IMETHODIMP +ReadStream::Inner::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, + uint32_t aCount, uint32_t* aNumReadOut) +{ + // stream ops can happen on any thread + MOZ_ASSERT(aNumReadOut); + + nsresult rv = mSnappyStream->ReadSegments(aWriter, aClosure, aCount, + aNumReadOut); + + if ((NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK && + rv != NS_ERROR_NOT_IMPLEMENTED) || *aNumReadOut == 0) { + Close(); + } + + return rv; +} + +NS_IMETHODIMP +ReadStream::Inner::IsNonBlocking(bool* aNonBlockingOut) +{ + // stream ops can happen on any thread + return mSnappyStream->IsNonBlocking(aNonBlockingOut); +} + +ReadStream::Inner::~Inner() +{ + // Any thread + MOZ_ASSERT(mState == Closed); + MOZ_ASSERT(!mControl); +} + +void +ReadStream::Inner::NoteClosed() +{ + // Any thread + if (mState == Closed) { + return; + } + + if (NS_GetCurrentThread() == mOwningThread) { + NoteClosedOnOwningThread(); + return; + } + + nsCOMPtr runnable = new NoteClosedRunnable(this); + MOZ_ALWAYS_TRUE(NS_SUCCEEDED( + mOwningThread->Dispatch(runnable, nsIThread::DISPATCH_NORMAL))); +} + +void +ReadStream::Inner::Forget() +{ + // Any thread + if (mState == Closed) { + return; + } + + if (NS_GetCurrentThread() == mOwningThread) { + ForgetOnOwningThread(); + return; + } + + nsCOMPtr runnable = new ForgetRunnable(this); + MOZ_ALWAYS_TRUE(NS_SUCCEEDED( + mOwningThread->Dispatch(runnable, nsIThread::DISPATCH_NORMAL))); +} + +void +ReadStream::Inner::NoteClosedOnOwningThread() +{ + MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread); + + // Mark closed and do nothing if we were already closed + if (!mState.compareExchange(Open, Closed)) { + return; + } + + MOZ_ASSERT(mControl); + mControl->NoteClosed(this, mId); + mControl = nullptr; +} + +void +ReadStream::Inner::ForgetOnOwningThread() +{ + MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread); + + // Mark closed and do nothing if we were already closed + if (!mState.compareExchange(Open, Closed)) { + return; + } + + MOZ_ASSERT(mControl); + mControl->ForgetReadStream(this); + mControl = nullptr; +} + +// ---------------------------------------------------------------------------- + +NS_IMPL_ISUPPORTS(cache::ReadStream, nsIInputStream, ReadStream); // static already_AddRefed @@ -311,33 +406,20 @@ ReadStream::Create(const PCacheReadStream& aReadStream) return nullptr; } - nsAutoTArray fds; - if (aReadStream.fds().type() == - OptionalFileDescriptorSet::TPFileDescriptorSetChild) { - - FileDescriptorSetChild* fdSetActor = - static_cast(aReadStream.fds().get_PFileDescriptorSetChild()); - MOZ_ASSERT(fdSetActor); - - fdSetActor->ForgetFileDescriptors(fds); - MOZ_ASSERT(!fds.IsEmpty()); - - unused << fdSetActor->Send__delete__(fdSetActor); - } else if (aReadStream.fds().type() == - OptionalFileDescriptorSet::TPFileDescriptorSetParent) { - - FileDescriptorSetParent* fdSetActor = - static_cast(aReadStream.fds().get_PFileDescriptorSetParent()); - MOZ_ASSERT(fdSetActor); - - fdSetActor->ForgetFileDescriptors(fds); - MOZ_ASSERT(!fds.IsEmpty()); - - if (!fdSetActor->Send__delete__(fdSetActor)) { - // child process is gone, warn and allow actor to clean up normally - NS_WARNING("Cache failed to delete fd set actor."); - } + // Control is guaranteed to survive this method as ActorDestroy() cannot + // run on this thread until we complete. + StreamControl* control; + if (aReadStream.controlChild()) { + auto actor = static_cast(aReadStream.controlChild()); + control = actor; + } else { + auto actor = static_cast(aReadStream.controlParent()); + control = actor; } + MOZ_ASSERT(control); + + nsAutoTArray fds; + control->DeserializeFds(aReadStream, fds); nsCOMPtr stream = DeserializeInputStream(aReadStream.params(), fds); @@ -349,16 +431,8 @@ ReadStream::Create(const PCacheReadStream& aReadStream) MOZ_ASSERT(!asyncStream); #endif - nsRefPtr ref; - - if (aReadStream.controlChild()) { - ref = new ReadStreamChild(aReadStream.controlChild(), aReadStream.id(), - stream); - } else { - ref = new ReadStreamParent(aReadStream.controlParent(), aReadStream.id(), - stream); - } - + nsRefPtr inner = new Inner(control, aReadStream.id(), stream); + nsRefPtr ref = new ReadStream(inner); return ref.forget(); } @@ -367,170 +441,67 @@ already_AddRefed ReadStream::Create(PCacheStreamControlParent* aControl, const nsID& aId, nsIInputStream* aStream) { - nsRefPtr ref = new ReadStreamParent(aControl, aId, aStream); + MOZ_ASSERT(aControl); + auto actor = static_cast(aControl); + nsRefPtr inner = new Inner(actor, aId, aStream); + nsRefPtr ref = new ReadStream(inner); return ref.forget(); } void ReadStream::Serialize(PCacheReadStreamOrVoid* aReadStreamOut) { - MOZ_ASSERT(aReadStreamOut); - PCacheReadStream stream; - Serialize(&stream); - *aReadStreamOut = stream; + mInner->Serialize(aReadStreamOut); } void ReadStream::Serialize(PCacheReadStream* aReadStreamOut) { - MOZ_ASSERT(aReadStreamOut); - MOZ_ASSERT(!mClosed); - - aReadStreamOut->id() = mId; - SerializeControl(aReadStreamOut); - - nsAutoTArray fds; - SerializeInputStream(mStream, aReadStreamOut->params(), fds); - - SerializeFds(aReadStreamOut, fds); - - // We're passing ownership across the IPC barrier with the control, so - // do not signal that the stream is closed here. - Forget(); + mInner->Serialize(aReadStreamOut); } -void -ReadStream::CloseStream() +ReadStream::ReadStream(ReadStream::Inner* aInner) + : mInner(aInner) { - Close(); -} - -void -ReadStream::CloseStreamWithoutReporting() -{ - Forget(); -} - -bool -ReadStream::MatchId(const nsID& aId) const -{ - return mId.Equals(aId); -} - -ReadStream::ReadStream(const nsID& aId, nsIInputStream* aStream) - : mId(aId) - , mStream(aStream) - , mSnappyStream(new SnappyUncompressInputStream(aStream)) - , mOwningThread(NS_GetCurrentThread()) - , mClosed(false) -{ - MOZ_ASSERT(mStream); + MOZ_ASSERT(mInner); } ReadStream::~ReadStream() { - NS_ASSERT_OWNINGTHREAD(ReadStream); - - // We cannot directly call NoteClosed() here. The concrete subclasses - // destructors must do this because it takes code paths through virtual - // methods. We don't want to execute these while partially destroyed. - MOZ_ASSERT(mClosed); -} - -void -ReadStream::NoteClosed() -{ - if (mClosed) { - return; - } - - if (NS_GetCurrentThread() == mOwningThread) { - NoteClosedOnOwningThread(); - return; - } - - nsCOMPtr runnable = new NoteClosedRunnable(this); - nsresult rv = mOwningThread->Dispatch(runnable, nsIThread::DISPATCH_NORMAL); - if (NS_FAILED(rv)) { - NS_WARNING("Failed to dispatch Cache ReadStream NoteClosed() runnable."); - } -} - -void -ReadStream::Forget() -{ - if (mClosed) { - return; - } - - if (NS_GetCurrentThread() == mOwningThread) { - ForgetOnOwningThread(); - return; - } - - nsCOMPtr runnable = new ForgetRunnable(this); - nsresult rv = mOwningThread->Dispatch(runnable, nsIThread::DISPATCH_NORMAL); - if (NS_FAILED(rv)) { - NS_WARNING("Failed to dispatch Cache ReadStream Forget() runnable."); - } + // Explicitly close the inner stream so that it does not have to + // deal with implicitly closing at destruction time. + mInner->Close(); } NS_IMETHODIMP ReadStream::Close() { - nsresult rv = mStream->Close(); - NoteClosed(); - return rv; + return mInner->Close(); } NS_IMETHODIMP ReadStream::Available(uint64_t* aNumAvailableOut) { - nsresult rv = mSnappyStream->Available(aNumAvailableOut); - - if (NS_FAILED(rv)) { - Close(); - } - - return rv; + return mInner->Available(aNumAvailableOut); } NS_IMETHODIMP ReadStream::Read(char* aBuf, uint32_t aCount, uint32_t* aNumReadOut) { - MOZ_ASSERT(aNumReadOut); - - nsresult rv = mSnappyStream->Read(aBuf, aCount, aNumReadOut); - - if ((NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) || - *aNumReadOut == 0) { - Close(); - } - - return rv; + return mInner->Read(aBuf, aCount, aNumReadOut); } NS_IMETHODIMP ReadStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, uint32_t aCount, uint32_t* aNumReadOut) { - MOZ_ASSERT(aNumReadOut); - - nsresult rv = mSnappyStream->ReadSegments(aWriter, aClosure, aCount, - aNumReadOut); - - if ((NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK && - rv != NS_ERROR_NOT_IMPLEMENTED) || *aNumReadOut == 0) { - Close(); - } - - return rv; + return mInner->ReadSegments(aWriter, aClosure, aCount, aNumReadOut); } NS_IMETHODIMP ReadStream::IsNonBlocking(bool* aNonBlockingOut) { - return mSnappyStream->IsNonBlocking(aNonBlockingOut); + return mInner->IsNonBlocking(aNonBlockingOut); } } // namespace cache diff --git a/dom/cache/ReadStream.h b/dom/cache/ReadStream.h index b89dc7c97a0..c6a73175401 100644 --- a/dom/cache/ReadStream.h +++ b/dom/cache/ReadStream.h @@ -12,6 +12,7 @@ #include "nsID.h" #include "nsIInputStream.h" #include "nsISupportsImpl.h" +#include "nsRefPtr.h" #include "nsTArrayForwardDeclare.h" class nsIThread; @@ -29,6 +30,7 @@ class PCacheStreamControlParent; {0x8e5da7c9, 0x0940, 0x4f1d, \ {0x97, 0x25, 0x5c, 0x59, 0x38, 0xdd, 0xb9, 0x9f}} + // Custom stream class for Request and Response bodies being read from // a Cache. The main purpose of this class is to report back to the // Cache's Manager when the stream is closed. This allows the Cache to @@ -40,9 +42,34 @@ class PCacheStreamControlParent; // stream channel. For example, Cache.put() can detect that the content // script is passing a Cache-originated-stream back into the Cache // again. This enables certain optimizations. -class ReadStream : public nsIInputStream +class ReadStream MOZ_FINAL : public nsIInputStream { public: + // Interface that lets the StreamControl classes interact with + // our private inner stream. + class Controllable + { + public: + // Closes the stream, notifies the stream control, and then forgets + // the stream control. + virtual void + CloseStream() = 0; + + // Closes the stream and then forgets the stream control. Does not + // notify. + virtual void + CloseStreamWithoutReporting() = 0; + + virtual bool + MatchId(const nsID& aId) const = 0; + + NS_IMETHOD_(MozExternalRefCountType) + AddRef(void) = 0; + + NS_IMETHOD_(MozExternalRefCountType) + Release(void) = 0; + }; + static already_AddRefed Create(const PCacheReadStreamOrVoid& aReadStreamOrVoid); @@ -56,39 +83,21 @@ public: void Serialize(PCacheReadStreamOrVoid* aReadStreamOut); void Serialize(PCacheReadStream* aReadStreamOut); - // methods called from the child and parent CacheStreamControl actors - void CloseStream(); - void CloseStreamWithoutReporting(); - bool MatchId(const nsID& aId) const; +private: + class Inner; -protected: - class NoteClosedRunnable; - class ForgetRunnable; + explicit ReadStream(Inner* aInner); + ~ReadStream(); - ReadStream(const nsID& aId, nsIInputStream* aStream); - virtual ~ReadStream(); - - void NoteClosed(); - void Forget(); - - virtual void NoteClosedOnOwningThread() = 0; - virtual void ForgetOnOwningThread() = 0; - virtual void SerializeControl(PCacheReadStream* aReadStreamOut) = 0; - - virtual void - SerializeFds(PCacheReadStream* aReadStreamOut, - const nsTArray& fds) = 0; - - const nsID mId; - nsCOMPtr mStream; - nsCOMPtr mSnappyStream; - nsCOMPtr mOwningThread; - bool mClosed; + // Hold a strong ref to an inner class that actually implements the + // majority of the stream logic. Before releasing this ref the outer + // ReadStream guarantees it will call Close() on the inner stream. + // This is essential for the inner stream to avoid dealing with the + // implicit close that can happen when a stream is destroyed. + nsRefPtr mInner; public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_CACHE_READSTREAM_IID); - NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIINPUTSTREAM }; diff --git a/dom/cache/StreamControl.cpp b/dom/cache/StreamControl.cpp new file mode 100644 index 00000000000..8be74bab728 --- /dev/null +++ b/dom/cache/StreamControl.cpp @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/cache/StreamControl.h" + +namespace mozilla { +namespace dom { +namespace cache { + +void +StreamControl::AddReadStream(ReadStream::Controllable* aReadStream) +{ + AssertOwningThread(); + MOZ_ASSERT(aReadStream); + MOZ_ASSERT(!mReadStreamList.Contains(aReadStream)); + mReadStreamList.AppendElement(aReadStream); +} + +void +StreamControl::ForgetReadStream(ReadStream::Controllable* aReadStream) +{ + AssertOwningThread(); + MOZ_ALWAYS_TRUE(mReadStreamList.RemoveElement(aReadStream)); +} + +void +StreamControl::NoteClosed(ReadStream::Controllable* aReadStream, + const nsID& aId) +{ + AssertOwningThread(); + ForgetReadStream(aReadStream); + NoteClosedAfterForget(aId); +} + +StreamControl::~StreamControl() +{ + // owning thread only, but can't call virtual AssertOwningThread in destructor + MOZ_ASSERT(mReadStreamList.IsEmpty()); +} + +void +StreamControl::CloseReadStreams(const nsID& aId) +{ + AssertOwningThread(); + DebugOnly closedCount = 0; + + ReadStreamList::ForwardIterator iter(mReadStreamList); + while (iter.HasMore()) { + nsRefPtr stream = iter.GetNext(); + if (stream->MatchId(aId)) { + stream->CloseStream(); + closedCount += 1; + } + } + + MOZ_ASSERT(closedCount > 0); +} + +void +StreamControl::CloseAllReadStreams() +{ + AssertOwningThread(); + + ReadStreamList::ForwardIterator iter(mReadStreamList); + while (iter.HasMore()) { + iter.GetNext()->CloseStream(); + } +} + +void +StreamControl::CloseAllReadStreamsWithoutReporting() +{ + AssertOwningThread(); + + ReadStreamList::ForwardIterator iter(mReadStreamList); + while (iter.HasMore()) { + nsRefPtr stream = iter.GetNext(); + // Note, we cannot trigger IPC traffic here. So use + // CloseStreamWithoutReporting(). + stream->CloseStreamWithoutReporting(); + } +} + +} // namespace cache +} // namespace dom +} // namespace mozilla diff --git a/dom/cache/StreamControl.h b/dom/cache/StreamControl.h new file mode 100644 index 00000000000..8b1cb6f8f9f --- /dev/null +++ b/dom/cache/StreamControl.h @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_cache_StreamControl_h +#define mozilla_dom_cache_StreamControl_h + +#include "mozilla/dom/cache/ReadStream.h" +#include "nsRefPtr.h" +#include "nsTObserverArray.h" + +struct nsID; + +namespace mozilla { +namespace ipc { + class FileDescriptor; +} +namespace dom { +namespace cache { + +class PCacheReadStream; + +// Abstract class to help implement the stream control Child and Parent actors. +// This provides an interface to partly help with serialization of IPC types, +// but also an implementation for tracking ReadStream objects. +class StreamControl +{ +public: + // abstract interface that must be implemented by child class + virtual void + SerializeControl(PCacheReadStream* aReadStreamOut) = 0; + + virtual void + SerializeFds(PCacheReadStream* aReadStreamOut, + const nsTArray& aFds) = 0; + + virtual void + DeserializeFds(const PCacheReadStream& aReadStream, + nsTArray& aFdsOut) = 0; + + // inherited implementation of the ReadStream::Controllable list + + // Begin controlling the given ReadStream. This causes a strong ref to + // be held by the control. The ReadStream must call NoteClosed() or + // ForgetReadStream() to release this ref. + void + AddReadStream(ReadStream::Controllable* aReadStream); + + // Forget the ReadStream without notifying the actor. + void + ForgetReadStream(ReadStream::Controllable* aReadStream); + + // Forget the ReadStream and then notify the actor the stream is closed. + void + NoteClosed(ReadStream::Controllable* aReadStream, const nsID& aId); + +protected: + ~StreamControl(); + + void + CloseReadStreams(const nsID& aId); + + void + CloseAllReadStreams(); + + void + CloseAllReadStreamsWithoutReporting(); + + // protected parts of the abstract interface + virtual void + NoteClosedAfterForget(const nsID& aId) = 0; + +#ifdef DEBUG + virtual void + AssertOwningThread() = 0; +#else + void AssertOwningThread() { } +#endif + +private: + // Hold strong references to ReadStream object. When the stream is closed + // it should call NoteClosed() or ForgetReadStream() to release this ref. + typedef nsTObserverArray> ReadStreamList; + ReadStreamList mReadStreamList; +}; + +} // namespace cache +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_cache_StreamControl_h diff --git a/dom/cache/moz.build b/dom/cache/moz.build index bc35f2fac68..912ddee81b7 100644 --- a/dom/cache/moz.build +++ b/dom/cache/moz.build @@ -30,6 +30,7 @@ EXPORTS.mozilla.dom.cache += [ 'QuotaClient.h', 'ReadStream.h', 'SavedTypes.h', + 'StreamControl.h', 'StreamList.h', 'StreamUtils.h', 'Types.h', @@ -59,6 +60,7 @@ UNIFIED_SOURCES += [ 'PrincipalVerifier.cpp', 'QuotaClient.cpp', 'ReadStream.cpp', + 'StreamControl.cpp', 'StreamList.cpp', 'StreamUtils.cpp', 'TypeUtils.cpp', diff --git a/dom/cache/test/mochitest/test_cache_matchAll_request.js b/dom/cache/test/mochitest/test_cache_matchAll_request.js index 8c8e7f4c250..0ad2c93b69d 100644 --- a/dom/cache/test/mochitest/test_cache_matchAll_request.js +++ b/dom/cache/test/mochitest/test_cache_matchAll_request.js @@ -101,7 +101,7 @@ function testRequest(request1, request2, request3, unknownRequest, return checkResponse(r[0], response1, response1Text); }).then(function() { return c.matchAll(requestWithAlternateQueryString, - {ignoreSearch: true, cacheName: name}); + {ignoreSearch: true}); }).then(function(r) { is(r.length, 2, "Should find 2 items"); return Promise.all([ @@ -122,16 +122,25 @@ function testRequest(request1, request2, request3, unknownRequest, checkResponse(r[1], response3, response3Text) ]); }).then(function() { - return c.matchAll({cacheName: name + "mambojambo"}); - }).then(function(r) { - is(r.length, 0, "Searching in the wrong cache should not succeed"); + return caches.match(request1, {cacheName: name + "mambojambo"}) + .then(function() { + ok(false, "Promise should be rejected"); + }, function(err) { + is(err.name, "NotFoundError", "Searching in the wrong cache should not succeed"); + }); }).then(function() { return c.matchAll(unknownRequest); }).then(function(r) { is(r.length, 0, "Searching for an unknown request should not succeed"); - return c.matchAll(unknownRequest, {cacheName: name}); + return caches.match(unknownRequest, {cacheName: name}); }).then(function(r) { - is(r.length, 0, "Searching for an unknown request should not succeed"); + is(typeof r, "undefined", "Searching for an unknown request should not succeed"); + // Make sure that cacheName is ignored on Cache + return c.matchAll(request1, {cacheName: name + "mambojambo"}); + }).then(function(r) { + is(r.length, 1, "Should only find 1 item"); + return checkResponse(r[0], response1, response1Text); + }).then(function() { return caches.delete(name); }).then(function(success) { ok(success, "We should be able to delete the cache successfully"); diff --git a/dom/cache/test/mochitest/test_cache_match_request.js b/dom/cache/test/mochitest/test_cache_match_request.js index 9d32a56a8ac..2843cb0d90f 100644 --- a/dom/cache/test/mochitest/test_cache_match_request.js +++ b/dom/cache/test/mochitest/test_cache_match_request.js @@ -102,6 +102,11 @@ function testRequest(request, unknownRequest, requestWithAlternateQueryString, }, function(err) { is(err.name, "NotFoundError", "Searching in the wrong cache should not succeed"); }); + }).then(function() { + // Make sure that cacheName is ignored on Cache + return c.match(request, {cacheName: name + "mambojambo"}); + }).then(function(r) { + return checkResponse(r); }).then(function() { return c.match(unknownRequest); }).then(function(r) { diff --git a/dom/canvas/test/_webgl-conformance.ini b/dom/canvas/test/_webgl-conformance.ini index 280b2bf3834..b8e8ccdcec5 100644 --- a/dom/canvas/test/_webgl-conformance.ini +++ b/dom/canvas/test/_webgl-conformance.ini @@ -4,6 +4,7 @@ # Mark failing tests in mochi-single.html. [DEFAULT] +subsuite = webgl skip-if = e10s || os == 'b2g' || ((os == 'linux') && (buildapp == 'b2g')) || ((os == 'linux') && (buildapp == 'mulet')) support-files = webgl-conformance/../webgl-mochitest/driver-info.js diff --git a/dom/canvas/test/mochitest-subsuite-webgl.ini b/dom/canvas/test/mochitest-subsuite-webgl.ini index b415045d061..6ed6e959ee5 100644 --- a/dom/canvas/test/mochitest-subsuite-webgl.ini +++ b/dom/canvas/test/mochitest-subsuite-webgl.ini @@ -1,3 +1,5 @@ [DEFAULT] +subsuite = webgl + [include:_webgl-conformance.ini] [include:webgl-mochitest.ini] diff --git a/dom/canvas/test/webgl-conformance/generate-wrappers-and-manifest.py b/dom/canvas/test/webgl-conformance/generate-wrappers-and-manifest.py index b80aea00d2c..2658b1088e5 100644 --- a/dom/canvas/test/webgl-conformance/generate-wrappers-and-manifest.py +++ b/dom/canvas/test/webgl-conformance/generate-wrappers-and-manifest.py @@ -30,8 +30,9 @@ EXTRA_SUPPORT_FILES = [ ] ACCEPTABLE_ERRATA_KEYS = set([ - 'skip-if', 'fail-if', + 'skip-if', + 'subsuite', ]) GENERATED_HEADER = ''' diff --git a/dom/canvas/test/webgl-conformance/mochitest-errata.ini b/dom/canvas/test/webgl-conformance/mochitest-errata.ini index 6e9c18c2cbe..d79193bb7d1 100644 --- a/dom/canvas/test/webgl-conformance/mochitest-errata.ini +++ b/dom/canvas/test/webgl-conformance/mochitest-errata.ini @@ -5,6 +5,7 @@ # See python/mozbuild/mozbuild/mozinfo.py for incoming data. [DEFAULT] +subsuite = webgl # No e10s yet. # 'B2G Desktop Linux' fails to create WebGL contexts. # Also skip B2G for now, until we get a handle on the longer tail of emulator diff --git a/dom/canvas/test/webgl-mochitest.ini b/dom/canvas/test/webgl-mochitest.ini index 1e0a0bf9180..319f0e6449b 100644 --- a/dom/canvas/test/webgl-mochitest.ini +++ b/dom/canvas/test/webgl-mochitest.ini @@ -1,4 +1,5 @@ [DEFAULT] +subsuite = webgl skip-if = ((os == 'linux') && (buildapp == 'b2g')) support-files = diff --git a/dom/events/test/mochitest.ini b/dom/events/test/mochitest.ini index 005ca2febf5..739e3e2a68a 100644 --- a/dom/events/test/mochitest.ini +++ b/dom/events/test/mochitest.ini @@ -183,3 +183,4 @@ skip-if = buildapp == 'b2g' || e10s support-files = bug1096146_embedded.html [test_offsetxy.html] +[test_eventhandler_scoping.html] diff --git a/dom/events/test/test_eventhandler_scoping.html b/dom/events/test/test_eventhandler_scoping.html new file mode 100644 index 00000000000..f15238a0c8e --- /dev/null +++ b/dom/events/test/test_eventhandler_scoping.html @@ -0,0 +1,17 @@ + + +Test for event handler scoping + + +
+ diff --git a/dom/indexedDB/IDBDatabase.cpp b/dom/indexedDB/IDBDatabase.cpp index b66958c493e..bf0237a9697 100644 --- a/dom/indexedDB/IDBDatabase.cpp +++ b/dom/indexedDB/IDBDatabase.cpp @@ -1335,7 +1335,7 @@ nsresult IDBDatabase::PostHandleEvent(EventChainPostVisitor& aVisitor) { nsresult rv = - IndexedDatabaseManager::CommonPostHandleEvent(this, mFactory, aVisitor); + IndexedDatabaseManager::CommonPostHandleEvent(aVisitor, mFactory); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } diff --git a/dom/indexedDB/IDBRequest.cpp b/dom/indexedDB/IDBRequest.cpp index 4c21f088d45..8b30a9d13a8 100644 --- a/dom/indexedDB/IDBRequest.cpp +++ b/dom/indexedDB/IDBRequest.cpp @@ -43,6 +43,12 @@ namespace indexedDB { using namespace mozilla::dom::workers; using namespace mozilla::ipc; +namespace { + +NS_DEFINE_IID(kIDBRequestIID, PRIVATE_IDBREQUEST_IID); + +} // anonymous namespace + IDBRequest::IDBRequest(IDBDatabase* aDatabase) : IDBWrapperCache(aDatabase) { @@ -407,6 +413,9 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache) NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBRequest) + if (aIID.Equals(kIDBRequestIID)) { + foundInterface = this; + } else NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache) NS_IMPL_ADDREF_INHERITED(IDBRequest, IDBWrapperCache) @@ -563,7 +572,7 @@ nsresult IDBOpenDBRequest::PostHandleEvent(EventChainPostVisitor& aVisitor) { nsresult rv = - IndexedDatabaseManager::CommonPostHandleEvent(this, mFactory, aVisitor); + IndexedDatabaseManager::CommonPostHandleEvent(aVisitor, mFactory); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } diff --git a/dom/indexedDB/IDBRequest.h b/dom/indexedDB/IDBRequest.h index 15fff5869a8..5e81d9c09b0 100644 --- a/dom/indexedDB/IDBRequest.h +++ b/dom/indexedDB/IDBRequest.h @@ -15,6 +15,9 @@ #include "nsAutoPtr.h" #include "nsCycleCollectionParticipant.h" +#define PRIVATE_IDBREQUEST_IID \ + {0xe68901e5, 0x1d50, 0x4ee9, {0xaf, 0x49, 0x90, 0x99, 0x4a, 0xff, 0xc8, 0x39}} + class nsPIDOMWindow; struct PRThread; diff --git a/dom/indexedDB/IndexedDatabaseManager.cpp b/dom/indexedDB/IndexedDatabaseManager.cpp index 41c5dc1d945..6a3dd4e7f7b 100644 --- a/dom/indexedDB/IndexedDatabaseManager.cpp +++ b/dom/indexedDB/IndexedDatabaseManager.cpp @@ -8,9 +8,11 @@ #include "nsIConsoleService.h" #include "nsIDiskSpaceWatcher.h" +#include "nsIDOMWindow.h" #include "nsIFile.h" #include "nsIObserverService.h" #include "nsIScriptError.h" +#include "nsIScriptGlobalObject.h" #include "jsapi.h" #include "mozilla/ClearOnShutdown.h" @@ -117,6 +119,8 @@ private: namespace { +NS_DEFINE_IID(kIDBRequestIID, PRIVATE_IDBREQUEST_IID); + #define IDB_PREF_BRANCH_ROOT "dom.indexedDB." const char kTestingPref[] = IDB_PREF_BRANCH_ROOT "testing"; @@ -370,38 +374,41 @@ IndexedDatabaseManager::Destroy() // static nsresult -IndexedDatabaseManager::CommonPostHandleEvent( - DOMEventTargetHelper* aEventTarget, - IDBFactory* aFactory, - EventChainPostVisitor& aVisitor) +IndexedDatabaseManager::CommonPostHandleEvent(EventChainPostVisitor& aVisitor, + IDBFactory* aFactory) { - MOZ_ASSERT(aEventTarget); - MOZ_ASSERT(aFactory); MOZ_ASSERT(aVisitor.mDOMEvent); + MOZ_ASSERT(aFactory); if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault) { return NS_OK; } - nsString type; - nsresult rv = aVisitor.mDOMEvent->GetType(type); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } + Event* internalEvent = aVisitor.mDOMEvent->InternalDOMEvent(); + MOZ_ASSERT(internalEvent); - NS_NAMED_LITERAL_STRING(errorType, "error"); - - MOZ_ASSERT(nsDependentString(kErrorEventType) == errorType); - - if (type != errorType) { + if (!internalEvent->IsTrusted()) { return NS_OK; } - nsCOMPtr eventTarget = - aVisitor.mDOMEvent->InternalDOMEvent()->GetTarget(); + nsString type; + MOZ_ALWAYS_TRUE(NS_SUCCEEDED(internalEvent->GetType(type))); + + MOZ_ASSERT(nsDependentString(kErrorEventType).EqualsLiteral("error")); + if (!type.EqualsLiteral("error")) { + return NS_OK; + } + + nsCOMPtr eventTarget = internalEvent->GetTarget(); MOZ_ASSERT(eventTarget); - auto* request = static_cast(eventTarget.get()); + // Only mess with events that were originally targeted to an IDBRequest. + nsRefPtr request; + if (NS_FAILED(eventTarget->QueryInterface(kIDBRequestIID, + getter_AddRefs(request))) || + !request) { + return NS_OK; + } nsRefPtr error = request->GetErrorAfterResult(); @@ -421,7 +428,7 @@ IndexedDatabaseManager::CommonPostHandleEvent( nsEventStatus status = nsEventStatus_eIgnore; if (NS_IsMainThread()) { - if (nsPIDOMWindow* window = aEventTarget->GetOwner()) { + if (nsIDOMWindow* window = eventTarget->GetOwnerGlobal()) { nsCOMPtr sgo = do_QueryInterface(window); MOZ_ASSERT(sgo); @@ -441,7 +448,9 @@ IndexedDatabaseManager::CommonPostHandleEvent( MOZ_ASSERT(globalScope); nsRefPtr errorEvent = - ErrorEvent::Constructor(globalScope, errorType, init); + ErrorEvent::Constructor(globalScope, + nsDependentString(kErrorEventType), + init); MOZ_ASSERT(errorEvent); errorEvent->SetTrusted(true); diff --git a/dom/indexedDB/IndexedDatabaseManager.h b/dom/indexedDB/IndexedDatabaseManager.h index c622bba586c..cb08f2a6cb4 100644 --- a/dom/indexedDB/IndexedDatabaseManager.h +++ b/dom/indexedDB/IndexedDatabaseManager.h @@ -158,9 +158,7 @@ public: } static nsresult - CommonPostHandleEvent(DOMEventTargetHelper* aEventTarget, - IDBFactory* aFactory, - EventChainPostVisitor& aVisitor); + CommonPostHandleEvent(EventChainPostVisitor& aVisitor, IDBFactory* aFactory); static bool TabContextMayAccessOrigin(const mozilla::dom::TabContext& aContext, diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index b2e0a797b80..f7540da5081 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -551,19 +551,20 @@ InitOnContentProcessCreated() #ifdef MOZ_NUWA_PROCESS static void -ResetTransports(void* aUnused) { +ResetTransports(void* aUnused) +{ ContentChild* child = ContentChild::GetSingleton(); mozilla::ipc::Transport* transport = child->GetTransport(); int fd = transport->GetFileDescriptor(); transport->ResetFileDescriptor(fd); - IToplevelProtocol* toplevel = child->GetFirstOpenedActors(); - while (toplevel != nullptr) { + nsTArray actors; + child->GetOpenedActors(actors); + for (size_t i = 0; i < actors.Length(); i++) { + IToplevelProtocol* toplevel = actors[i]; transport = toplevel->GetTransport(); fd = transport->GetFileDescriptor(); transport->ResetFileDescriptor(fd); - - toplevel = toplevel->getNext(); } } #endif @@ -2677,9 +2678,10 @@ GetProtoFdInfos(NuwaProtoFdInfo* aInfoList, content->GetTransport()->GetFileDescriptor(); i++; - for (IToplevelProtocol* actor = content->GetFirstOpenedActors(); - actor != nullptr; - actor = actor->getNext()) { + IToplevelProtocol* actors[NUWA_TOPLEVEL_MAX]; + size_t count = content->GetOpenedActorsUnsafe(actors, ArrayLength(actors)); + for (size_t j = 0; j < count; j++) { + IToplevelProtocol* actor = actors[j]; if (i >= aInfoListSize) { NS_RUNTIMEABORT("Too many top level protocols!"); } diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index e531309a870..9f945572c52 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -528,7 +528,6 @@ child: HandleDoubleTap(CSSPoint aPoint, Modifiers aModifiers, ScrollableLayerGuid aGuid); HandleSingleTap(CSSPoint aPoint, Modifiers aModifiers, ScrollableLayerGuid aGuid); HandleLongTap(CSSPoint point, Modifiers aModifiers, ScrollableLayerGuid aGuid, uint64_t aInputBlockId); - HandleLongTapUp(CSSPoint point, Modifiers aModifiers, ScrollableLayerGuid aGuid); NotifyAPZStateChange(ViewID aViewId, APZStateChange aChange, int aArg); diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index ac43ed5da3e..af15f787506 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -2113,15 +2113,6 @@ TabChild::RecvHandleLongTap(const CSSPoint& aPoint, const Modifiers& aModifiers, return true; } -bool -TabChild::RecvHandleLongTapUp(const CSSPoint& aPoint, const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid) -{ - if (mGlobal && mTabChildGlobal) { - mAPZEventState->ProcessLongTapUp(aPoint, aModifiers, aGuid, GetPresShellResolution()); - } - return true; -} - bool TabChild::RecvNotifyAPZStateChange(const ViewID& aViewId, const APZStateChange& aChange, diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 2b82d34c3d6..79e736e6a08 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -335,9 +335,6 @@ public: const Modifiers& aModifiers, const mozilla::layers::ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId) MOZ_OVERRIDE; - virtual bool RecvHandleLongTapUp(const CSSPoint& aPoint, - const Modifiers& aModifiers, - const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE; virtual bool RecvNotifyAPZStateChange(const ViewID& aViewId, const APZStateChange& aChange, const int& aArg) MOZ_OVERRIDE; diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 5fa7505d77a..c60e8440470 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -964,15 +964,6 @@ void TabParent::HandleLongTap(const CSSPoint& aPoint, } } -void TabParent::HandleLongTapUp(const CSSPoint& aPoint, - Modifiers aModifiers, - const ScrollableLayerGuid &aGuid) -{ - if (!mIsDestroyed) { - unused << SendHandleLongTapUp(aPoint, aModifiers, aGuid); - } -} - void TabParent::NotifyAPZStateChange(ViewID aViewId, APZStateChange aChange, int aArg) @@ -1198,15 +1189,6 @@ bool TabParent::SendHandleLongTap(const CSSPoint& aPoint, const Modifiers& aModi return PBrowserParent::SendHandleLongTap(AdjustTapToChildWidget(aPoint), aModifiers, aGuid, aInputBlockId); } -bool TabParent::SendHandleLongTapUp(const CSSPoint& aPoint, const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid) -{ - if (mIsDestroyed) { - return false; - } - - return PBrowserParent::SendHandleLongTapUp(AdjustTapToChildWidget(aPoint), aModifiers, aGuid); -} - bool TabParent::SendHandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid) { if (mIsDestroyed) { diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 7e53774a3d5..55bbb65cdef 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -239,9 +239,6 @@ public: Modifiers aModifiers, const ScrollableLayerGuid& aGuid, uint64_t aInputBlockId); - void HandleLongTapUp(const CSSPoint& aPoint, - Modifiers aModifiers, - const ScrollableLayerGuid& aGuid); void NotifyAPZStateChange(ViewID aViewId, APZStateChange aChange, int aArg); @@ -268,7 +265,6 @@ public: bool SendRealTouchEvent(WidgetTouchEvent& event); bool SendHandleSingleTap(const CSSPoint& aPoint, const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid); bool SendHandleLongTap(const CSSPoint& aPoint, const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId); - bool SendHandleLongTapUp(const CSSPoint& aPoint, const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid); bool SendHandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid); virtual PDocumentRendererParent* diff --git a/dom/manifest/ManifestProcessor.jsm b/dom/manifest/ManifestProcessor.jsm index b6df920d1aa..ce5cebdcb07 100644 --- a/dom/manifest/ManifestProcessor.jsm +++ b/dom/manifest/ManifestProcessor.jsm @@ -1,8 +1,7 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * * ManifestProcessor * Implementation of processing algorithms from: * http://www.w3.org/2008/webapps/manifest/ @@ -11,347 +10,351 @@ * or individual parts of a manifest object. A manifest is just a * standard JS object that has been cleaned up. * - * .process(jsonText, manifestURL, docURL); + * .process({jsonText,manifestURL,docURL}); * * TODO: The constructor should accept the UA's supported orientations. * TODO: The constructor should accept the UA's supported display modes. - * TODO: hook up developer tools to issueDeveloperWarning (1086997). + * TODO: hook up developer tools to console. (1086997). */ -/*globals Components*/ /*exported EXPORTED_SYMBOLS */ +/*JSLint options in comment below: */ +/*globals Components, XPCOMUtils*/ 'use strict'; - this.EXPORTED_SYMBOLS = ['ManifestProcessor']; +const imports = {}; const { utils: Cu, classes: Cc, interfaces: Ci } = Components; -const imports = {}; -Cu.import('resource://gre/modules/Services.jsm', imports); +Cu.import('resource://gre/modules/XPCOMUtils.jsm'); Cu.importGlobalProperties(['URL']); -const securityManager = imports.Services.scriptSecurityManager; -const netutil = Cc['@mozilla.org/network/util;1'].getService(Ci.nsINetUtil); -const defaultDisplayMode = 'browser'; -const displayModes = new Set([ - 'fullscreen', - 'standalone', - 'minimal-ui', +XPCOMUtils.defineLazyModuleGetter(imports, 'Services', + 'resource://gre/modules/Services.jsm'); +imports.netutil = Cc['@mozilla.org/network/util;1'].getService(Ci.nsINetUtil); +// Helper function extracts values from manifest members +// and reports conformance violations. +function extractValue({ + objectName, + object, + property, + expectedType, + trim +}, console) { + const value = object[property]; + const isArray = Array.isArray(value); + // We need to special-case "array", as it's not a JS primitive. + const type = (isArray) ? 'array' : typeof value; + if (type !== expectedType) { + if (type !== 'undefined') { + let msg = `Expected the ${objectName}'s ${property} `; + msg += `member to a be a ${expectedType}.`; + console.log(msg); + } + return undefined; + } + // Trim string and returned undefined if the empty string. + const shouldTrim = expectedType === 'string' && value && trim; + if (shouldTrim) { + return value.trim() || undefined; + } + return value; +} +const displayModes = new Set(['fullscreen', 'standalone', 'minimal-ui', 'browser' ]); -const orientationTypes = new Set([ - 'any', - 'natural', - 'landscape', - 'portrait', - 'portrait-primary', - 'portrait-secondary', - 'landscape-primary', +const orientationTypes = new Set(['any', 'natural', 'landscape', 'portrait', + 'portrait-primary', 'portrait-secondary', 'landscape-primary', 'landscape-secondary' ]); +const { + ConsoleAPI +} = Cu.import('resource://gre/modules/devtools/Console.jsm'); -this.ManifestProcessor = function ManifestProcessor() {}; -/** - * process method: processes json text into a clean manifest - * that conforms with the W3C specification. - * @param jsonText - the JSON string to be processd. - * @param manifestURL - the URL of the manifest, to resolve URLs. - * @param docURL - the URL of the owner doc, for security checks - */ -this.ManifestProcessor.prototype.process = function({ - jsonText: jsonText, - manifestURL: manifestURL, - docLocation: docURL -}) { - /* - * This helper function is used to extract values from manifest members. - * It also reports conformance violations. - */ - function extractValue(obj) { - let value = obj.object[obj.property]; - //we need to special-case "array", as it's not a JS primitive - const type = (Array.isArray(value)) ? 'array' : typeof value; +class ManifestProcessor { - if (type !== obj.expectedType) { - if (type !== 'undefined') { - let msg = `Expected the ${obj.objectName}'s ${obj.property}`; - msg += `member to a be a ${obj.expectedType}.`; - issueDeveloperWarning(msg); - } - value = undefined; + constructor() {} + + static get defaultDisplayMode() { + return 'browser'; + } + + static get displayModes() { + return displayModes; + } + + static get orientationTypes() { + return orientationTypes; + } + + // process method: processes json text into a clean manifest + // that conforms with the W3C specification. Takes an object + // expecting the following dictionary items: + // * jsonText: the JSON string to be processd. + // * manifestURL: the URL of the manifest, to resolve URLs. + // * docURL: the URL of the owner doc, for security checks. + process({ + jsonText, manifestURL, docURL + }) { + const console = new ConsoleAPI({ + prefix: 'Web Manifest: ' + }); + let rawManifest = {}; + try { + rawManifest = JSON.parse(jsonText); + } catch (e) {} + if (typeof rawManifest !== 'object' || rawManifest === null) { + let msg = 'Manifest needs to be an object.'; + console.warn(msg); + rawManifest = {}; } - return value; - } - - function issueDeveloperWarning(msg) { - //https://bugzilla.mozilla.org/show_bug.cgi?id=1086997 - } - - function processNameMember(manifest) { - const obj = { - objectName: 'manifest', - object: manifest, - property: 'name', - expectedType: 'string' + const processedManifest = { + start_url: processStartURLMember(rawManifest, manifestURL, docURL), + display: processDisplayMember(rawManifest), + orientation: processOrientationMember(rawManifest), + name: processNameMember(rawManifest), + icons: IconsProcessor.process(rawManifest, manifestURL, console), + short_name: processShortNameMember(rawManifest), }; - let value = extractValue(obj); - return (value) ? value.trim() : value; - } + processedManifest.scope = processScopeMember(rawManifest, manifestURL, + docURL, processedManifest.start_url); + return processedManifest; - function processShortNameMember(manifest) { - const obj = { - objectName: 'manifest', - object: manifest, - property: 'short_name', - expectedType: 'string' - }; - let value = extractValue(obj); - return (value) ? value.trim() : value; - } - - function processOrientationMember(manifest) { - const obj = { - objectName: 'manifest', - object: manifest, - property: 'orientation', - expectedType: 'string' - }; - let value = extractValue(obj); - value = (value) ? value.trim() : undefined; - //The spec special-cases orientation to return the empty string - return (orientationTypes.has(value)) ? value : ''; - } - - function processDisplayMember(manifest) { - const obj = { - objectName: 'manifest', - object: manifest, - property: 'display', - expectedType: 'string' - }; - - let value = extractValue(obj); - value = (value) ? value.trim() : value; - return (displayModes.has(value)) ? value : defaultDisplayMode; - } - - function processScopeMember(manifest, manifestURL, docURL, startURL) { - const spec = { + function processNameMember(aManifest) { + const spec = { objectName: 'manifest', - object: manifest, + object: aManifest, + property: 'name', + expectedType: 'string', + trim: true + }; + return extractValue(spec, console); + } + + function processShortNameMember(aManifest) { + const spec = { + objectName: 'manifest', + object: aManifest, + property: 'short_name', + expectedType: 'string', + trim: true + }; + return extractValue(spec, console); + } + + function processOrientationMember(aManifest) { + const spec = { + objectName: 'manifest', + object: aManifest, + property: 'orientation', + expectedType: 'string', + trim: true + }; + const value = extractValue(spec, console); + if (ManifestProcessor.orientationTypes.has(value)) { + return value; + } + // The spec special-cases orientation to return the empty string. + return ''; + } + + function processDisplayMember(aManifest) { + const spec = { + objectName: 'manifest', + object: aManifest, + property: 'display', + expectedType: 'string', + trim: true + }; + const value = extractValue(spec, console); + if (ManifestProcessor.displayModes.has(value)) { + return value; + } + return ManifestProcessor.defaultDisplayMode; + } + + function processScopeMember(aManifest, aManifestURL, aDocURL, aStartURL) { + const spec = { + objectName: 'manifest', + object: aManifest, property: 'scope', expectedType: 'string', - dontTrim: true - }, - value = extractValue(spec); - let scopeURL; - try { - scopeURL = new URL(value, manifestURL); - } catch (e) { - let msg = 'The URL of scope is invalid.'; - issueDeveloperWarning(msg); - return undefined; - } - - if (scopeURL.origin !== docURL.origin) { - let msg = 'Scope needs to be same-origin as Document.'; - issueDeveloperWarning(msg); - return undefined; - } - - //If start URL is not within scope of scope URL: - if (startURL && startURL.origin !== scopeURL.origin || !startURL.pathname.startsWith(scopeURL.pathname)) { - let msg = 'The start URL is outside the scope, so scope is invalid.'; - issueDeveloperWarning(msg); - return undefined; - } - return scopeURL; - } - - function processStartURLMember(manifest, manifestURL, docURL) { - const obj = { - objectName: 'manifest', - object: manifest, - property: 'start_url', - expectedType: 'string' - }; - - let value = extractValue(obj), - result = new URL(docURL), - targetURI = makeURI(result), - sameOrigin = false, - potentialResult, - referrerURI; - - if (value === undefined || value === '') { - return result; - } - - try { - potentialResult = new URL(value, manifestURL); - } catch (e) { - issueDeveloperWarning('Invalid URL.'); - return result; - } - referrerURI = makeURI(potentialResult); - try { - securityManager.checkSameOriginURI(referrerURI, targetURI, false); - sameOrigin = true; - } catch (e) {} - if (!sameOrigin) { - let msg = 'start_url must be same origin as document.'; - issueDeveloperWarning(msg); - } else { - result = potentialResult; - } - return result; - - //Converts a URL to a Gecko URI - function makeURI(webURL) { - return imports.Services.io.newURI(webURL.toString(), null, null); - } - } - - //Constants used by IconsProcessor - const onlyDecimals = /^\d+$/, - anyRegEx = new RegExp('any', 'i'); - - function IconsProcessor() {} - IconsProcessor.prototype.processIcons = function(manifest, baseURL) { - const obj = { - objectName: 'manifest', - object: manifest, - property: 'icons', - expectedType: 'array' - }, - icons = []; - let value = extractValue(obj); - - if (Array.isArray(value)) { - //filter out icons with no "src" or src is empty string - let processableIcons = value.filter( - icon => icon && Object.prototype.hasOwnProperty.call(icon, 'src') && icon.src !== '' - ); - for (let potentialIcon of processableIcons) { - let src = processSrcMember(potentialIcon, baseURL) - if(src !== undefined){ - let icon = { - src: src, - type: processTypeMember(potentialIcon), - sizes: processSizesMember(potentialIcon), - density: processDensityMember(potentialIcon) - }; - icons.push(icon); - } + trim: false + }; + const value = extractValue(spec, console); + let scopeURL; + try { + scopeURL = new URL(value, aManifestURL); + } catch (e) { + let msg = 'The URL of scope is invalid.'; + console.warn(msg); + return undefined; } + if (scopeURL.origin !== aDocURL.origin) { + let msg = 'Scope needs to be same-origin as Document.'; + console.warn(msg); + return undefined; + } + // If start URL is not within scope of scope URL: + let isSameOrigin = aStartURL && aStartURL.origin !== scopeURL.origin; + if (isSameOrigin || !aStartURL.pathname.startsWith(scopeURL.pathname)) { + let msg = + 'The start URL is outside the scope, so scope is invalid.'; + console.warn(msg); + return undefined; + } + return scopeURL; + } + + function processStartURLMember(aManifest, aManifestURL, aDocURL) { + const spec = { + objectName: 'manifest', + object: aManifest, + property: 'start_url', + expectedType: 'string', + trim: false + }; + let result = new URL(aDocURL); + const value = extractValue(spec, console); + if (value === undefined || value === '') { + return result; + } + let potentialResult; + try { + potentialResult = new URL(value, aManifestURL); + } catch (e) { + console.warn('Invalid URL.'); + return result; + } + if (potentialResult.origin !== aDocURL.origin) { + let msg = 'start_url must be same origin as document.'; + console.warn(msg); + } else { + result = potentialResult; + } + return result; + } + } +} +this.ManifestProcessor = ManifestProcessor; + +class IconsProcessor { + + constructor() { + throw new Error('Static use only.'); + } + + static get onlyDecimals() { + return /^\d+$/; + } + + static get anyRegEx() { + return new RegExp('any', 'i'); + } + + static process(aManifest, aBaseURL, console) { + const spec = { + objectName: 'manifest', + object: aManifest, + property: 'icons', + expectedType: 'array', + trim: false + }; + const icons = []; + const value = extractValue(spec, console); + if (Array.isArray(value)) { + // Filter out icons whose "src" is not useful. + value.filter(item => !!processSrcMember(item, aBaseURL)) + .map(toIconObject) + .forEach(icon => icons.push(icon)); } return icons; - function processTypeMember(icon) { - const charset = {}, - hadCharset = {}, - obj = { - objectName: 'icon', - object: icon, - property: 'type', - expectedType: 'string' - }; - let value = extractValue(obj), - isParsable = (typeof value === 'string' && value.length > 0); - value = (isParsable) ? netutil.parseContentType(value.trim(), charset, hadCharset) : undefined; - return (value === '') ? undefined : value; + function toIconObject(aIconData) { + return { + src: processSrcMember(aIconData, aBaseURL), + type: processTypeMember(aIconData), + sizes: processSizesMember(aIconData), + density: processDensityMember(aIconData) + }; } - function processDensityMember(icon) { - const hasDensity = Object.prototype.hasOwnProperty.call(icon, 'density'), - rawValue = (hasDensity) ? icon.density : undefined, - value = parseFloat(rawValue), - result = (Number.isNaN(value) || value === +Infinity || value <= 0) ? 1.0 : value; - return result; + function processTypeMember(aIcon) { + const charset = {}; + const hadCharset = {}; + const spec = { + objectName: 'icon', + object: aIcon, + property: 'type', + expectedType: 'string', + trim: true + }; + let value = extractValue(spec, console); + if (value) { + value = imports.netutil.parseContentType(value, charset, hadCharset); + } + return value || undefined; } - function processSrcMember(icon, baseURL) { - const obj = { - objectName: 'icon', - object: icon, - property: 'src', - expectedType: 'string' - }, - value = extractValue(obj); + function processDensityMember(aIcon) { + const value = parseFloat(aIcon.density); + const validNum = Number.isNaN(value) || value === +Infinity || value <= + 0; + return (validNum) ? 1.0 : value; + } + + function processSrcMember(aIcon, aBaseURL) { + const spec = { + objectName: 'icon', + object: aIcon, + property: 'src', + expectedType: 'string', + trim: false + }; + const value = extractValue(spec, console); let url; - if (typeof value === 'string' && value.trim() !== '') { + if (value && value.length) { try { - url = new URL(value, baseURL); + url = new URL(value, aBaseURL); } catch (e) {} } return url; } - function processSizesMember(icon) { + function processSizesMember(aIcon) { const sizes = new Set(), - obj = { + spec = { objectName: 'icon', - object: icon, + object: aIcon, property: 'sizes', - expectedType: 'string' - }; - let value = extractValue(obj); - value = (value) ? value.trim() : value; + expectedType: 'string', + trim: true + }, + value = extractValue(spec, console); if (value) { - //split on whitespace and filter out invalid values - let validSizes = value.split(/\s+/).filter(isValidSizeValue); - validSizes.forEach((size) => sizes.add(size)); + // Split on whitespace and filter out invalid values. + value.split(/\s+/) + .filter(isValidSizeValue) + .forEach(size => sizes.add(size)); } return sizes; - - /* - * Implementation of HTML's link@size attribute checker - */ - function isValidSizeValue(size) { - if (anyRegEx.test(size)) { + // Implementation of HTML's link@size attribute checker. + function isValidSizeValue(aSize) { + const size = aSize.toLowerCase(); + if (IconsProcessor.anyRegEx.test(aSize)) { return true; } - size = size.toLowerCase(); if (!size.contains('x') || size.indexOf('x') !== size.lastIndexOf('x')) { return false; } - - //split left of x for width, after x for height - const width = size.substring(0, size.indexOf('x')); - const height = size.substring(size.indexOf('x') + 1, size.length); - const isValid = !(height.startsWith('0') || width.startsWith('0') || !onlyDecimals.test(width + height)); - return isValid; + // Split left of x for width, after x for height. + const widthAndHeight = size.split('x'); + const w = widthAndHeight.shift(); + const h = widthAndHeight.join('x'); + const validStarts = !w.startsWith('0') && !h.startsWith('0'); + const validDecimals = IconsProcessor.onlyDecimals.test(w + h); + return (validStarts && validDecimals); } } - }; - - function processIconsMember(manifest, manifestURL) { - const iconsProcessor = new IconsProcessor(); - return iconsProcessor.processIcons(manifest, manifestURL); } - - //Processing starts here! - let manifest = {}; - - try { - manifest = JSON.parse(jsonText); - if (typeof manifest !== 'object' || manifest === null) { - let msg = 'Manifest needs to be an object.'; - issueDeveloperWarning(msg); - manifest = {}; - } - } catch (e) { - issueDeveloperWarning(e); - } - - const processedManifest = { - start_url: processStartURLMember(manifest, manifestURL, docURL), - display: processDisplayMember(manifest), - orientation: processOrientationMember(manifest), - name: processNameMember(manifest), - icons: processIconsMember(manifest, manifestURL), - short_name: processShortNameMember(manifest) - }; - processedManifest.scope = processScopeMember(manifest, manifestURL, docURL, processedManifest.start_url); - return processedManifest; -}; \ No newline at end of file +} diff --git a/dom/manifest/test/common.js b/dom/manifest/test/common.js index 7b0cf35f812..422a033c77f 100644 --- a/dom/manifest/test/common.js +++ b/dom/manifest/test/common.js @@ -16,5 +16,5 @@ const bsp = SpecialPowers.Cu.import('resource://gre/modules/ManifestProcessor.js data = { jsonText: '{}', manifestURL: manifestURL, - docLocation: docLocation + docURL: docLocation }; diff --git a/dom/media/DecoderTraits.cpp b/dom/media/DecoderTraits.cpp index 806b8073b9f..93c0b6caad9 100644 --- a/dom/media/DecoderTraits.cpp +++ b/dom/media/DecoderTraits.cpp @@ -221,6 +221,7 @@ static const char* const gOmxTypes[] = { "audio/mp4", "audio/amr", "audio/3gpp", + "audio/flac", "video/mp4", "video/3gpp", "video/3gpp2", diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp index 39876d1bc22..2e981a383ce 100644 --- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -1418,7 +1418,11 @@ NS_IMPL_ISUPPORTS(MediaManager, nsIMediaManagerService, nsIObserver) MediaManager::Get() { if (!sSingleton) { NS_ASSERTION(NS_IsMainThread(), "Only create MediaManager on main thread"); - +#ifdef DEBUG + static int timesCreated = 0; + timesCreated++; + MOZ_ASSERT(timesCreated == 1); +#endif sSingleton = new MediaManager(); sSingleton->mMediaThread = new base::Thread("MediaManager"); @@ -1454,6 +1458,11 @@ MediaManager::Get() { return sSingleton; } +/* static */ MediaManager* +MediaManager::GetIfExists() { + return sSingleton; +} + /* static */ already_AddRefed MediaManager::GetInstance() { diff --git a/dom/media/MediaManager.h b/dom/media/MediaManager.h index a8fc867c11a..f4ae26edaf8 100644 --- a/dom/media/MediaManager.h +++ b/dom/media/MediaManager.h @@ -554,6 +554,7 @@ public: // thread from the MainThread, as we NS_DISPATCH_SYNC to MainThread // from MediaManager thread. static MediaManager* Get(); + static MediaManager* GetIfExists(); static MessageLoop* GetMessageLoop(); static bool Exists() diff --git a/dom/media/fmp4/gmp/GMPVideoDecoder.cpp b/dom/media/fmp4/gmp/GMPVideoDecoder.cpp index 447aab4873a..cb4b65a9024 100644 --- a/dom/media/fmp4/gmp/GMPVideoDecoder.cpp +++ b/dom/media/fmp4/gmp/GMPVideoDecoder.cpp @@ -6,6 +6,7 @@ #include "GMPVideoDecoder.h" #include "GMPVideoHost.h" +#include "mozilla/Endian.h" #include "prsystem.h" namespace mozilla { @@ -132,13 +133,26 @@ GMPVideoDecoder::CreateFrame(mp4_demuxer::MP4Sample* aSample) memcpy(frame->Buffer(), aSample->data, frame->Size()); + // Convert 4-byte NAL unit lengths to host-endian 4-byte buffer lengths to + // suit the GMP API. + if (mConvertNALUnitLengths) { + const int kNALLengthSize = 4; + uint8_t* buf = frame->Buffer(); + while (buf < frame->Buffer() + frame->Size() - kNALLengthSize) { + uint32_t length = BigEndian::readUint32(buf) + kNALLengthSize; + *reinterpret_cast(buf) = length; + buf += length; + } + } + + frame->SetBufferType(GMP_BufferLength32); + frame->SetEncodedWidth(mConfig.display_width); frame->SetEncodedHeight(mConfig.display_height); frame->SetTimeStamp(aSample->composition_timestamp); frame->SetCompleteFrame(true); frame->SetDuration(aSample->duration); frame->SetFrameType(aSample->is_sync_point ? kGMPKeyFrame : kGMPDeltaFrame); - frame->SetBufferType(GMP_BufferLength32); return frame; } @@ -157,6 +171,16 @@ GMPVideoDecoder::Init() NS_ENSURE_SUCCESS(rv, rv); MOZ_ASSERT(mHost && mGMP); + // GMP implementations have interpreted the meaning of GMP_BufferLength32 + // differently. The OpenH264 GMP expects GMP_BufferLength32 to behave as + // specified in the GMP API, where each buffer is prefixed by a 32-bit + // host-endian buffer length that includes the size of the buffer length + // field. Other existing GMPs currently expect GMP_BufferLength32 (when + // combined with kGMPVideoCodecH264) to mean "like AVCC but restricted to + // 4-byte NAL lengths" (i.e. buffer lengths are specified in big-endian + // and do not include the length of the buffer length field. + mConvertNALUnitLengths = mGMP->GetDisplayName().EqualsLiteral("gmpopenh264"); + GMPVideoCodec codec; memset(&codec, 0, sizeof(codec)); diff --git a/dom/media/fmp4/gmp/GMPVideoDecoder.h b/dom/media/fmp4/gmp/GMPVideoDecoder.h index de45bb431ea..3f76dfdebf6 100644 --- a/dom/media/fmp4/gmp/GMPVideoDecoder.h +++ b/dom/media/fmp4/gmp/GMPVideoDecoder.h @@ -62,6 +62,7 @@ protected: , mGMP(nullptr) , mHost(nullptr) , mAdapter(aAdapter) + , mConvertNALUnitLengths(false) { } @@ -79,6 +80,7 @@ public: VideoInfo(aConfig.display_width, aConfig.display_height), aImageContainer)) + , mConvertNALUnitLengths(false) { } @@ -100,9 +102,9 @@ private: GMPVideoDecoderProxy* mGMP; GMPVideoHost* mHost; nsAutoPtr mAdapter; + bool mConvertNALUnitLengths; }; - } // namespace mozilla #endif // GMPVideoDecoder_h_ diff --git a/dom/media/gmp/GMPParent.cpp b/dom/media/gmp/GMPParent.cpp index cae2d814737..351234bf957 100644 --- a/dom/media/gmp/GMPParent.cpp +++ b/dom/media/gmp/GMPParent.cpp @@ -34,25 +34,18 @@ using CrashReporter::GetIDFromMinidump; namespace mozilla { -#ifdef LOG #undef LOG -#endif +#undef LOGD #ifdef PR_LOGGING extern PRLogModuleInfo* GetGMPLog(); - -#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg) -#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg) +#define LOG(level, x, ...) PR_LOG(GetGMPLog(), (level), (x, ##__VA_ARGS__)) +#define LOGD(x, ...) LOG(PR_LOG_DEBUG, "GMPParent[%p|childPid=%d] " x, this, mChildPid, ##__VA_ARGS__) #else -#define LOGD(msg) -#define LOG(level, msg) +#define LOG(level, x, ...) +#define LOGD(x, ...) #endif -#ifdef __CLASS__ -#undef __CLASS__ -#endif -#define __CLASS__ "GMPParent" - namespace gmp { GMPParent::GMPParent() @@ -62,13 +55,18 @@ GMPParent::GMPParent() , mAbnormalShutdownInProgress(false) , mAsyncShutdownRequired(false) , mAsyncShutdownInProgress(false) +#ifdef PR_LOGGING + , mChildPid(0) +#endif { + LOGD("GMPParent ctor"); } GMPParent::~GMPParent() { // Can't Close or Destroy the process here, since destruction is MainThread only MOZ_ASSERT(NS_IsMainThread()); + LOGD("GMPParent dtor"); } void @@ -107,8 +105,7 @@ GMPParent::Init(GeckoMediaPluginService *aService, nsIFile* aPluginDir) if (NS_FAILED(rv)) { return rv; } - LOGD(("%s::%s: %p for %s", __CLASS__, __FUNCTION__, this, - NS_LossyConvertUTF16toASCII(parentLeafName).get())); + LOGD("%s: for %s", __FUNCTION__, NS_LossyConvertUTF16toASCII(parentLeafName).get()); MOZ_ASSERT(parentLeafName.Length() > 4); mName = Substring(parentLeafName, 4); @@ -135,7 +132,7 @@ GMPParent::LoadProcess() if (NS_FAILED(mDirectory->GetPath(path))) { return NS_ERROR_FAILURE; } - LOGD(("%s::%s: %p for %s", __CLASS__, __FUNCTION__, this, path.get())); + LOGD("%s: for %s", __FUNCTION__, NS_ConvertUTF16toUTF8(path).get()); if (!mProcess) { mProcess = new GMPProcessParent(NS_ConvertUTF16toUTF8(path).get()); @@ -145,32 +142,36 @@ GMPParent::LoadProcess() return NS_ERROR_FAILURE; } +#ifdef PR_LOGGING + mChildPid = base::GetProcId(mProcess->GetChildProcessHandle()); +#endif + bool opened = Open(mProcess->GetChannel(), mProcess->GetChildProcessHandle()); if (!opened) { - LOGD(("%s::%s: Failed to create new child process %p", __CLASS__, __FUNCTION__, (void *)mProcess)); + LOGD("%s: Failed to create new child process", __FUNCTION__); mProcess->Delete(); mProcess = nullptr; return NS_ERROR_FAILURE; } - LOGD(("%s::%s: Created new child process %p", __CLASS__, __FUNCTION__, (void *)mProcess)); + LOGD("%s: Created new child process", __FUNCTION__); bool ok = SendSetNodeId(mNodeId); if (!ok) { - LOGD(("%s::%s: Failed to send node id to child process %p", __CLASS__, __FUNCTION__, (void *)mProcess)); + LOGD("%s: Failed to send node id to child process", __FUNCTION__); mProcess->Delete(); mProcess = nullptr; return NS_ERROR_FAILURE; } - LOGD(("%s::%s: Sent node id to child process %p", __CLASS__, __FUNCTION__, (void *)mProcess)); + LOGD("%s: Sent node id to child process", __FUNCTION__); ok = SendStartPlugin(); if (!ok) { - LOGD(("%s::%s: Failed to send start to child process %p", __CLASS__, __FUNCTION__, (void *)mProcess)); + LOGD("%s: Failed to send start to child process", __FUNCTION__); mProcess->Delete(); mProcess = nullptr; return NS_ERROR_FAILURE; } - LOGD(("%s::%s: Sent StartPlugin to child process %p", __CLASS__, __FUNCTION__, (void *)mProcess)); + LOGD("%s: Sent StartPlugin to child process", __FUNCTION__); } mState = GMPStateLoaded; @@ -225,8 +226,7 @@ void GMPParent::CloseIfUnused() { MOZ_ASSERT(GMPThread() == NS_GetCurrentThread()); - LOGD(("%s::%s: %p mAsyncShutdownRequired=%d", __CLASS__, __FUNCTION__, this, - mAsyncShutdownRequired)); + LOGD("%s: mAsyncShutdownRequired=%d", __FUNCTION__, mAsyncShutdownRequired); if ((mDeleteProcessOnlyOnUnload || mState == GMPStateLoaded || @@ -243,8 +243,7 @@ GMPParent::CloseIfUnused() if (mAsyncShutdownRequired) { if (!mAsyncShutdownInProgress) { - LOGD(("%s::%s: %p sending async shutdown notification", __CLASS__, - __FUNCTION__, this)); + LOGD("%s: sending async shutdown notification", __FUNCTION__); mAsyncShutdownInProgress = true; if (!SendBeginAsyncShutdown() || NS_FAILED(EnsureAsyncShutdownTimeoutSet())) { @@ -265,7 +264,7 @@ void GMPParent::AbortAsyncShutdown() { MOZ_ASSERT(GMPThread() == NS_GetCurrentThread()); - LOGD(("%s::%s: %p", __CLASS__, __FUNCTION__, this)); + LOGD("%s", __FUNCTION__); if (mAsyncShutdownTimeout) { mAsyncShutdownTimeout->Cancel(); @@ -299,7 +298,7 @@ GMPParent::AudioDecoderDestroyed(GMPAudioDecoderParent* aDecoder) void GMPParent::CloseActive(bool aDieWhenUnloaded) { - LOGD(("%s::%s: %p state %d", __CLASS__, __FUNCTION__, this, mState)); + LOGD("%s: state %d", __FUNCTION__, mState); if (aDieWhenUnloaded) { mDeleteProcessOnlyOnUnload = true; // don't allow this to go back... } @@ -339,7 +338,7 @@ GMPParent::CloseActive(bool aDieWhenUnloaded) void GMPParent::Shutdown() { - LOGD(("%s::%s: %p", __CLASS__, __FUNCTION__, this)); + LOGD("%s", __FUNCTION__); MOZ_ASSERT(GMPThread() == NS_GetCurrentThread()); MOZ_ASSERT(!mAsyncShutdownTimeout, "Should have canceled shutdown timeout"); @@ -384,7 +383,7 @@ public: void GMPParent::DeleteProcess() { - LOGD(("%s::%s: %p", __CLASS__, __FUNCTION__, this)); + LOGD("%s", __FUNCTION__); if (mState != GMPStateClosing) { // Don't Close() twice! @@ -393,7 +392,7 @@ GMPParent::DeleteProcess() Close(); } mProcess->Delete(); - LOGD(("%s::%s: Shut down process %p", __CLASS__, __FUNCTION__, (void *) mProcess)); + LOGD("%s: Shut down process", __FUNCTION__); mProcess = nullptr; mState = GMPStateNotLoaded; @@ -654,7 +653,7 @@ GMPNotifyObservers(nsAString& aData) void GMPParent::ActorDestroy(ActorDestroyReason aWhy) { - LOGD(("%s::%s: %p (%d)", __CLASS__, __FUNCTION__, this, (int) aWhy)); + LOGD("%s: (%d)", __FUNCTION__, (int)aWhy); #ifdef MOZ_CRASHREPORTER if (AbnormalShutdown == aWhy) { Telemetry::Accumulate(Telemetry::SUBPROCESS_ABNORMAL_ABORT, @@ -1002,6 +1001,12 @@ GMPParent::SetNodeId(const nsACString& aNodeId) mNodeId = aNodeId; } +const nsCString& +GMPParent::GetDisplayName() const +{ + return mDisplayName; +} + const nsCString& GMPParent::GetVersion() const { @@ -1011,7 +1016,7 @@ GMPParent::GetVersion() const bool GMPParent::RecvAsyncShutdownRequired() { - LOGD(("%s::%s: %p", __CLASS__, __FUNCTION__, this)); + LOGD("%s", __FUNCTION__); if (mAsyncShutdownRequired) { NS_WARNING("Received AsyncShutdownRequired message more than once!"); return true; @@ -1024,7 +1029,7 @@ GMPParent::RecvAsyncShutdownRequired() bool GMPParent::RecvAsyncShutdownComplete() { - LOGD(("%s::%s: %p", __CLASS__, __FUNCTION__, this)); + LOGD("%s", __FUNCTION__); MOZ_ASSERT(mAsyncShutdownRequired); AbortAsyncShutdown(); @@ -1033,3 +1038,6 @@ GMPParent::RecvAsyncShutdownComplete() } // namespace gmp } // namespace mozilla + +#undef LOG +#undef LOGD diff --git a/dom/media/gmp/GMPParent.h b/dom/media/gmp/GMPParent.h index a91c99829c7..9683f84c835 100644 --- a/dom/media/gmp/GMPParent.h +++ b/dom/media/gmp/GMPParent.h @@ -115,6 +115,7 @@ public: void SetNodeId(const nsACString& aNodeId); const nsACString& GetNodeId() const { return mNodeId; } + const nsCString& GetDisplayName() const; const nsCString& GetVersion() const; // Returns true if a plugin can be or is being used across multiple NodeIds. @@ -198,6 +199,10 @@ private: bool mAsyncShutdownRequired; bool mAsyncShutdownInProgress; + +#ifdef PR_LOGGING + int mChildPid; +#endif }; } // namespace gmp diff --git a/dom/media/gmp/GMPStorageParent.cpp b/dom/media/gmp/GMPStorageParent.cpp index 5274e8b8ec7..4f06fcb370f 100644 --- a/dom/media/gmp/GMPStorageParent.cpp +++ b/dom/media/gmp/GMPStorageParent.cpp @@ -39,7 +39,7 @@ extern PRLogModuleInfo* GetGMPLog(); #ifdef __CLASS__ #undef __CLASS__ #endif -#define __CLASS__ "GMPParent" +#define __CLASS__ "GMPStorageParent" namespace gmp { diff --git a/dom/media/gmp/GMPVideoDecoderParent.cpp b/dom/media/gmp/GMPVideoDecoderParent.cpp index 49bdf271310..d5d157eb6cc 100644 --- a/dom/media/gmp/GMPVideoDecoderParent.cpp +++ b/dom/media/gmp/GMPVideoDecoderParent.cpp @@ -182,6 +182,18 @@ GMPVideoDecoderParent::Drain() return NS_OK; } +const nsCString& +GMPVideoDecoderParent::GetDisplayName() const +{ + if (!mIsOpen) { + NS_WARNING("Trying to use an dead GMP video decoder"); + } + + MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread()); + + return mPlugin->GetDisplayName(); +} + // Note: Consider keeping ActorDestroy sync'd up when making changes here. nsresult GMPVideoDecoderParent::Shutdown() diff --git a/dom/media/gmp/GMPVideoDecoderParent.h b/dom/media/gmp/GMPVideoDecoderParent.h index bce39a83c0f..e79135530a6 100644 --- a/dom/media/gmp/GMPVideoDecoderParent.h +++ b/dom/media/gmp/GMPVideoDecoderParent.h @@ -45,6 +45,7 @@ public: virtual nsresult Reset() MOZ_OVERRIDE; virtual nsresult Drain() MOZ_OVERRIDE; virtual const uint64_t ParentID() MOZ_OVERRIDE { return reinterpret_cast(mPlugin.get()); } + virtual const nsCString& GetDisplayName() const MOZ_OVERRIDE; // GMPSharedMemManager virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem) MOZ_OVERRIDE diff --git a/dom/media/gmp/GMPVideoDecoderProxy.h b/dom/media/gmp/GMPVideoDecoderProxy.h index 1677f9a59a5..f4d344ac8d8 100644 --- a/dom/media/gmp/GMPVideoDecoderProxy.h +++ b/dom/media/gmp/GMPVideoDecoderProxy.h @@ -49,6 +49,8 @@ public: // Call to tell GMP/plugin the consumer will no longer use this // interface/codec. virtual void Close() = 0; + + virtual const nsCString& GetDisplayName() const = 0; }; #endif diff --git a/dom/media/test/manifest.js b/dom/media/test/manifest.js index ab750fdde92..b363a4944e2 100644 --- a/dom/media/test/manifest.js +++ b/dom/media/test/manifest.js @@ -9,6 +9,7 @@ var gSmallTests = [ { name:"small-shot.m4a", type:"audio/mp4", duration:0.29 }, { name:"small-shot.mp3", type:"audio/mpeg", duration:0.27 }, { name:"small-shot-mp3.mp4", type:"audio/mp4; codecs=mp3", duration:0.34 }, + { name:"small-shot.flac", type:"audio/flac", duration:0.197 }, { name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 }, { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266 }, { name:"seek.webm", type:"video/webm", width:320, height:240, duration:3.966 }, diff --git a/dom/media/test/mochitest.ini b/dom/media/test/mochitest.ini index 5644e2cffdc..090a9084a99 100644 --- a/dom/media/test/mochitest.ini +++ b/dom/media/test/mochitest.ini @@ -247,6 +247,7 @@ support-files = small-shot.mp3^headers^ small-shot.ogg small-shot.ogg^headers^ + small-shot.flac sound.ogg sound.ogg^headers^ spacestorm-1000Hz-100ms.ogg diff --git a/dom/media/test/small-shot.flac b/dom/media/test/small-shot.flac new file mode 100644 index 00000000000..0da7c9044e5 Binary files /dev/null and b/dom/media/test/small-shot.flac differ diff --git a/dom/media/tests/mochitest/pc.js b/dom/media/tests/mochitest/pc.js index 4b8c183b230..37d8c610537 100644 --- a/dom/media/tests/mochitest/pc.js +++ b/dom/media/tests/mochitest/pc.js @@ -742,9 +742,9 @@ function PeerConnectionWrapper(label, configuration, h264) { this.remoteRequiresTrickleIce = false; this.localMediaElements = []; - this.expectedLocalTrackTypesById = {}; - this.expectedRemoteTrackTypesById = {}; - this.observedRemoteTrackTypesById = {}; + this.expectedLocalTrackInfoById = {}; + this.expectedRemoteTrackInfoById = {}; + this.observedRemoteTrackInfoById = {}; this.disableRtpCountChecking = false; @@ -875,7 +875,10 @@ PeerConnectionWrapper.prototype = { stream.getTracks().forEach(track => { ok(track.id, "track has id"); ok(track.kind, "track has kind"); - this.expectedLocalTrackTypesById[track.id] = track.kind; + this.expectedLocalTrackInfoById[track.id] = { + type: track.kind, + streamId: stream.id + }; }); } @@ -893,14 +896,17 @@ PeerConnectionWrapper.prototype = { removeSender : function(index) { var sender = this._pc.getSenders()[index]; - delete this.expectedLocalTrackTypesById[sender.track.id]; + delete this.expectedLocalTrackInfoById[sender.track.id]; this._pc.removeTrack(sender); }, - senderReplaceTrack : function(index, withTrack) { + senderReplaceTrack : function(index, withTrack, withStreamId) { var sender = this._pc.getSenders()[index]; - delete this.expectedLocalTrackTypesById[sender.track.id]; - this.expectedLocalTrackTypesById[withTrack.id] = withTrack.kind; + delete this.expectedLocalTrackInfoById[sender.track.id]; + this.expectedLocalTrackInfoById[withTrack.id] = { + type: withTrack.kind, + streamId: withStreamId + }; return sender.replaceTrack(withTrack); }, @@ -1081,20 +1087,23 @@ PeerConnectionWrapper.prototype = { /** * Checks whether a given track is expected, has not been observed yet, and * is of the correct type. Then, moves the track from - * |expectedTrackTypesById| to |observedTrackTypesById|. + * |expectedTrackInfoById| to |observedTrackInfoById|. */ checkTrackIsExpected : function(track, - expectedTrackTypesById, - observedTrackTypesById) { - ok(expectedTrackTypesById[track.id], "track id " + track.id + " was expected"); - ok(!observedTrackTypesById[track.id], "track id " + track.id + " was not yet observed"); + expectedTrackInfoById, + observedTrackInfoById) { + ok(expectedTrackInfoById[track.id], "track id " + track.id + " was expected"); + ok(!observedTrackInfoById[track.id], "track id " + track.id + " was not yet observed"); var observedKind = track.kind; - var expectedKind = expectedTrackTypesById[track.id]; + var expectedKind = expectedTrackInfoById[track.id].type; is(observedKind, expectedKind, "track id " + track.id + " was of kind " + observedKind + ", which matches " + expectedKind); - observedTrackTypesById[track.id] = expectedTrackTypesById[track.id]; - delete expectedTrackTypesById[track.id]; + observedTrackInfoById[track.id] = expectedTrackInfoById[track.id]; + }, + + allExpectedTracksAreObserved: function(expected, observed) { + return Object.keys(expected).every(trackId => observed[trackId]); }, setupAddStreamEventHandler: function() { @@ -1112,11 +1121,12 @@ PeerConnectionWrapper.prototype = { event.stream.getTracks().forEach(track => { this.checkTrackIsExpected(track, - this.expectedRemoteTrackTypesById, - this.observedRemoteTrackTypesById); + this.expectedRemoteTrackInfoById, + this.observedRemoteTrackInfoById); }); - if (Object.keys(this.expectedRemoteTrackTypesById).length === 0) { + if (this.allExpectedTracksAreObserved(this.expectedRemoteTrackInfoById, + this.observedRemoteTrackInfoById)) { resolveAllAddStreamEventsDone(); } @@ -1363,24 +1373,14 @@ PeerConnectionWrapper.prototype = { }, checkLocalMediaTracks : function() { - var observedLocalTrackTypesById = {}; - // We do not want to empty out this.expectedLocalTrackTypesById, so make a - // copy. - var expectedLocalTrackTypesById = - JSON.parse(JSON.stringify((this.expectedLocalTrackTypesById))); - info(this + " Checking local tracks " + - JSON.stringify(expectedLocalTrackTypesById)); - this._pc.getLocalStreams().forEach(stream => { - stream.getTracks().forEach(track => { - this.checkTrackIsExpected(track, - expectedLocalTrackTypesById, - observedLocalTrackTypesById); - }); + var observed = {}; + info(this + " Checking local tracks " + JSON.stringify(this.expectedLocalTrackInfoById)); + this._pc.getSenders().forEach(sender => { + this.checkTrackIsExpected(sender.track, this.expectedLocalTrackInfoById, observed); }); - Object.keys(expectedLocalTrackTypesById).forEach(id => { - ok(false, this + " local id " + id + " was observed"); - }); + Object.keys(this.expectedLocalTrackInfoById).forEach( + id => ok(observed[id], this + " local id " + id + " was observed")); }, /** @@ -1393,10 +1393,11 @@ PeerConnectionWrapper.prototype = { this.checkLocalMediaTracks(); info(this + " Checking remote tracks " + - JSON.stringify(this.expectedRemoteTrackTypesById)); + JSON.stringify(this.expectedRemoteTrackInfoById)); // No tracks are expected - if (Object.keys(this.expectedRemoteTrackTypesById).length === 0) { + if (this.allExpectedTracksAreObserved(this.expectedRemoteTrackInfoById, + this.observedRemoteTrackInfoById)) { return; } @@ -1404,19 +1405,18 @@ PeerConnectionWrapper.prototype = { }, checkMsids: function() { - var checkSdpForMsids = (desc, streams, side) => { - streams.forEach(stream => { - stream.getTracks().forEach(track => { - ok(desc.sdp.match(new RegExp("a=msid:" + stream.id + " " + track.id)), - this + ": " + side + " SDP contains stream " + stream.id + - " and track " + track.id ); - }); + var checkSdpForMsids = (desc, expectedTrackInfo, side) => { + Object.keys(expectedTrackInfo).forEach(trackId => { + var streamId = expectedTrackInfo[trackId].streamId; + ok(desc.sdp.match(new RegExp("a=msid:" + streamId + " " + trackId)), + this + ": " + side + " SDP contains stream " + streamId + + " and track " + trackId ); }); }; - checkSdpForMsids(this.localDescription, this._pc.getLocalStreams(), + checkSdpForMsids(this.localDescription, this.expectedLocalTrackInfoById, "local"); - checkSdpForMsids(this.remoteDescription, this._pc.getRemoteStreams(), + checkSdpForMsids(this.remoteDescription, this.expectedRemoteTrackInfoById, "remote"); }, @@ -1507,11 +1507,6 @@ PeerConnectionWrapper.prototype = { */ checkStats : function(stats, twoMachines) { var toNum = obj => obj? obj : 0; - var numTracks = streams => - streams.reduce((count, stream) => count + - stream.getAudioTracks().length + - stream.getVideoTracks().length, - 0); const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1; @@ -1599,8 +1594,8 @@ PeerConnectionWrapper.prototype = { }); is(JSON.stringify(counters), JSON.stringify(counters2), "Spec and MapClass variant of RTCStatsReport enumeration agree"); - var nin = numTracks(this._pc.getRemoteStreams()); - var nout = numTracks(this._pc.getLocalStreams()); + var nin = Object.keys(this.expectedRemoteTrackInfoById).length; + var nout = Object.keys(this.expectedLocalTrackInfoById).length; var ndata = this.dataChannels.length; // TODO(Bug 957145): Restore stronger inboundrtp test once Bug 948249 is fixed diff --git a/dom/media/tests/mochitest/templates.js b/dom/media/tests/mochitest/templates.js index baadccaf3b0..d3b401c8b2e 100644 --- a/dom/media/tests/mochitest/templates.js +++ b/dom/media/tests/mochitest/templates.js @@ -106,36 +106,32 @@ function waitForAnIceCandidate(pc) { }); } -function checkTrackStats(pc, audio, outbound) { - var stream = outbound ? pc._pc.getLocalStreams()[0] : pc._pc.getRemoteStreams()[0]; - if (!stream) { - return Promise.resolve(); - } - var track = audio ? stream.getAudioTracks()[0] : stream.getVideoTracks()[0]; - if (!track) { - return Promise.resolve(); - } +function checkTrackStats(pc, rtpSenderOrReceiver, outbound) { + var track = rtpSenderOrReceiver.track; + var audio = (track.kind == "audio"); var msg = pc + " stats " + (outbound ? "outbound " : "inbound ") + - (audio ? "audio" : "video") + " rtp "; + (audio ? "audio" : "video") + " rtp track id " + track.id; return pc.getStats(track).then(stats => { ok(pc.hasStat(stats, { type: outbound ? "outboundrtp" : "inboundrtp", isRemote: false, mediaType: audio ? "audio" : "video" - }), msg + "1"); + }), msg + " - found expected stats"); ok(!pc.hasStat(stats, { type: outbound ? "inboundrtp" : "outboundrtp", isRemote: false - }), msg + "2"); + }), msg + " - did not find extra stats with wrong direction"); ok(!pc.hasStat(stats, { mediaType: audio ? "video" : "audio" - }), msg + "3"); + }), msg + " - did not find extra stats with wrong media type"); }); } -// checks all stats combinations inbound/outbound, audio/video -var checkAllTrackStats = pc => - Promise.all([0, 1, 2, 3].map(i => checkTrackStats(pc, i & 1, i & 2))); +var checkAllTrackStats = pc => { + return Promise.all([].concat( + pc._pc.getSenders().map(sender => checkTrackStats(pc, sender, true)), + pc._pc.getReceivers().map(receiver => checkTrackStats(pc, receiver, false)))); +} // Commands run once at the beginning of each test, even when performing a // renegotiation test. @@ -246,14 +242,14 @@ var commandsPeerConnectionOfferAnswer = [ function PC_LOCAL_STEEPLECHASE_SIGNAL_EXPECTED_LOCAL_TRACKS(test) { if (test.steeplechase) { send_message({"type": "local_expected_tracks", - "expected_tracks": test.pcLocal.expectedLocalTrackTypesById}); + "expected_tracks": test.pcLocal.expectedLocalTrackInfoById}); } }, function PC_REMOTE_STEEPLECHASE_SIGNAL_EXPECTED_LOCAL_TRACKS(test) { if (test.steeplechase) { send_message({"type": "remote_expected_tracks", - "expected_tracks": test.pcRemote.expectedLocalTrackTypesById}); + "expected_tracks": test.pcRemote.expectedLocalTrackInfoById}); } }, @@ -261,36 +257,26 @@ var commandsPeerConnectionOfferAnswer = [ if (test.steeplechase) { return test.getSignalingMessage("remote_expected_tracks").then( message => { - test.pcLocal.expectedRemoteTrackTypesById = message.expected_tracks; + test.pcLocal.expectedRemoteTrackInfoById = message.expected_tracks; }); - } else { - // Deep copy, as similar to steeplechase as possible - test.pcLocal.expectedRemoteTrackTypesById = - JSON.parse(JSON.stringify((test.pcRemote.expectedLocalTrackTypesById))); } - // Remove what we've already observed - Object.keys(test.pcLocal.observedRemoteTrackTypesById).forEach(id => { - delete test.pcLocal.expectedRemoteTrackTypesById[id]; - }); + // Deep copy, as similar to steeplechase as possible + test.pcLocal.expectedRemoteTrackInfoById = + JSON.parse(JSON.stringify(test.pcRemote.expectedLocalTrackInfoById)); }, function PC_REMOTE_GET_EXPECTED_REMOTE_TRACKS(test) { if (test.steeplechase) { return test.getSignalingMessage("local_expected_tracks").then( message => { - test.pcRemote.expectedRemoteTrackTypesById = message.expected_tracks; + test.pcRemote.expectedRemoteTrackInfoById = message.expected_tracks; }); - } else { - // Deep copy, as similar to steeplechase as possible - test.pcRemote.expectedRemoteTrackTypesById = - JSON.parse(JSON.stringify((test.pcLocal.expectedLocalTrackTypesById))); } - // Remove what we've already observed - Object.keys(test.pcRemote.observedRemoteTrackTypesById).forEach(id => { - delete test.pcRemote.expectedRemoteTrackTypesById[id]; - }); + // Deep copy, as similar to steeplechase as possible + test.pcRemote.expectedRemoteTrackInfoById = + JSON.parse(JSON.stringify(test.pcLocal.expectedLocalTrackInfoById)); }, function PC_LOCAL_CREATE_OFFER(test) { diff --git a/dom/media/tests/mochitest/test_peerConnection_capturedVideo.html b/dom/media/tests/mochitest/test_peerConnection_capturedVideo.html index 4b5167cbfa1..b225020b74e 100644 --- a/dom/media/tests/mochitest/test_peerConnection_capturedVideo.html +++ b/dom/media/tests/mochitest/test_peerConnection_capturedVideo.html @@ -31,9 +31,12 @@ runNetworkTest(function() { .then(() => { var stream = v1.mozCaptureStreamUntilEnded(); is(stream.getTracks().length, 2, "Captured stream has 2 tracks"); - stream.getTracks().forEach(tr => { - test.pcLocal._pc.addTrack(tr, stream); - test.pcLocal.expectedLocalTrackTypesById[tr.id] = tr.kind; + stream.getTracks().forEach(track => { + test.pcLocal._pc.addTrack(track, stream); + test.pcLocal.expectedLocalTrackInfoById[track.id] = { + type: track.kind, + streamId: stream.id + }; }); test.pcLocal.constraints = [{ video: true, audio:true }]; // fool tests }); diff --git a/dom/media/tests/mochitest/test_peerConnection_replaceVideoThenRenegotiate.html b/dom/media/tests/mochitest/test_peerConnection_replaceVideoThenRenegotiate.html index f7532afffd0..1693e9e78ef 100644 --- a/dom/media/tests/mochitest/test_peerConnection_replaceVideoThenRenegotiate.html +++ b/dom/media/tests/mochitest/test_peerConnection_replaceVideoThenRenegotiate.html @@ -24,7 +24,7 @@ return navigator.mediaDevices.getUserMedia({video:true, fake:true}) .then(newstream => { var newtrack = newstream.getVideoTracks()[0]; - return test.pcLocal.senderReplaceTrack(0, newtrack); + return test.pcLocal.senderReplaceTrack(0, newtrack, newstream.id); }) .then(() => { test.setMediaConstraints([{video: true}, {video: true}], diff --git a/dom/media/webaudio/test/mochitest.ini b/dom/media/webaudio/test/mochitest.ini index faa684228cf..fa5eb8a5f4e 100644 --- a/dom/media/webaudio/test/mochitest.ini +++ b/dom/media/webaudio/test/mochitest.ini @@ -111,7 +111,9 @@ skip-if = toolkit == 'android' # bug 1056706 [test_mediaDecoding.html] [test_mediaElementAudioSourceNode.html] [test_mediaElementAudioSourceNodePassThrough.html] +skip-if = toolkit == 'android' # bug 1145816 [test_mediaElementAudioSourceNodeCrossOrigin.html] +skip-if = toolkit == 'android' # bug 1145816 [test_mediaStreamAudioDestinationNode.html] [test_mediaStreamAudioSourceNode.html] [test_mediaStreamAudioSourceNodeCrossOrigin.html] diff --git a/dom/media/webm/WebMReader.cpp b/dom/media/webm/WebMReader.cpp index 4879f1f6379..73f05e3644d 100644 --- a/dom/media/webm/WebMReader.cpp +++ b/dom/media/webm/WebMReader.cpp @@ -941,8 +941,108 @@ bool WebMReader::DecodeAudioData() return DecodeAudioPacket(holder->mPacket, holder->mOffset); } +bool WebMReader::FilterPacketByTime(int64_t aEndTime, WebMPacketQueue& aOutput) +{ + // Push the video frames to the aOutput which's timestamp is less + // than aEndTime. + while (true) { + nsAutoRef holder(NextPacket(VIDEO)); + if (!holder) { + break; + } + uint64_t tstamp = 0; + int r = nestegg_packet_tstamp(holder->mPacket, &tstamp); + if (r == -1) { + break; + } + uint64_t tstamp_usecs = tstamp / NS_PER_USEC; + if (tstamp_usecs >= (uint64_t)aEndTime) { + PushVideoPacket(holder.disown()); + return true; + } else { + aOutput.PushFront(holder.disown()); + } + } + + return false; +} + +int64_t WebMReader::GetNextKeyframeTime(int64_t aTimeThreshold) +{ + WebMPacketQueue skipPacketQueue; + if (!FilterPacketByTime(aTimeThreshold, skipPacketQueue)) { + // Restore the packets before we return -1. + uint32_t size = skipPacketQueue.GetSize(); + for (uint32_t i = 0; i < size; ++i) { + PushVideoPacket(skipPacketQueue.PopFront()); + } + return -1; + } + + // Find keyframe. + bool foundKeyframe = false; + int64_t keyframeTime = -1; + while (!foundKeyframe) { + nsAutoRef holder(NextPacket(VIDEO)); + if (!holder) { + break; + } + unsigned int count = 0; + int r = nestegg_packet_count(holder->mPacket, &count); + if (r == -1) { + break; + } + uint64_t tstamp = 0; + r = nestegg_packet_tstamp(holder->mPacket, &tstamp); + if (r == -1) { + break; + } + uint64_t tstamp_usecs = tstamp / NS_PER_USEC; + + for (uint32_t i = 0; i < count; ++i) { + unsigned char* data; + size_t length; + r = nestegg_packet_data(holder->mPacket, i, &data, &length); + if (r == -1) { + foundKeyframe = true; + break; + } + vpx_codec_stream_info_t si; + memset(&si, 0, sizeof(si)); + si.sz = sizeof(si); + if (mVideoCodec == NESTEGG_CODEC_VP8) { + vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), data, length, &si); + } else if (mVideoCodec == NESTEGG_CODEC_VP9) { + vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), data, length, &si); + } + if (si.is_kf) { + foundKeyframe = true; + keyframeTime = tstamp_usecs; + break; + } + } + skipPacketQueue.PushFront(holder.disown()); + } + + uint32_t size = skipPacketQueue.GetSize(); + for (uint32_t i = 0; i < size; ++i) { + PushVideoPacket(skipPacketQueue.PopFront()); + } + + return keyframeTime; +} + +bool WebMReader::ShouldSkipVideoFrame(int64_t aTimeThreshold) +{ + return GetNextKeyframeTime(aTimeThreshold) != -1; +} + bool WebMReader::DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold) { + if (!(aKeyframeSkip && ShouldSkipVideoFrame(aTimeThreshold))) { + LOG(PR_LOG_DEBUG, ("Reader [%p]: set the aKeyframeSkip to false.",this)); + aKeyframeSkip = false; + } return mVideoDecoder->DecodeVideoFrame(aKeyframeSkip, aTimeThreshold); } diff --git a/dom/media/webm/WebMReader.h b/dom/media/webm/WebMReader.h index 23bebb0b087..9e8be9189d3 100644 --- a/dom/media/webm/WebMReader.h +++ b/dom/media/webm/WebMReader.h @@ -215,7 +215,15 @@ protected: // Initializes mLayersBackendType if possible. void InitLayersBackendType(); + bool ShouldSkipVideoFrame(int64_t aTimeThreshold); + private: + // Get the timestamp of keyframe greater than aTimeThreshold. + int64_t GetNextKeyframeTime(int64_t aTimeThreshold); + // Push the packets into aOutput which's timestamp is less than aEndTime. + // Return false if we reach the end of stream or something wrong. + bool FilterPacketByTime(int64_t aEndTime, WebMPacketQueue& aOutput); + // libnestegg context for webm container. Access on state machine thread // or decoder thread only. nestegg* mContext; diff --git a/dom/system/NetworkGeolocationProvider.js b/dom/system/NetworkGeolocationProvider.js old mode 100755 new mode 100644 diff --git a/dom/webidl/AnimationPlayer.webidl b/dom/webidl/AnimationPlayer.webidl index cb027f8e39e..2e00fbd1978 100644 --- a/dom/webidl/AnimationPlayer.webidl +++ b/dom/webidl/AnimationPlayer.webidl @@ -24,8 +24,7 @@ interface AnimationPlayer { [SetterThrows, BinaryName="currentTimeAsDouble"] attribute double? currentTime; - /* Not yet implemented - attribute double playbackRate; */ + attribute double playbackRate; [BinaryName="playStateFromJS"] readonly attribute AnimationPlayState playState; [Throws] diff --git a/dom/webidl/FetchEvent.webidl b/dom/webidl/FetchEvent.webidl index 054837d2dbf..66699a2d333 100644 --- a/dom/webidl/FetchEvent.webidl +++ b/dom/webidl/FetchEvent.webidl @@ -18,6 +18,7 @@ interface FetchEvent : Event { readonly attribute boolean isReload; [Throws] void respondWith(Promise r); + [Throws] void respondWith(Response r); }; dictionary FetchEventInit : EventInit { diff --git a/dom/webidl/WorkerDebuggerGlobalScope.webidl b/dom/webidl/WorkerDebuggerGlobalScope.webidl index 7f3fd45fb5b..38fd4eef951 100644 --- a/dom/webidl/WorkerDebuggerGlobalScope.webidl +++ b/dom/webidl/WorkerDebuggerGlobalScope.webidl @@ -6,6 +6,10 @@ [Global=(WorkerDebugger), Exposed=WorkerDebugger] interface WorkerDebuggerGlobalScope : EventTarget { readonly attribute object global; + + void postMessage(DOMString message); + + attribute EventHandler onmessage; }; // So you can debug while you debug diff --git a/dom/wifi/WifiWorker.js b/dom/wifi/WifiWorker.js old mode 100755 new mode 100644 diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp index 38dc2165298..d7db985c8e4 100644 --- a/dom/workers/ServiceWorkerEvents.cpp +++ b/dom/workers/ServiceWorkerEvents.cpp @@ -23,6 +23,8 @@ #include "mozilla/dom/WorkerScope.h" #include "mozilla/dom/workers/bindings/ServiceWorker.h" +#include "WorkerPrivate.h" + using namespace mozilla::dom; BEGIN_WORKERS_NAMESPACE @@ -283,6 +285,26 @@ FetchEvent::RespondWith(Promise& aPromise, ErrorResult& aRv) aPromise.AppendNativeHandler(handler); } +void +FetchEvent::RespondWith(Response& aResponse, ErrorResult& aRv) +{ + if (mWaitToRespond) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return; + } + + WorkerPrivate* worker = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(worker); + worker->AssertIsOnWorkerThread(); + nsRefPtr promise = Promise::Create(worker->GlobalScope(), aRv); + if (NS_WARN_IF(aRv.Failed())) { + return; + } + promise->MaybeResolve(&aResponse); + + RespondWith(*promise, aRv); +} + already_AddRefed FetchEvent::GetClient() { diff --git a/dom/workers/ServiceWorkerEvents.h b/dom/workers/ServiceWorkerEvents.h index 00a43299ebe..38ffe1834d1 100644 --- a/dom/workers/ServiceWorkerEvents.h +++ b/dom/workers/ServiceWorkerEvents.h @@ -11,6 +11,7 @@ #include "mozilla/dom/FetchEventBinding.h" #include "mozilla/dom/InstallEventBinding.h" #include "mozilla/dom/Promise.h" +#include "mozilla/dom/Response.h" #include "nsProxyRelease.h" class nsIInterceptedChannel; @@ -83,6 +84,9 @@ public: void RespondWith(Promise& aPromise, ErrorResult& aRv); + void + RespondWith(Response& aResponse, ErrorResult& aRv); + already_AddRefed ForwardTo(const nsAString& aUrl); diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index d8b017036c0..b8cb9b6037d 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -1295,6 +1295,54 @@ private: } }; +class DebuggerMessageEventRunnable : public WorkerDebuggerRunnable { + nsString mMessage; + +public: + DebuggerMessageEventRunnable(WorkerPrivate* aWorkerPrivate, + const nsAString& aMessage) + : WorkerDebuggerRunnable(aWorkerPrivate), + mMessage(aMessage) + { + } + +private: + virtual bool + WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) MOZ_OVERRIDE + { + WorkerDebuggerGlobalScope* globalScope = aWorkerPrivate->DebuggerGlobalScope(); + MOZ_ASSERT(globalScope); + + JS::Rooted message(aCx, JS_NewUCStringCopyN(aCx, mMessage.get(), + mMessage.Length())); + if (!message) { + return false; + } + JS::Rooted data(aCx, JS::StringValue(message)); + + nsRefPtr event = new MessageEvent(globalScope, nullptr, + nullptr); + nsresult rv = + event->InitMessageEvent(NS_LITERAL_STRING("message"), + false, // canBubble + true, // cancelable + data, + EmptyString(), + EmptyString(), + nullptr); + if (NS_FAILED(rv)) { + xpc::Throw(aCx, rv); + return false; + } + event->SetTrusted(true); + + nsCOMPtr domEvent = do_QueryObject(event); + nsEventStatus status = nsEventStatus_eIgnore; + globalScope->DispatchDOMEvent(nullptr, domEvent, nullptr, &status); + return true; + } +}; + class NotifyRunnable MOZ_FINAL : public WorkerControlRunnable { Status mStatus; @@ -4322,6 +4370,26 @@ WorkerDebugger::Initialize(const nsAString& aURL, JSContext* aCx) return NS_OK; } +NS_IMETHODIMP +WorkerDebugger::PostMessageMoz(const nsAString& aMessage, JSContext* aCx) +{ + AssertIsOnMainThread(); + + MutexAutoLock lock(mMutex); + + if (!mWorkerPrivate || !mIsInitialized) { + return NS_ERROR_UNEXPECTED; + } + + nsRefPtr runnable = + new DebuggerMessageEventRunnable(mWorkerPrivate, aMessage); + if (!runnable->Dispatch(aCx)) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + NS_IMETHODIMP WorkerDebugger::AddListener(nsIWorkerDebuggerListener* aListener) { @@ -4402,6 +4470,35 @@ WorkerDebugger::Disable() NotifyIsEnabled(false); } +void +WorkerDebugger::PostMessageToDebugger(const nsAString& aMessage) +{ + mWorkerPrivate->AssertIsOnWorkerThread(); + + nsCOMPtr runnable = + NS_NewRunnableMethodWithArg(this, + &WorkerDebugger::PostMessageToDebuggerOnMainThread, nsString(aMessage)); + NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL); +} + +void +WorkerDebugger::PostMessageToDebuggerOnMainThread(const nsAString& aMessage) +{ + AssertIsOnMainThread(); + + nsTArray> listeners; + + { + MutexAutoLock lock(mMutex); + + listeners.AppendElements(mListeners); + } + + for (size_t index = 0; index < listeners.Length(); ++index) { + listeners[index]->OnMessage(aMessage); + } +} + WorkerPrivate::WorkerPrivate(JSContext* aCx, WorkerPrivate* aParent, const nsAString& aScriptURL, @@ -6016,6 +6113,12 @@ WorkerPrivate::PostMessageToParentMessagePort( aMessagePortSerial, aRv); } +void +WorkerPrivate::PostMessageToDebugger(const nsAString& aMessage) +{ + mDebugger->PostMessageToDebugger(aMessage); +} + bool WorkerPrivate::NotifyInternal(JSContext* aCx, Status aStatus) { diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index f63dcb46853..a0008828a91 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -738,18 +738,30 @@ public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIWORKERDEBUGGER - void AssertIsOnParentThread(); + void + AssertIsOnParentThread(); - void WaitIsEnabled(bool aIsEnabled); + void + WaitIsEnabled(bool aIsEnabled); - void Enable(); + void + Enable(); - void Disable(); + void + Disable(); + + void + PostMessageToDebugger(const nsAString& aMessage); private: - virtual ~WorkerDebugger(); + virtual + ~WorkerDebugger(); - void NotifyIsEnabled(bool aIsEnabled); + void + NotifyIsEnabled(bool aIsEnabled); + + void + PostMessageToDebuggerOnMainThread(const nsAString& aMessage); }; class WorkerPrivate : public WorkerPrivateParent @@ -950,6 +962,9 @@ public: const Optional>& aTransferable, ErrorResult& aRv); + void + PostMessageToDebugger(const nsAString& aMessage); + bool NotifyInternal(JSContext* aCx, Status aStatus); diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp index 001e758ebe7..1277656e414 100644 --- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -513,6 +513,12 @@ WorkerDebuggerGlobalScope::GetGlobal(JSContext* aCx, aGlobal.set(mWorkerPrivate->GetOrCreateGlobalScope(aCx)->GetWrapper()); } +void +WorkerDebuggerGlobalScope::PostMessage(const nsAString& aMessage) +{ + mWorkerPrivate->PostMessageToDebugger(aMessage); +} + void WorkerDebuggerGlobalScope::Dump(JSContext* aCx, const Optional& aString) const diff --git a/dom/workers/WorkerScope.h b/dom/workers/WorkerScope.h index b13b3da1929..8743e0317d6 100644 --- a/dom/workers/WorkerScope.h +++ b/dom/workers/WorkerScope.h @@ -264,6 +264,11 @@ public: void GetGlobal(JSContext* aCx, JS::MutableHandle aGlobal); + void + PostMessage(const nsAString& aMessage); + + IMPL_EVENT_HANDLER(message) + void Dump(JSContext* aCx, const Optional& aString) const; diff --git a/dom/workers/nsIWorkerDebugger.idl b/dom/workers/nsIWorkerDebugger.idl index 4709be0d165..0d521b4287f 100644 --- a/dom/workers/nsIWorkerDebugger.idl +++ b/dom/workers/nsIWorkerDebugger.idl @@ -2,13 +2,15 @@ interface nsIDOMWindow; -[scriptable, uuid(54fd2dd3-c01b-4f71-888f-462f37a54f57)] +[scriptable, uuid(ead45621-22a7-48ef-b7db-c4252ae3e6cb)] interface nsIWorkerDebuggerListener : nsISupports { void onClose(); + + void onMessage(in DOMString message); }; -[scriptable, builtinclass, uuid(b0ea6da8-8bd9-446a-94e2-2ee979903205)] +[scriptable, builtinclass, uuid(28e0a60c-ff10-446c-8c2a-5fbdc01394ea)] interface nsIWorkerDebugger : nsISupports { const unsigned long TYPE_DEDICATED = 0; @@ -30,6 +32,9 @@ interface nsIWorkerDebugger : nsISupports [implicit_jscontext] void initialize(in DOMString url); + [implicit_jscontext, binaryname(PostMessageMoz)] + void postMessage(in DOMString message); + void addListener(in nsIWorkerDebuggerListener listener); void removeListener(in nsIWorkerDebuggerListener listener); diff --git a/dom/workers/test/WorkerDebugger.postMessage_childWorker.js b/dom/workers/test/WorkerDebugger.postMessage_childWorker.js new file mode 100644 index 00000000000..8cee6809e5f --- /dev/null +++ b/dom/workers/test/WorkerDebugger.postMessage_childWorker.js @@ -0,0 +1,3 @@ +"use strict"; + +self.onmessage = function () {}; diff --git a/dom/workers/test/WorkerDebugger.postMessage_debugger.js b/dom/workers/test/WorkerDebugger.postMessage_debugger.js new file mode 100644 index 00000000000..261dc72e258 --- /dev/null +++ b/dom/workers/test/WorkerDebugger.postMessage_debugger.js @@ -0,0 +1,9 @@ +"use strict" + +onmessage = function (event) { + switch (event.data) { + case "ping": + postMessage("pong"); + break; + } +}; diff --git a/dom/workers/test/WorkerDebugger.postMessage_worker.js b/dom/workers/test/WorkerDebugger.postMessage_worker.js new file mode 100644 index 00000000000..8ddf6cf8657 --- /dev/null +++ b/dom/workers/test/WorkerDebugger.postMessage_worker.js @@ -0,0 +1,3 @@ +"use strict"; + +var worker = new Worker("WorkerDebugger.postMessage_childWorker.js"); diff --git a/dom/workers/test/chrome.ini b/dom/workers/test/chrome.ini index 41332d67785..e3e0a31d25b 100644 --- a/dom/workers/test/chrome.ini +++ b/dom/workers/test/chrome.ini @@ -4,6 +4,9 @@ support-files = WorkerDebugger.initialize_childWorker.js WorkerDebugger.initialize_debugger.js WorkerDebugger.initialize_worker.js + WorkerDebugger.postMessage_childWorker.js + WorkerDebugger.postMessage_debugger.js + WorkerDebugger.postMessage_worker.js WorkerDebuggerManager_childWorker.js WorkerDebuggerManager_worker.js WorkerDebugger_childWorker.js @@ -33,6 +36,7 @@ support-files = [test_WorkerDebugger.xul] [test_WorkerDebugger.initialize.xul] +[test_WorkerDebugger.postMessage.xul] [test_WorkerDebuggerManager.xul] [test_bug883784.jsm] [test_bug883784.xul] diff --git a/dom/workers/test/dom_worker_helper.js b/dom/workers/test/dom_worker_helper.js index f03900958d7..f3b1485c705 100644 --- a/dom/workers/test/dom_worker_helper.js +++ b/dom/workers/test/dom_worker_helper.js @@ -104,6 +104,21 @@ function waitForDebuggerClose(dbg) { }); } +function waitForDebuggerMessage(dbg, message) { + return new Promise(function (resolve) { + dbg.addListener({ + onMessage: function (message1) { + if (message !== message1) { + return; + } + info(true, "Should receive " + message + " message from debugger."); + dbg.removeListener(this); + resolve(); + } + }); + }); +} + function waitForWorkerMessage(worker, message) { return new Promise(function (resolve) { worker.addEventListener("message", function onmessage(event) { diff --git a/dom/workers/test/serviceworkers/fetch/fetch_tests.js b/dom/workers/test/serviceworkers/fetch/fetch_tests.js index b2a70ce5bd3..242655d7ac1 100644 --- a/dom/workers/test/serviceworkers/fetch/fetch_tests.js +++ b/dom/workers/test/serviceworkers/fetch/fetch_tests.js @@ -27,6 +27,12 @@ fetch('synthesized.txt', function(xhr) { finish(); }); +fetch('test-respondwith-response.txt', function(xhr) { + my_ok(xhr.status == 200, "test-respondwith-response load should be successful"); + my_ok(xhr.responseText == "test-respondwith-response response body", "load should have response"); + finish(); +}); + fetch('synthesized-404.txt', function(xhr) { my_ok(xhr.status == 404, "load should 404"); my_ok(xhr.responseText == "synthesized response body", "404 load should have synthesized response"); diff --git a/dom/workers/test/serviceworkers/fetch_event_worker.js b/dom/workers/test/serviceworkers/fetch_event_worker.js index 42dd2edf31e..f2dad56cc5f 100644 --- a/dom/workers/test/serviceworkers/fetch_event_worker.js +++ b/dom/workers/test/serviceworkers/fetch_event_worker.js @@ -21,6 +21,10 @@ onfetch = function(ev) { )); } + else if (ev.request.url.contains("test-respondwith-response.txt")) { + ev.respondWith(new Response("test-respondwith-response response body", {})); + } + else if (ev.request.url.contains("ignored.txt")) { } diff --git a/dom/workers/test/test_WorkerDebugger.postMessage.xul b/dom/workers/test/test_WorkerDebugger.postMessage.xul new file mode 100644 index 00000000000..e1a1842afa5 --- /dev/null +++ b/dom/workers/test/test_WorkerDebugger.postMessage.xul @@ -0,0 +1,61 @@ + + + + + + + +

+ +

+  
+  
diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp index 6acf0a11400..29fb260e897 100644 --- a/dom/xul/XULDocument.cpp +++ b/dom/xul/XULDocument.cpp @@ -3581,7 +3581,7 @@ XULDocument::ExecuteScript(nsXULPrototypeScript *aScript) // The script is in the compilation scope. Clone it into the target scope // and execute it. On failure, ~AutoScriptEntry will handle exceptions, so // there is no need to manually check the return value. - JS::CloneAndExecuteScript(cx, global, scriptObject); + JS::CloneAndExecuteScript(cx, scriptObject); return NS_OK; } diff --git a/gfx/layers/IMFYCbCrImage.h b/gfx/layers/IMFYCbCrImage.h index cdce4c8724c..c1172d2ad53 100644 --- a/gfx/layers/IMFYCbCrImage.h +++ b/gfx/layers/IMFYCbCrImage.h @@ -8,7 +8,7 @@ #include "mozilla/RefPtr.h" #include "ImageContainer.h" -#include "Mfidl.h" +#include "mfidl.h" namespace mozilla { namespace layers { diff --git a/gfx/layers/apz/public/GeckoContentController.h b/gfx/layers/apz/public/GeckoContentController.h index d901647f7ba..1114ea5d2ef 100644 --- a/gfx/layers/apz/public/GeckoContentController.h +++ b/gfx/layers/apz/public/GeckoContentController.h @@ -74,18 +74,6 @@ public: const ScrollableLayerGuid& aGuid, uint64_t aInputBlockId) = 0; - /** - * Requests handling of releasing a long tap. |aPoint| is in CSS pixels, - * relative to the current scroll offset. HandleLongTapUp will always be - * preceeded by HandleLongTap. However not all calls to HandleLongTap will - * be followed by a HandleLongTapUp (for example, if the user drags - * around between the long-tap and lifting their finger, or if content - * notifies the APZ that the long-tap event was prevent-defaulted). - */ - virtual void HandleLongTapUp(const CSSPoint& aPoint, - Modifiers aModifiers, - const ScrollableLayerGuid& aGuid) = 0; - /** * Requests sending a mozbrowserasyncscroll domevent to embedder. * |aContentRect| is in CSS pixels, relative to the current cssPage. diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 64f0d9ec08f..5f32af865f9 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -364,9 +364,12 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer, // If the content represented by the scrollable layer has changed (which may // be possible because of DLBI heuristics) then we don't want to keep using - // the same old APZC for the new content. Null it out so we run through the - // code to find another one or create one. - if (apzc && !apzc->Matches(guid)) { + // the same old APZC for the new content. Also, when reparenting a tab into a + // new window a layer might get moved to a different layer tree with a + // different APZCTreeManager. In these cases we don't want to reuse the same + // APZC, so null it out so we run through the code to find another one or + // create one. + if (apzc && (!apzc->Matches(guid) || !apzc->HasTreeManager(this))) { apzc = nullptr; } diff --git a/gfx/layers/apz/src/APZCTreeManager.h b/gfx/layers/apz/src/APZCTreeManager.h index bb2d3c1a2d3..9ddeb89f51e 100644 --- a/gfx/layers/apz/src/APZCTreeManager.h +++ b/gfx/layers/apz/src/APZCTreeManager.h @@ -144,12 +144,9 @@ public: * * The following values may be returned by this function: * nsEventStatus_eConsumeNoDefault is returned to indicate the - * caller should discard the event with extreme prejudice. - * Currently this is only returned if the APZ determines that something is - * in overscroll and the event should be ignored entirely, or if the input - * event is part of a extended gesture like flywheel scrolling, and gets - * consumed within the APZ code. There may be other scenarios where this - * return code might be used in the future. + * APZ is consuming this event and the caller should discard the event with + * extreme prejudice. The exact scenarios under which this is returned is + * implementation-dependent and may vary. * nsEventStatus_eIgnore is returned to indicate that the APZ code didn't * use this event. This might be because it was directed at a point on * the screen where there was no APZ, or because the thing the user was diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index bc0061cabb1..e825d8aa07d 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -1637,15 +1637,7 @@ nsEventStatus AsyncPanZoomController::OnLongPress(const TapGestureInput& aEvent) nsEventStatus AsyncPanZoomController::OnLongPressUp(const TapGestureInput& aEvent) { APZC_LOG("%p got a long-tap-up in state %d\n", this, mState); - nsRefPtr controller = GetGeckoContentController(); - if (controller) { - CSSPoint geckoScreenPoint; - if (ConvertToGecko(aEvent.mLocalPoint, &geckoScreenPoint)) { - controller->HandleLongTapUp(geckoScreenPoint, aEvent.modifiers, GetGuid()); - return nsEventStatus_eConsumeNoDefault; - } - } - return nsEventStatus_eIgnore; + return GenerateSingleTap(aEvent.mLocalPoint, aEvent.modifiers); } nsEventStatus AsyncPanZoomController::GenerateSingleTap(const ParentLayerPoint& aPoint, mozilla::Modifiers aModifiers) { @@ -3065,6 +3057,11 @@ bool AsyncPanZoomController::Matches(const ScrollableLayerGuid& aGuid) return aGuid == GetGuid(); } +bool AsyncPanZoomController::HasTreeManager(const APZCTreeManager* aTreeManager) const +{ + return GetApzcTreeManager() == aTreeManager; +} + void AsyncPanZoomController::GetGuid(ScrollableLayerGuid* aGuidOut) const { if (aGuidOut) { diff --git a/gfx/layers/apz/src/AsyncPanZoomController.h b/gfx/layers/apz/src/AsyncPanZoomController.h index 5bd40f3a619..1fc0003cb59 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.h +++ b/gfx/layers/apz/src/AsyncPanZoomController.h @@ -287,6 +287,12 @@ public: */ bool Matches(const ScrollableLayerGuid& aGuid); + /** + * Returns true if the tree manager of this APZC is the same as the one + * passed in. + */ + bool HasTreeManager(const APZCTreeManager* aTreeManager) const; + void StartAnimation(AsyncPanZoomAnimation* aAnimation); /** diff --git a/gfx/layers/apz/src/Axis.cpp b/gfx/layers/apz/src/Axis.cpp index 70028073a73..36ff4d313bf 100644 --- a/gfx/layers/apz/src/Axis.cpp +++ b/gfx/layers/apz/src/Axis.cpp @@ -206,7 +206,14 @@ ParentLayerCoord Axis::GetOverscroll() const { ParentLayerCoord result = (mOverscroll - mLastOverscrollPeak) / mOverscrollScale; // Assert that we return overscroll in the correct direction - MOZ_ASSERT((result.value * mFirstOverscrollAnimationSample.value) >= 0.0f); +#ifdef DEBUG + if ((result.value * mFirstOverscrollAnimationSample.value) < 0.0f) { + nsPrintfCString message("GetOverscroll() (%f) and first overscroll animation sample (%f) have different signs\n", + result.value, mFirstOverscrollAnimationSample.value); + NS_ASSERTION(false, message.get()); + MOZ_CRASH(); + } +#endif return result; } diff --git a/gfx/layers/apz/util/APZEventState.cpp b/gfx/layers/apz/util/APZEventState.cpp index 7e8d910fd83..aaaed7c0620 100644 --- a/gfx/layers/apz/util/APZEventState.cpp +++ b/gfx/layers/apz/util/APZEventState.cpp @@ -233,17 +233,6 @@ APZEventState::ProcessLongTap(const nsCOMPtr& aUtils, mContentReceivedInputBlockCallback->Run(aGuid, aInputBlockId, eventHandled); } -void -APZEventState::ProcessLongTapUp(const CSSPoint& aPoint, - Modifiers aModifiers, - const ScrollableLayerGuid& aGuid, - float aPresShellResolution) -{ - APZES_LOG("Handling long tap up at %s\n", Stringify(aPoint).c_str()); - - ProcessSingleTap(aPoint, aModifiers, aGuid, aPresShellResolution); -} - void APZEventState::ProcessTouchEvent(const WidgetTouchEvent& aEvent, const ScrollableLayerGuid& aGuid, diff --git a/gfx/layers/apz/util/APZEventState.h b/gfx/layers/apz/util/APZEventState.h index 4e83f6c3cd4..2b1e7929573 100644 --- a/gfx/layers/apz/util/APZEventState.h +++ b/gfx/layers/apz/util/APZEventState.h @@ -59,10 +59,6 @@ public: const ScrollableLayerGuid& aGuid, uint64_t aInputBlockId, float aPresShellResolution); - void ProcessLongTapUp(const CSSPoint& aPoint, - Modifiers aModifiers, - const ScrollableLayerGuid& aGuid, - float aPresShellResolution); void ProcessTouchEvent(const WidgetTouchEvent& aEvent, const ScrollableLayerGuid& aGuid, uint64_t aInputBlockId); diff --git a/gfx/layers/apz/util/APZThreadUtils.cpp b/gfx/layers/apz/util/APZThreadUtils.cpp index a56d6eae1c0..1c9c5eb6e05 100644 --- a/gfx/layers/apz/util/APZThreadUtils.cpp +++ b/gfx/layers/apz/util/APZThreadUtils.cpp @@ -56,6 +56,12 @@ APZThreadUtils::RunOnControllerThread(Task* aTask) // On B2G the controller thread is the compositor thread, and this function // is always called from the libui thread or the main thread. MessageLoop* loop = CompositorParent::CompositorLoop(); + if (!loop) { + // Could happen on startup + NS_WARNING("Dropping task posted to controller thread\n"); + delete aTask; + return; + } MOZ_ASSERT(MessageLoop::current() != loop); loop->PostTask(FROM_HERE, aTask); #else diff --git a/gfx/layers/apz/util/ChromeProcessController.cpp b/gfx/layers/apz/util/ChromeProcessController.cpp index 70ee508d9c8..8ab74a3bb41 100644 --- a/gfx/layers/apz/util/ChromeProcessController.cpp +++ b/gfx/layers/apz/util/ChromeProcessController.cpp @@ -183,21 +183,6 @@ ChromeProcessController::HandleLongTap(const mozilla::CSSPoint& aPoint, Modifier aInputBlockId, GetPresShellResolution()); } -void -ChromeProcessController::HandleLongTapUp(const CSSPoint& aPoint, Modifiers aModifiers, - const ScrollableLayerGuid& aGuid) -{ - if (MessageLoop::current() != mUILoop) { - mUILoop->PostTask( - FROM_HERE, - NewRunnableMethod(this, &ChromeProcessController::HandleLongTapUp, - aPoint, aModifiers, aGuid)); - return; - } - - mAPZEventState->ProcessLongTapUp(aPoint, aModifiers, aGuid, GetPresShellResolution()); -} - void ChromeProcessController::NotifyAPZStateChange(const ScrollableLayerGuid& aGuid, APZStateChange aChange, diff --git a/gfx/layers/apz/util/ChromeProcessController.h b/gfx/layers/apz/util/ChromeProcessController.h index 371573a3915..638a9b0ccef 100644 --- a/gfx/layers/apz/util/ChromeProcessController.h +++ b/gfx/layers/apz/util/ChromeProcessController.h @@ -50,8 +50,6 @@ public: virtual void HandleLongTap(const mozilla::CSSPoint& aPoint, Modifiers aModifiers, const ScrollableLayerGuid& aGuid, uint64_t aInputBlockId) MOZ_OVERRIDE; - virtual void HandleLongTapUp(const CSSPoint& aPoint, Modifiers aModifiers, - const ScrollableLayerGuid& aGuid) MOZ_OVERRIDE; virtual void SendAsyncScrollDOMEvent(bool aIsRoot, const mozilla::CSSRect &aContentRect, const mozilla::CSSSize &aScrollableSize) MOZ_OVERRIDE {} virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid, diff --git a/gfx/layers/client/ClientTiledPaintedLayer.cpp b/gfx/layers/client/ClientTiledPaintedLayer.cpp index fe6c9156707..78481e7cde1 100644 --- a/gfx/layers/client/ClientTiledPaintedLayer.cpp +++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp @@ -174,7 +174,7 @@ ClientTiledPaintedLayer::BeginPaint() ParentLayerRect criticalDisplayPort = (displayportMetrics.GetCriticalDisplayPort() * displayportMetrics.GetZoom()) + displayportMetrics.mCompositionBounds.TopLeft(); - mPaintData.mCriticalDisplayPort = RoundedOut( + mPaintData.mCriticalDisplayPort = RoundedToInt( ApplyParentLayerToLayerTransform(transformDisplayPortToLayer, criticalDisplayPort)); } TILING_LOG("TILING %p: Critical displayport %s\n", this, Stringify(mPaintData.mCriticalDisplayPort).c_str()); @@ -182,7 +182,7 @@ ClientTiledPaintedLayer::BeginPaint() // Store the resolution from the displayport ancestor layer. Because this is Gecko-side, // before any async transforms have occurred, we can use the zoom for this. mPaintData.mResolution = displayportMetrics.GetZoom(); - TILING_LOG("TILING %p: Resolution %f\n", this, mPaintData.mResolution.scale); + TILING_LOG("TILING %p: Resolution %s\n", this, Stringify(mPaintData.mResolution).c_str()); // Store the applicable composition bounds in this layer's Layer units. mPaintData.mTransformToCompBounds = diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index 3a05759fbd2..3972a3bb4b6 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -66,7 +66,6 @@ public: MOCK_METHOD3(HandleDoubleTap, void(const CSSPoint&, Modifiers, const ScrollableLayerGuid&)); MOCK_METHOD3(HandleSingleTap, void(const CSSPoint&, Modifiers, const ScrollableLayerGuid&)); MOCK_METHOD4(HandleLongTap, void(const CSSPoint&, Modifiers, const ScrollableLayerGuid&, uint64_t)); - MOCK_METHOD3(HandleLongTapUp, void(const CSSPoint&, Modifiers, const ScrollableLayerGuid&)); MOCK_METHOD3(SendAsyncScrollDOMEvent, void(bool aIsRoot, const CSSRect &aContentRect, const CSSSize &aScrollableSize)); MOCK_METHOD2(PostDelayedTask, void(Task* aTask, int aDelayMs)); MOCK_METHOD3(NotifyAPZStateChange, void(const ScrollableLayerGuid& aGuid, APZStateChange aChange, int aArg)); @@ -1390,9 +1389,9 @@ protected: EXPECT_CALL(*mcc, HandleLongTap(CSSPoint(10, 10), 0, apzc->GetGuid(), blockId)).Times(1); EXPECT_CALL(check, Call("postHandleLongTap")); - EXPECT_CALL(check, Call("preHandleLongTapUp")); - EXPECT_CALL(*mcc, HandleLongTapUp(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1); - EXPECT_CALL(check, Call("postHandleLongTapUp")); + EXPECT_CALL(check, Call("preHandleSingleTap")); + EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1); + EXPECT_CALL(check, Call("postHandleSingleTap")); } // There is a longpress event scheduled on a timeout @@ -1419,10 +1418,11 @@ protected: // Finally, simulate lifting the finger. Since the long-press wasn't // prevent-defaulted, we should get a long-tap-up event. - check.Call("preHandleLongTapUp"); + check.Call("preHandleSingleTap"); status = TouchUp(apzc, 10, 10, time); + mcc->RunDelayedTask(); EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status); - check.Call("postHandleLongTapUp"); + check.Call("postHandleSingleTap"); apzc->AssertStateIsReset(); } @@ -1488,7 +1488,7 @@ protected: status = apzc->ReceiveInputEvent(mti, nullptr); EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status); - EXPECT_CALL(*mcc, HandleLongTapUp(CSSPoint(touchX, touchEndY), 0, apzc->GetGuid())).Times(0); + EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(touchX, touchEndY), 0, apzc->GetGuid())).Times(0); status = TouchUp(apzc, touchX, touchEndY, time); EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status); diff --git a/gfx/thebes/gfxAndroidPlatform.cpp b/gfx/thebes/gfxAndroidPlatform.cpp index 9bc77292f07..c87070c4598 100644 --- a/gfx/thebes/gfxAndroidPlatform.cpp +++ b/gfx/thebes/gfxAndroidPlatform.cpp @@ -499,7 +499,6 @@ gfxAndroidPlatform::CreateHardwareVsyncSource() display.DisableVsync(); return vsyncSource.forget(); #else - NS_WARNING("Hardware vsync not supported on android yet"); - return nullptr; + return gfxPlatform::CreateHardwareVsyncSource(); #endif } diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index ad576d37375..2b804ee28e6 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -232,7 +232,7 @@ private: DECL_GFX_PREF(Once, "image.cache.timeweight", ImageCacheTimeWeight, int32_t, 500); DECL_GFX_PREF(Once, "image.cache.size", ImageCacheSize, int32_t, 5*1024*1024); - DECL_GFX_PREF(Live, "image.downscale-during-decode.enabled", ImageDownscaleDuringDecodeEnabled, bool, true); + DECL_GFX_PREF(Live, "image.downscale-during-decode.enabled", ImageDownscaleDuringDecodeEnabled, bool, false); DECL_GFX_PREF(Live, "image.high_quality_downscaling.enabled", ImageHQDownscalingEnabled, bool, false); DECL_GFX_PREF(Live, "image.high_quality_downscaling.min_factor", ImageHQDownscalingMinFactor, uint32_t, 1000); DECL_GFX_PREF(Live, "image.high_quality_upscaling.max_size", ImageHQUpscalingMaxSize, uint32_t, 20971520); diff --git a/image/public/imgIContainer.idl b/image/public/imgIContainer.idl index 84735e4fa2c..a06c508b3f7 100644 --- a/image/public/imgIContainer.idl +++ b/image/public/imgIContainer.idl @@ -116,7 +116,7 @@ native nsIntSizeByVal(nsIntSize); * * Internally, imgIContainer also manages animation of images. */ -[scriptable, builtinclass, uuid(44fbd7d5-e417-4d31-ae4a-8ad61d07eb3c)] +[scriptable, builtinclass, uuid(e3261ae7-4749-4cf6-bf06-59946233366f)] interface imgIContainer : nsISupports { /** @@ -173,12 +173,7 @@ interface imgIContainer : nsISupports /** * The type of this image (one of the TYPE_* values above). */ - readonly attribute unsigned short type; - - /** - * Direct C++ accessor for 'type' attribute, for convenience. - */ - [noscript, notxpcom] uint16_t GetType(); + [infallible] readonly attribute unsigned short type; /** * Whether this image is animated. You can only be guaranteed that querying diff --git a/image/src/DynamicImage.cpp b/image/src/DynamicImage.cpp index c8167457cad..ccd4b88e472 100644 --- a/image/src/DynamicImage.cpp +++ b/image/src/DynamicImage.cpp @@ -162,12 +162,6 @@ DynamicImage::GetType(uint16_t* aType) return NS_OK; } -NS_IMETHODIMP_(uint16_t) -DynamicImage::GetType() -{ - return imgIContainer::TYPE_RASTER; -} - NS_IMETHODIMP DynamicImage::GetAnimated(bool* aAnimated) { diff --git a/image/src/ImageWrapper.cpp b/image/src/ImageWrapper.cpp index d97c0458d1b..f9695e4aa6e 100644 --- a/image/src/ImageWrapper.cpp +++ b/image/src/ImageWrapper.cpp @@ -167,12 +167,6 @@ ImageWrapper::GetType(uint16_t* aType) return mInnerImage->GetType(aType); } -NS_IMETHODIMP_(uint16_t) -ImageWrapper::GetType() -{ - return mInnerImage->GetType(); -} - NS_IMETHODIMP ImageWrapper::GetAnimated(bool* aAnimated) { diff --git a/image/src/RasterImage.cpp b/image/src/RasterImage.cpp index 928789b44fb..db828aa5b4a 100644 --- a/image/src/RasterImage.cpp +++ b/image/src/RasterImage.cpp @@ -449,18 +449,10 @@ RasterImage::GetType(uint16_t *aType) { NS_ENSURE_ARG_POINTER(aType); - *aType = GetType(); + *aType = imgIContainer::TYPE_RASTER; return NS_OK; } -//****************************************************************************** -/* [noscript, notxpcom] uint16_t GetType(); */ -NS_IMETHODIMP_(uint16_t) -RasterImage::GetType() -{ - return imgIContainer::TYPE_RASTER; -} - DrawableFrameRef RasterImage::LookupFrameInternal(uint32_t aFrameNum, const IntSize& aSize, diff --git a/image/src/VectorImage.cpp b/image/src/VectorImage.cpp index 1220186e829..a51c749c168 100644 --- a/image/src/VectorImage.cpp +++ b/image/src/VectorImage.cpp @@ -599,18 +599,10 @@ VectorImage::GetType(uint16_t* aType) { NS_ENSURE_ARG_POINTER(aType); - *aType = GetType(); + *aType = imgIContainer::TYPE_VECTOR; return NS_OK; } -//****************************************************************************** -/* [noscript, notxpcom] uint16_t GetType(); */ -NS_IMETHODIMP_(uint16_t) -VectorImage::GetType() -{ - return imgIContainer::TYPE_VECTOR; -} - //****************************************************************************** /* readonly attribute boolean animated; */ NS_IMETHODIMP diff --git a/image/test/crashtests/crashtests.list b/image/test/crashtests/crashtests.list index b03a27a299a..d914a54964b 100644 --- a/image/test/crashtests/crashtests.list +++ b/image/test/crashtests/crashtests.list @@ -46,4 +46,4 @@ load multiple-png-hassize.ico # Asserts in the debug build load 856616.gif -skip-if(AddressSanitizer) skip-if(B2G) load 944353.jpg +skip-if(AddressSanitizer) load 944353.jpg diff --git a/ipc/glue/ProtocolUtils.cpp b/ipc/glue/ProtocolUtils.cpp index 4135e56b77e..db25caacabc 100644 --- a/ipc/glue/ProtocolUtils.cpp +++ b/ipc/glue/ProtocolUtils.cpp @@ -21,19 +21,56 @@ using base::ProcessId; namespace mozilla { namespace ipc { -#ifdef MOZ_IPDL_TESTS -bool IToplevelProtocol::sAllowNonMainThreadUse; -#endif +static Atomic gNumProtocols; +static StaticAutoPtr gProtocolMutex; + +IToplevelProtocol::IToplevelProtocol(ProtocolId aProtoId) + : mOpener(nullptr) + , mProtocolId(aProtoId) + , mTrans(nullptr) +{ + size_t old = gNumProtocols++; + + if (!old) { + // We assume that two threads never race to create the first protocol. This + // assertion is sufficient to ensure that. + MOZ_ASSERT(NS_IsMainThread()); + gProtocolMutex = new Mutex("ITopLevelProtocol::ProtocolMutex"); + } +} IToplevelProtocol::~IToplevelProtocol() { - MOZ_ASSERT(NS_IsMainThread() || AllowNonMainThreadUse()); - mOpenActors.clear(); + bool last = false; + + { + MutexAutoLock al(*gProtocolMutex); + + for (IToplevelProtocol* actor = mOpenActors.getFirst(); + actor; + actor = actor->getNext()) { + actor->mOpener = nullptr; + } + + mOpenActors.clear(); + + if (mOpener) { + removeFrom(mOpener->mOpenActors); + } + + gNumProtocols--; + last = gNumProtocols == 0; + } + + if (last) { + gProtocolMutex = nullptr; + } } -void IToplevelProtocol::AddOpenedActor(IToplevelProtocol* aActor) +void +IToplevelProtocol::AddOpenedActorLocked(IToplevelProtocol* aActor) { - MOZ_ASSERT(NS_IsMainThread() || AllowNonMainThreadUse()); + gProtocolMutex->AssertCurrentThreadOwns(); #ifdef DEBUG for (const IToplevelProtocol* actor = mOpenActors.getFirst(); @@ -44,9 +81,49 @@ void IToplevelProtocol::AddOpenedActor(IToplevelProtocol* aActor) } #endif + aActor->mOpener = this; mOpenActors.insertBack(aActor); } +void +IToplevelProtocol::AddOpenedActor(IToplevelProtocol* aActor) +{ + MutexAutoLock al(*gProtocolMutex); + AddOpenedActorLocked(aActor); +} + +void +IToplevelProtocol::GetOpenedActorsLocked(nsTArray& aActors) +{ + gProtocolMutex->AssertCurrentThreadOwns(); + + for (IToplevelProtocol* actor = mOpenActors.getFirst(); + actor; + actor = actor->getNext()) { + aActors.AppendElement(actor); + } +} + +void +IToplevelProtocol::GetOpenedActors(nsTArray& aActors) +{ + MutexAutoLock al(*gProtocolMutex); + GetOpenedActorsLocked(aActors); +} + +size_t +IToplevelProtocol::GetOpenedActorsUnsafe(IToplevelProtocol** aActors, size_t aActorsMax) +{ + size_t count = 0; + for (IToplevelProtocol* actor = mOpenActors.getFirst(); + actor; + actor = actor->getNext()) { + MOZ_RELEASE_ASSERT(count < aActorsMax); + aActors[count++] = actor; + } + return count; +} + IToplevelProtocol* IToplevelProtocol::CloneToplevel(const InfallibleTArray& aFds, base::ProcessHandle aPeerProcess, @@ -62,22 +139,17 @@ IToplevelProtocol::CloneOpenedToplevels(IToplevelProtocol* aTemplate, base::ProcessHandle aPeerProcess, ProtocolCloneContext* aCtx) { - for (IToplevelProtocol* actor = aTemplate->GetFirstOpenedActors(); - actor; - actor = actor->getNext()) { - IToplevelProtocol* newactor = actor->CloneToplevel(aFds, aPeerProcess, aCtx); - AddOpenedActor(newactor); + MutexAutoLock al(*gProtocolMutex); + + nsTArray actors; + aTemplate->GetOpenedActorsLocked(actors); + + for (size_t i = 0; i < actors.Length(); i++) { + IToplevelProtocol* newactor = actors[i]->CloneToplevel(aFds, aPeerProcess, aCtx); + AddOpenedActorLocked(newactor); } } -#ifdef MOZ_IPDL_TESTS -void -IToplevelProtocol::SetAllowNonMainThreadUse() -{ - sAllowNonMainThreadUse = true; -} -#endif - class ChannelOpened : public IPC::Message { public: diff --git a/ipc/glue/ProtocolUtils.h b/ipc/glue/ProtocolUtils.h index e5220903529..ce8fe2805ee 100644 --- a/ipc/glue/ProtocolUtils.h +++ b/ipc/glue/ProtocolUtils.h @@ -21,6 +21,7 @@ #include "mozilla/ipc/Transport.h" #include "mozilla/ipc/MessageLink.h" #include "mozilla/LinkedList.h" +#include "mozilla/Mutex.h" #include "MainThreadUtils.h" #if defined(ANDROID) && defined(DEBUG) @@ -181,16 +182,13 @@ public: * IToplevelProtocol tracks all top-level protocol actors created from * this protocol actor. */ -class IToplevelProtocol : public LinkedListElement +class IToplevelProtocol : private LinkedListElement { -protected: - explicit IToplevelProtocol(ProtocolId aProtoId) - : mProtocolId(aProtoId) - , mTrans(nullptr) - { - MOZ_ASSERT(NS_IsMainThread() || AllowNonMainThreadUse()); - } + friend class LinkedList; + friend class LinkedListElement; +protected: + explicit IToplevelProtocol(ProtocolId aProtoId); ~IToplevelProtocol(); /** @@ -209,19 +207,13 @@ public: ProtocolId GetProtocolId() const { return mProtocolId; } - /** - * Return first of actors of top level protocols opened by this one. - */ - IToplevelProtocol* GetFirstOpenedActors() - { - MOZ_ASSERT(NS_IsMainThread() || AllowNonMainThreadUse()); - return mOpenActors.getFirst(); - } - const IToplevelProtocol* GetFirstOpenedActors() const - { - MOZ_ASSERT(NS_IsMainThread() || AllowNonMainThreadUse()); - return mOpenActors.getFirst(); - } + void GetOpenedActors(nsTArray& aActors); + + // This Unsafe version should only be used when all other threads are + // frozen, since it performs no locking. It also takes a stack-allocated + // array and its size (number of elements) rather than an nsTArray. The Nuwa + // code that calls this function is not allowed to allocate memory. + size_t GetOpenedActorsUnsafe(IToplevelProtocol** aActors, size_t aActorsMax); virtual IToplevelProtocol* CloneToplevel(const InfallibleTArray& aFds, @@ -233,27 +225,15 @@ public: base::ProcessHandle aPeerProcess, ProtocolCloneContext* aCtx); -#ifdef MOZ_IPDL_TESTS - static void SetAllowNonMainThreadUse(); -#endif - - static bool AllowNonMainThreadUse() { -#ifdef MOZ_IPDL_TESTS - return sAllowNonMainThreadUse; -#else - return false; -#endif - } - private: + void AddOpenedActorLocked(IToplevelProtocol* aActor); + void GetOpenedActorsLocked(nsTArray& aActors); + LinkedList mOpenActors; // All protocol actors opened by this. + IToplevelProtocol* mOpener; ProtocolId mProtocolId; Transport* mTrans; - -#ifdef MOZ_IPDL_TESTS - static bool sAllowNonMainThreadUse; -#endif }; diff --git a/ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp b/ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp index a64f4cc84ec..5a4df6faa27 100644 --- a/ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp +++ b/ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp @@ -139,10 +139,6 @@ IPDLUnitTestMain(void* aData) { char* testString = reinterpret_cast(aData); - // Some tests require this, and we don't care what thread we're on if we're - // not using Nuwa. - mozilla::ipc::IToplevelProtocol::SetAllowNonMainThreadUse(); - // Check if we are to run the test using threads instead: const char *prefix = "thread:"; const int prefixLen = strlen(prefix); @@ -378,10 +374,6 @@ IPDLUnitTestChildInit(IPC::Channel* transport, base::ProcessHandle parent, MessageLoop* worker) { - // Some tests require this, and we don't care what thread we're on if we're - // not using Nuwa. - mozilla::ipc::IToplevelProtocol::SetAllowNonMainThreadUse(); - switch (IPDLUnitTest()) { //----------------------------------------------------------------------------- //===== TEMPLATED ===== diff --git a/js/public/ProfilingFrameIterator.h b/js/public/ProfilingFrameIterator.h index 6ebcb1648ce..37cd8658b68 100644 --- a/js/public/ProfilingFrameIterator.h +++ b/js/public/ProfilingFrameIterator.h @@ -123,6 +123,9 @@ class JS_PUBLIC_API(ProfilingFrameIterator) bool isJit() const; }; +extern JS_PUBLIC_API(ProfilingFrameIterator::FrameKind) +GetProfilingFrameKindFromNativeAddr(JSRuntime *runtime, void *pc); + JS_FRIEND_API(bool) IsProfilingEnabledForRuntime(JSRuntime *runtime); diff --git a/js/public/TrackedOptimizationInfo.h b/js/public/TrackedOptimizationInfo.h index eacee45b7b1..ff947285651 100644 --- a/js/public/TrackedOptimizationInfo.h +++ b/js/public/TrackedOptimizationInfo.h @@ -7,252 +7,141 @@ #ifndef js_TrackedOptimizationInfo_h #define js_TrackedOptimizationInfo_h +#include "mozilla/Maybe.h" + namespace JS { #define TRACKED_STRATEGY_LIST(_) \ - _(GetProp_ArgumentsLength, \ - "getprop arguments.length") \ - _(GetProp_ArgumentsCallee, \ - "getprop arguments.callee") \ - _(GetProp_InferredConstant, \ - "getprop inferred constant") \ - _(GetProp_Constant, \ - "getprop constant") \ - _(GetProp_SimdGetter, \ - "getprop SIMD getter") \ - _(GetProp_TypedObject, \ - "getprop TypedObject") \ - _(GetProp_DefiniteSlot, \ - "getprop definite slot") \ - _(GetProp_Unboxed, \ - "getprop unboxed object") \ - _(GetProp_CommonGetter, \ - "getprop common getter") \ - _(GetProp_InlineAccess, \ - "getprop inline access") \ - _(GetProp_Innerize, \ - "getprop innerize (access on global window)") \ - _(GetProp_InlineCache, \ - "getprop IC") \ + _(GetProp_ArgumentsLength) \ + _(GetProp_ArgumentsCallee) \ + _(GetProp_InferredConstant) \ + _(GetProp_Constant) \ + _(GetProp_SimdGetter) \ + _(GetProp_TypedObject) \ + _(GetProp_DefiniteSlot) \ + _(GetProp_Unboxed) \ + _(GetProp_CommonGetter) \ + _(GetProp_InlineAccess) \ + _(GetProp_Innerize) \ + _(GetProp_InlineCache) \ \ - _(SetProp_CommonSetter, \ - "setprop common setter") \ - _(SetProp_TypedObject, \ - "setprop TypedObject") \ - _(SetProp_DefiniteSlot, \ - "setprop definite slot") \ - _(SetProp_Unboxed, \ - "setprop unboxed object") \ - _(SetProp_InlineAccess, \ - "setprop inline access") \ + _(SetProp_CommonSetter) \ + _(SetProp_TypedObject) \ + _(SetProp_DefiniteSlot) \ + _(SetProp_Unboxed) \ + _(SetProp_InlineAccess) \ \ - _(GetElem_TypedObject, \ - "getprop TypedObject") \ - _(GetElem_Dense, \ - "getelem dense") \ - _(GetElem_TypedStatic, \ - "getelem TypedArray static") \ - _(GetElem_TypedArray, \ - "getelem TypedArray") \ - _(GetElem_String, \ - "getelem string") \ - _(GetElem_Arguments, \ - "getelem arguments") \ - _(GetElem_ArgumentsInlined, \ - "getelem arguments inlined") \ - _(GetElem_InlineCache, \ - "getelem IC") \ + _(GetElem_TypedObject) \ + _(GetElem_Dense) \ + _(GetElem_TypedStatic) \ + _(GetElem_TypedArray) \ + _(GetElem_String) \ + _(GetElem_Arguments) \ + _(GetElem_ArgumentsInlined) \ + _(GetElem_InlineCache) \ \ - _(SetElem_TypedObject, \ - "setelem TypedObject") \ - _(SetElem_TypedStatic, \ - "setelem TypedArray static") \ - _(SetElem_TypedArray, \ - "setelem TypedArray") \ - _(SetElem_Dense, \ - "setelem dense") \ - _(SetElem_Arguments, \ - "setelem arguments") \ - _(SetElem_InlineCache, \ - "setelem IC") \ + _(SetElem_TypedObject) \ + _(SetElem_TypedStatic) \ + _(SetElem_TypedArray) \ + _(SetElem_Dense) \ + _(SetElem_Arguments) \ + _(SetElem_InlineCache) \ \ - _(Call_Inline, \ - "call inline") + _(Call_Inline) // Ordering is important below. All outcomes before GenericSuccess will be // considered failures, and all outcomes after GenericSuccess will be // considered successes. #define TRACKED_OUTCOME_LIST(_) \ - _(GenericFailure, \ - "failure") \ - _(Disabled, \ - "disabled") \ - _(NoTypeInfo, \ - "no type info") \ - _(NoAnalysisInfo, \ - "no newscript analysis") \ - _(NoShapeInfo, \ - "cannot determine shape") \ - _(UnknownObject, \ - "unknown object") \ - _(UnknownProperties, \ - "unknown properties") \ - _(Singleton, \ - "is singleton") \ - _(NotSingleton, \ - "is not singleton") \ - _(NotFixedSlot, \ - "property not in fixed slot") \ - _(InconsistentFixedSlot, \ - "property not in a consistent fixed slot") \ - _(NotObject, \ - "not definitely an object") \ - _(NotStruct, \ - "not definitely a TypedObject struct") \ - _(NotUnboxed, \ - "not definitely an unboxed object") \ - _(UnboxedConvertedToNative, \ - "unboxed object may have been converted") \ - _(StructNoField, \ - "struct doesn't definitely have field") \ - _(InconsistentFieldType, \ - "unboxed property does not have consistent type") \ - _(InconsistentFieldOffset, \ - "unboxed property does not have consistent offset") \ - _(NeedsTypeBarrier, \ - "needs type barrier") \ - _(InDictionaryMode, \ - "object in dictionary mode") \ - _(NoProtoFound, \ - "no proto found") \ - _(MultiProtoPaths, \ - "not all paths to property go through same proto") \ - _(NonWritableProperty, \ - "non-writable property") \ - _(ProtoIndexedProps, \ - "prototype has indexed properties") \ - _(ArrayBadFlags, \ - "array observed to be sparse, overflowed .length, or has been iterated") \ - _(ArrayDoubleConversion, \ - "array has ambiguous double conversion") \ - _(ArrayRange, \ - "array range issue (.length problems)") \ - _(ArraySeenNegativeIndex, \ - "has seen array access with negative index") \ - _(TypedObjectNeutered, \ - "TypedObject might have been neutered") \ - _(TypedObjectArrayRange, \ - "TypedObject array of unknown length") \ - _(AccessNotDense, \ - "access not on dense native (check receiver, index, and result types)") \ - _(AccessNotSimdObject, \ - "access not on SIMD object (check receiver)") \ - _(AccessNotTypedObject, \ - "access not on typed object (check receiver and index types)") \ - _(AccessNotTypedArray, \ - "access not on typed array (check receiver, index, and result types)") \ - _(AccessNotString, \ - "getelem not on string (check receiver and index types)") \ - _(StaticTypedArrayUint32, \ - "static uint32 arrays currently cannot be optimized") \ - _(StaticTypedArrayCantComputeMask, \ - "can't compute mask for static typed array access (index isn't constant or not int32)") \ - _(OutOfBounds, \ - "observed out of bounds access") \ - _(GetElemStringNotCached, \ - "getelem on strings is not inline cached") \ - _(NonNativeReceiver, \ - "observed non-native receiver") \ - _(IndexType, \ - "index type must be int32, string, or symbol") \ - _(SetElemNonDenseNonTANotCached, \ - "setelem on non-dense non-TAs are not inline cached") \ - _(NoSimdJitSupport, \ - "SIMD isn't optimized in Ion on this platform yet") \ - _(SimdTypeNotOptimized, \ - "given SIMD type isn't optimized in Ion yet") \ - _(UnknownSimdProperty, \ - "getelem on an unknown SIMD property ") \ + _(GenericFailure) \ + _(Disabled) \ + _(NoTypeInfo) \ + _(NoAnalysisInfo) \ + _(NoShapeInfo) \ + _(UnknownObject) \ + _(UnknownProperties) \ + _(Singleton) \ + _(NotSingleton) \ + _(NotFixedSlot) \ + _(InconsistentFixedSlot) \ + _(NotObject) \ + _(NotStruct) \ + _(NotUnboxed) \ + _(UnboxedConvertedToNative) \ + _(StructNoField) \ + _(InconsistentFieldType) \ + _(InconsistentFieldOffset) \ + _(NeedsTypeBarrier) \ + _(InDictionaryMode) \ + _(NoProtoFound) \ + _(MultiProtoPaths) \ + _(NonWritableProperty) \ + _(ProtoIndexedProps) \ + _(ArrayBadFlags) \ + _(ArrayDoubleConversion) \ + _(ArrayRange) \ + _(ArraySeenNegativeIndex) \ + _(TypedObjectNeutered) \ + _(TypedObjectArrayRange) \ + _(AccessNotDense) \ + _(AccessNotSimdObject) \ + _(AccessNotTypedObject) \ + _(AccessNotTypedArray) \ + _(AccessNotString) \ + _(StaticTypedArrayUint32) \ + _(StaticTypedArrayCantComputeMask) \ + _(OutOfBounds) \ + _(GetElemStringNotCached) \ + _(NonNativeReceiver) \ + _(IndexType) \ + _(SetElemNonDenseNonTANotCached) \ + _(NoSimdJitSupport) \ + _(SimdTypeNotOptimized) \ + _(UnknownSimdProperty) \ \ - _(CantInlineGeneric, \ - "can't inline") \ - _(CantInlineNoTarget, \ - "can't inline: no target") \ - _(CantInlineNotInterpreted, \ - "can't inline: not interpreted") \ - _(CantInlineNoBaseline, \ - "can't inline: no baseline code") \ - _(CantInlineLazy, \ - "can't inline: lazy script") \ - _(CantInlineNotConstructor, \ - "can't inline: calling non-constructor with 'new'") \ - _(CantInlineDisabledIon, \ - "can't inline: ion disabled for callee") \ - _(CantInlineTooManyArgs, \ - "can't inline: too many arguments") \ - _(CantInlineRecursive, \ - "can't inline: recursive") \ - _(CantInlineHeavyweight, \ - "can't inline: heavyweight") \ - _(CantInlineNeedsArgsObj, \ - "can't inline: needs arguments object") \ - _(CantInlineDebuggee, \ - "can't inline: debuggee") \ - _(CantInlineUnknownProps, \ - "can't inline: type has unknown properties") \ - _(CantInlineExceededDepth, \ - "can't inline: exceeded inlining depth") \ - _(CantInlineBigLoop, \ - "can't inline: big function with a loop") \ - _(CantInlineBigCaller, \ - "can't inline: big caller") \ - _(CantInlineBigCallee, \ - "can't inline: big callee") \ - _(CantInlineNotHot, \ - "can't inline: not hot enough") \ - _(CantInlineNotInDispatch, \ - "can't inline: not in dispatch table") \ - _(CantInlineUnreachable, \ - "can't inline: unreachable due to incomplete types for this/arguments") \ - _(CantInlineNativeBadForm, \ - "can't inline native: bad form (arity mismatch/constructing)") \ - _(CantInlineNativeBadType, \ - "can't inline native: bad argument or return type observed") \ - _(CantInlineNativeNoTemplateObj, \ - "can't inline native: no template object") \ - _(CantInlineBound, \ - "can't inline bound function invocation") \ + _(CantInlineGeneric) \ + _(CantInlineNoTarget) \ + _(CantInlineNotInterpreted) \ + _(CantInlineNoBaseline) \ + _(CantInlineLazy) \ + _(CantInlineNotConstructor) \ + _(CantInlineDisabledIon) \ + _(CantInlineTooManyArgs) \ + _(CantInlineRecursive) \ + _(CantInlineHeavyweight) \ + _(CantInlineNeedsArgsObj) \ + _(CantInlineDebuggee) \ + _(CantInlineUnknownProps) \ + _(CantInlineExceededDepth) \ + _(CantInlineExceededTotalBytecodeLength) \ + _(CantInlineBigCaller) \ + _(CantInlineBigCallee) \ + _(CantInlineNotHot) \ + _(CantInlineNotInDispatch) \ + _(CantInlineUnreachable) \ + _(CantInlineNativeBadForm) \ + _(CantInlineNativeBadType) \ + _(CantInlineNativeNoTemplateObj) \ + _(CantInlineBound) \ \ - _(GenericSuccess, \ - "success") \ - _(Inlined, \ - "inlined") \ - _(DOM, \ - "DOM") \ - _(Monomorphic, \ - "monomorphic") \ - _(Polymorphic, \ - "polymorphic") + _(GenericSuccess) \ + _(Inlined) \ + _(DOM) \ + _(Monomorphic) \ + _(Polymorphic) #define TRACKED_TYPESITE_LIST(_) \ - _(Receiver, \ - "receiver object") \ - _(Index, \ - "index") \ - _(Value, \ - "value") \ - _(Call_Target, \ - "call target") \ - _(Call_This, \ - "call 'this'") \ - _(Call_Arg, \ - "call argument") \ - _(Call_Return, \ - "call return") + _(Receiver) \ + _(Index) \ + _(Value) \ + _(Call_Target) \ + _(Call_This) \ + _(Call_Arg) \ + _(Call_Return) enum class TrackedStrategy : uint32_t { -#define STRATEGY_OP(name, msg) name, +#define STRATEGY_OP(name) name, TRACKED_STRATEGY_LIST(STRATEGY_OP) #undef STRATEGY_OPT @@ -260,7 +149,7 @@ enum class TrackedStrategy : uint32_t { }; enum class TrackedOutcome : uint32_t { -#define OUTCOME_OP(name, msg) name, +#define OUTCOME_OP(name) name, TRACKED_OUTCOME_LIST(OUTCOME_OP) #undef OUTCOME_OP @@ -268,20 +157,20 @@ enum class TrackedOutcome : uint32_t { }; enum class TrackedTypeSite : uint32_t { -#define TYPESITE_OP(name, msg) name, +#define TYPESITE_OP(name) name, TRACKED_TYPESITE_LIST(TYPESITE_OP) #undef TYPESITE_OP Count }; -extern JS_PUBLIC_API(const char *) +JS_PUBLIC_API(const char *) TrackedStrategyString(TrackedStrategy strategy); -extern JS_PUBLIC_API(const char *) +JS_PUBLIC_API(const char *) TrackedOutcomeString(TrackedOutcome outcome); -extern JS_PUBLIC_API(const char *) +JS_PUBLIC_API(const char *) TrackedTypeSiteString(TrackedTypeSite site); struct ForEachTrackedOptimizationAttemptOp @@ -290,7 +179,7 @@ struct ForEachTrackedOptimizationAttemptOp }; JS_PUBLIC_API(void) -ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr, +ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr, uint8_t index, ForEachTrackedOptimizationAttemptOp &op, JSScript **scriptOut, jsbytecode **pcOut); @@ -335,10 +224,13 @@ struct ForEachTrackedOptimizationTypeInfoOp virtual void operator()(TrackedTypeSite site, const char *mirType) = 0; }; -extern JS_PUBLIC_API(void) -ForEachTrackedOptimizationTypeInfo(JSRuntime *rt, void *addr, +JS_PUBLIC_API(void) +ForEachTrackedOptimizationTypeInfo(JSRuntime *rt, void *addr, uint8_t index, ForEachTrackedOptimizationTypeInfoOp &op); +JS_PUBLIC_API(mozilla::Maybe) +TrackedOptimizationIndexAtAddr(JSRuntime *rt, void *addr, void **entryAddr); + } // namespace JS #endif // js_TrackedOptimizationInfo_h diff --git a/js/src/asmjs/AsmJSValidate.cpp b/js/src/asmjs/AsmJSValidate.cpp index 204ee389105..10c1de1b90b 100644 --- a/js/src/asmjs/AsmJSValidate.cpp +++ b/js/src/asmjs/AsmJSValidate.cpp @@ -2732,7 +2732,7 @@ class FunctionCompiler if (inDeadCode()) return nullptr; - MSimdSwizzle *ins = MSimdSwizzle::NewAsmJS(alloc(), vector, type, X, Y, Z, W); + MSimdSwizzle *ins = MSimdSwizzle::New(alloc(), vector, type, X, Y, Z, W); curBlock_->add(ins); return ins; } @@ -2743,7 +2743,7 @@ class FunctionCompiler if (inDeadCode()) return nullptr; - MInstruction *ins = MSimdShuffle::NewAsmJS(alloc(), lhs, rhs, type, X, Y, Z, W); + MInstruction *ins = MSimdShuffle::New(alloc(), lhs, rhs, type, X, Y, Z, W); curBlock_->add(ins); return ins; } @@ -9360,9 +9360,6 @@ EstablishPreconditions(ExclusiveContext *cx, AsmJSParser &parser) if (!parser.options().asmJSOption) return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by javascript.options.asmjs in about:config"); - if (!parser.options().compileAndGo) - return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Temporarily disabled for event-handler and other cloneable scripts"); - if (cx->compartment()->debuggerObservesAsmJS()) return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by debugger"); diff --git a/js/src/builtin/Eval.cpp b/js/src/builtin/Eval.cpp index c1365ed2dc0..b47071bc2e7 100644 --- a/js/src/builtin/Eval.cpp +++ b/js/src/builtin/Eval.cpp @@ -212,6 +212,18 @@ TryEvalJSON(JSContext *cx, JSLinearString *str, MutableHandleValue rval) : ParseEvalStringAsJSON(cx, linearChars.twoByteRange(), rval); } +static bool +HasPollutedScopeChain(JSObject* scopeChain) +{ + while (scopeChain) { + if (scopeChain->is()) + return true; + scopeChain = scopeChain->enclosingScope(); + } + + return false; +} + // Define subset of ExecuteType so that casting performs the injection. enum EvalType { DIRECT_EVAL = EXECUTE_DIRECT_EVAL, INDIRECT_EVAL = EXECUTE_INDIRECT_EVAL }; @@ -314,9 +326,14 @@ EvalKernel(JSContext *cx, const CallArgs &args, EvalType evalType, AbstractFrame if (!staticScope) return false; + bool hasPollutedGlobalScope = + HasPollutedScopeChain(scopeobj) || + (evalType == DIRECT_EVAL && callerScript->hasPollutedGlobalScope()); + CompileOptions options(cx); options.setFileAndLine(filename, 1) .setCompileAndGo(true) + .setHasPollutedScope(hasPollutedGlobalScope) .setForEval(true) .setNoScriptRval(false) .setMutedErrors(mutedErrors) @@ -399,6 +416,8 @@ js::DirectEvalStringFromIon(JSContext *cx, CompileOptions options(cx); options.setFileAndLine(filename, 1) .setCompileAndGo(true) + .setHasPollutedScope(HasPollutedScopeChain(scopeobj) || + callerScript->hasPollutedGlobalScope()) .setForEval(true) .setNoScriptRval(false) .setMutedErrors(mutedErrors) @@ -502,6 +521,7 @@ js::ExecuteInGlobalAndReturnScope(JSContext *cx, HandleObject global, HandleScri CHECK_REQUEST(cx); assertSameCompartment(cx, global); MOZ_ASSERT(global->is()); + MOZ_RELEASE_ASSERT(scriptArg->hasPollutedGlobalScope()); RootedScript script(cx, scriptArg); if (script->compartment() != cx->compartment()) { diff --git a/js/src/builtin/SIMD.h b/js/src/builtin/SIMD.h index 4ae2ce1010b..6051d2dd8f8 100644 --- a/js/src/builtin/SIMD.h +++ b/js/src/builtin/SIMD.h @@ -242,19 +242,19 @@ _(not) \ _(neg) \ _(swizzle) \ - _(load) \ - _(store) \ - _(check) -#define FOREACH_COMMONX4_SIMD_OP(_) \ - ION_COMMONX4_SIMD_OP(_) \ - COMP_COMMONX4_TO_INT32X4_SIMD_OP(_) \ _(shuffle) \ + _(load) \ _(loadX) \ _(loadXY) \ _(loadXYZ) \ + _(store) \ _(storeX) \ _(storeXY) \ - _(storeXYZ) + _(storeXYZ) \ + _(check) +#define FOREACH_COMMONX4_SIMD_OP(_) \ + ION_COMMONX4_SIMD_OP(_) \ + COMP_COMMONX4_TO_INT32X4_SIMD_OP(_) #define FORALL_SIMD_OP(_) \ FOREACH_INT32X4_SIMD_OP(_) \ FOREACH_FLOAT32X4_SIMD_OP(_) \ diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 74134eedf1e..a9de2d85412 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -2273,6 +2273,7 @@ EvalReturningScope(JSContext *cx, unsigned argc, jsval *vp) options.setFileAndLine(filename.get(), lineno); options.setNoScriptRval(true); options.setCompileAndGo(false); + options.setHasPollutedScope(true); JS::SourceBufferHolder srcBuf(src, srclen, JS::SourceBufferHolder::NoOwnership); RootedScript script(cx); @@ -2362,7 +2363,7 @@ ShellCloneAndExecuteScript(JSContext *cx, unsigned argc, Value *vp) AutoCompartment ac(cx, global); - if (!JS::CloneAndExecuteScript(cx, global, script)) + if (!JS::CloneAndExecuteScript(cx, script)) return false; args.rval().setUndefined(); diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index c2021d0e8ce..b1be2c877ae 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -147,6 +147,7 @@ CanLazilyParse(ExclusiveContext *cx, const ReadOnlyCompileOptions &options) { return options.canLazilyParse && options.compileAndGo && + !options.hasPollutedGlobalScope && !cx->compartment()->options().discardSource() && !options.sourceIsLazy; } @@ -282,7 +283,7 @@ frontend::CompileScript(ExclusiveContext *cx, LifoAlloc *alloc, HandleObject sco return nullptr; Directives directives(options.strictOption); - GlobalSharedContext globalsc(cx, scopeChain, directives, options.extraWarningsOption); + GlobalSharedContext globalsc(cx, directives, options.extraWarningsOption); bool savedCallerFun = evalCaller && evalCaller->functionOrCallerFunction(); Rooted script(cx, JSScript::Create(cx, evalStaticScope, savedCallerFun, diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 46231c11d05..d79c37af1f0 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -2158,21 +2158,9 @@ BytecodeEmitter::checkSingletonContext() bool BytecodeEmitter::needsImplicitThis() { - if (!script->compileAndGo()) + if (sc->isFunctionBox() && sc->asFunctionBox()->inWith) return true; - if (sc->isFunctionBox()) { - if (sc->asFunctionBox()->inWith) - return true; - } else { - JSObject *scope = sc->asGlobalSharedContext()->scopeChain(); - while (scope) { - if (scope->is()) - return true; - scope = scope->enclosingScope(); - } - } - for (StmtInfoBCE *stmt = topStmt; stmt; stmt = stmt->down) { if (stmt->type == STMT_WITH) return true; @@ -2347,8 +2335,10 @@ EmitNameOp(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool callC /* Need to provide |this| value for call */ if (callContext) { - if (op == JSOP_GETNAME && bce->needsImplicitThis()) { - if (!EmitAtomOp(cx, pn, JSOP_IMPLICITTHIS, bce)) + if (op == JSOP_GETNAME) { + JSOp thisOp = + bce->needsImplicitThis() ? JSOP_IMPLICITTHIS : JSOP_GIMPLICITTHIS; + if (!EmitAtomOp(cx, pn, thisOp, bce)) return false; } else { if (Emit1(cx, bce, JSOP_UNDEFINED) < 0) @@ -5401,6 +5391,7 @@ EmitFunc(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool needsPr CompileOptions options(cx, bce->parser->options()); options.setMutedErrors(parent->mutedErrors()) .setCompileAndGo(parent->compileAndGo()) + .setHasPollutedScope(parent->hasPollutedGlobalScope()) .setSelfHostingMode(parent->selfHosted()) .setNoScriptRval(false) .setForEval(false) diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 324fcaf223d..971c1854d41 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -624,23 +624,6 @@ FunctionBox::FunctionBox(ExclusiveContext *cx, ObjectBox* traceListHead, JSFunct // outerpc->parsingWith is true. inWith = true; - } else if (outerpc->sc->isGlobalSharedContext()) { - // This covers the case where a function is nested within an eval() - // within a |with| statement. - // - // with (o) { eval("(function() { g(); })();"); } - // - // In this case, |outerpc| corresponds to the eval(), - // outerpc->parsingWith is false because the eval() breaks the - // ParseContext chain, and |parent| is nullptr (again because of the - // eval(), so we have to look at |outerpc|'s scopeChain. - // - JSObject *scope = outerpc->sc->asGlobalSharedContext()->scopeChain(); - while (scope) { - if (scope->is()) - inWith = true; - scope = scope->enclosingScope(); - } } else if (outerpc->sc->isFunctionBox()) { // This is like the above case, but for more deeply nested functions. // For example: @@ -716,7 +699,7 @@ Parser::parse(JSObject *chain) * protected from the GC by a root or a stack frame reference. */ Directives directives(options().strictOption); - GlobalSharedContext globalsc(context, chain, directives, options().extraWarningsOption); + GlobalSharedContext globalsc(context, directives, options().extraWarningsOption); ParseContext globalpc(this, /* parent = */ nullptr, ParseHandler::null(), &globalsc, /* newDirectives = */ nullptr, /* staticLevel = */ 0, /* bodyid = */ 0, diff --git a/js/src/frontend/SharedContext.h b/js/src/frontend/SharedContext.h index 3857e14c599..f0101bb0d8c 100644 --- a/js/src/frontend/SharedContext.h +++ b/js/src/frontend/SharedContext.h @@ -193,9 +193,7 @@ class SharedContext {} virtual ObjectBox *toObjectBox() = 0; - inline bool isGlobalSharedContext() { return toObjectBox() == nullptr; } inline bool isFunctionBox() { return toObjectBox() && toObjectBox()->isFunctionBox(); } - inline GlobalSharedContext *asGlobalSharedContext(); inline FunctionBox *asFunctionBox(); bool hasExplicitUseStrict() const { return anyCxFlags.hasExplicitUseStrict; } @@ -231,27 +229,15 @@ class SharedContext class GlobalSharedContext : public SharedContext { - private: - const RootedObject scopeChain_; /* scope chain object for the script */ - public: - GlobalSharedContext(ExclusiveContext *cx, JSObject *scopeChain, + GlobalSharedContext(ExclusiveContext *cx, Directives directives, bool extraWarnings) - : SharedContext(cx, directives, extraWarnings), - scopeChain_(cx, scopeChain) + : SharedContext(cx, directives, extraWarnings) {} ObjectBox *toObjectBox() { return nullptr; } - JSObject *scopeChain() const { return scopeChain_; } }; -inline GlobalSharedContext * -SharedContext::asGlobalSharedContext() -{ - MOZ_ASSERT(isGlobalSharedContext()); - return static_cast(this); -} - class FunctionBox : public ObjectBox, public SharedContext { public: diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h index 6c666f17ec0..17d79263ef3 100644 --- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -1018,6 +1018,8 @@ class GCRuntime JSGCMode mode; + mozilla::Atomic numActiveZoneIters; + uint64_t decommitThreshold; /* During shutdown, the GC needs to clean up every possible object. */ @@ -1303,6 +1305,22 @@ class GCRuntime friend class js::GCHelperState; friend class js::gc::MarkingValidator; friend class js::gc::AutoTraceSession; + friend class AutoEnterIteration; +}; + +/* Prevent compartments and zones from being collected during iteration. */ +class AutoEnterIteration { + GCRuntime *gc; + + public: + explicit AutoEnterIteration(GCRuntime *gc_) : gc(gc_) { + ++gc->numActiveZoneIters; + } + + ~AutoEnterIteration() { + MOZ_ASSERT(gc->numActiveZoneIters); + --gc->numActiveZoneIters; + } }; #ifdef JS_GC_ZEAL diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index 68bb4d907e4..c0e0f467a3a 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -76,7 +76,9 @@ enum InitialHeap { }; /* The GC allocation kinds. */ -enum class AllocKind : uint8_t { +// FIXME: uint8_t would make more sense for the underlying type, but causes +// miscompilations in GCC (fixed in 4.8.5 and 4.9.3). See also bug 1143966. +enum class AllocKind { FIRST, OBJECT0 = FIRST, OBJECT0_BACKGROUND, diff --git a/js/src/gc/Zone.h b/js/src/gc/Zone.h index 1b39147faf7..8b72823714f 100644 --- a/js/src/gc/Zone.h +++ b/js/src/gc/Zone.h @@ -328,10 +328,11 @@ enum ZoneSelector { class ZonesIter { + gc::AutoEnterIteration iterMarker; JS::Zone **it, **end; public: - ZonesIter(JSRuntime *rt, ZoneSelector selector) { + ZonesIter(JSRuntime *rt, ZoneSelector selector) : iterMarker(&rt->gc) { it = rt->gc.zones.begin(); end = rt->gc.zones.end(); @@ -402,12 +403,13 @@ struct CompartmentsInZoneIter template class CompartmentsIterT { + gc::AutoEnterIteration iterMarker; ZonesIterT zone; mozilla::Maybe comp; public: explicit CompartmentsIterT(JSRuntime *rt) - : zone(rt) + : iterMarker(&rt->gc), zone(rt) { if (zone.done()) comp.emplace(); @@ -416,7 +418,7 @@ class CompartmentsIterT } CompartmentsIterT(JSRuntime *rt, ZoneSelector selector) - : zone(rt, selector) + : iterMarker(&rt->gc), zone(rt, selector) { if (zone.done()) comp.emplace(); diff --git a/js/src/jit-test/tests/SIMD/load.js b/js/src/jit-test/tests/SIMD/load.js index 89a1fd27cc0..3843d1e8e02 100644 --- a/js/src/jit-test/tests/SIMD/load.js +++ b/js/src/jit-test/tests/SIMD/load.js @@ -15,10 +15,10 @@ function f() { var i8 = new Int8Array(f32.buffer); var u8 = new Uint8Array(f32.buffer); - for (var i = 0; i < 150; i++) { - assertEqX4(SIMD.float32x4.load(f64, 0), [1,2,3,4]); - assertEqX4(SIMD.float32x4.load(f32, 1), [2,3,4,5]); - assertEqX4(SIMD.float32x4.load(i32, 2), [3,4,5,6]); + function testLoad() { + assertEqX4(SIMD.float32x4.load(f64, 0), [1,2,3,4]); + assertEqX4(SIMD.float32x4.load(f32, 1), [2,3,4,5]); + assertEqX4(SIMD.float32x4.load(i32, 2), [3,4,5,6]); assertEqX4(SIMD.float32x4.load(i16, 3 << 1), [4,5,6,7]); assertEqX4(SIMD.float32x4.load(u16, 4 << 1), [5,6,7,8]); assertEqX4(SIMD.float32x4.load(i8 , 5 << 2), [6,7,8,9]); @@ -32,6 +32,67 @@ function f() { assertEqX4(SIMD.float32x4.load(i8, (16 << 2) - (4 << 2)), [13,14,15,16]); assertEqX4(SIMD.float32x4.load(u8, (16 << 2) - (4 << 2)), [13,14,15,16]); } + + function testLoadX() { + assertEqX4(SIMD.float32x4.loadX(f64, 0), [1,0,0,0]); + assertEqX4(SIMD.float32x4.loadX(f32, 1), [2,0,0,0]); + assertEqX4(SIMD.float32x4.loadX(i32, 2), [3,0,0,0]); + assertEqX4(SIMD.float32x4.loadX(i16, 3 << 1), [4,0,0,0]); + assertEqX4(SIMD.float32x4.loadX(u16, 4 << 1), [5,0,0,0]); + assertEqX4(SIMD.float32x4.loadX(i8 , 5 << 2), [6,0,0,0]); + assertEqX4(SIMD.float32x4.loadX(u8 , 6 << 2), [7,0,0,0]); + + assertEqX4(SIMD.float32x4.loadX(f64, (16 >> 1) - (4 >> 1)), [13,0,0,0]); + assertEqX4(SIMD.float32x4.loadX(f32, 16 - 4), [13,0,0,0]); + assertEqX4(SIMD.float32x4.loadX(i32, 16 - 4), [13,0,0,0]); + assertEqX4(SIMD.float32x4.loadX(i16, (16 << 1) - (4 << 1)), [13,0,0,0]); + assertEqX4(SIMD.float32x4.loadX(u16, (16 << 1) - (4 << 1)), [13,0,0,0]); + assertEqX4(SIMD.float32x4.loadX(i8, (16 << 2) - (4 << 2)), [13,0,0,0]); + assertEqX4(SIMD.float32x4.loadX(u8, (16 << 2) - (4 << 2)), [13,0,0,0]); + } + + function testLoadXY() { + assertEqX4(SIMD.float32x4.loadXY(f64, 0), [1,2,0,0]); + assertEqX4(SIMD.float32x4.loadXY(f32, 1), [2,3,0,0]); + assertEqX4(SIMD.float32x4.loadXY(i32, 2), [3,4,0,0]); + assertEqX4(SIMD.float32x4.loadXY(i16, 3 << 1), [4,5,0,0]); + assertEqX4(SIMD.float32x4.loadXY(u16, 4 << 1), [5,6,0,0]); + assertEqX4(SIMD.float32x4.loadXY(i8 , 5 << 2), [6,7,0,0]); + assertEqX4(SIMD.float32x4.loadXY(u8 , 6 << 2), [7,8,0,0]); + + assertEqX4(SIMD.float32x4.loadXY(f64, (16 >> 1) - (4 >> 1)), [13,14,0,0]); + assertEqX4(SIMD.float32x4.loadXY(f32, 16 - 4), [13,14,0,0]); + assertEqX4(SIMD.float32x4.loadXY(i32, 16 - 4), [13,14,0,0]); + assertEqX4(SIMD.float32x4.loadXY(i16, (16 << 1) - (4 << 1)), [13,14,0,0]); + assertEqX4(SIMD.float32x4.loadXY(u16, (16 << 1) - (4 << 1)), [13,14,0,0]); + assertEqX4(SIMD.float32x4.loadXY(i8, (16 << 2) - (4 << 2)), [13,14,0,0]); + assertEqX4(SIMD.float32x4.loadXY(u8, (16 << 2) - (4 << 2)), [13,14,0,0]); + } + + function testLoadXYZ() { + assertEqX4(SIMD.float32x4.loadXYZ(f64, 0), [1,2,3,0]); + assertEqX4(SIMD.float32x4.loadXYZ(f32, 1), [2,3,4,0]); + assertEqX4(SIMD.float32x4.loadXYZ(i32, 2), [3,4,5,0]); + assertEqX4(SIMD.float32x4.loadXYZ(i16, 3 << 1), [4,5,6,0]); + assertEqX4(SIMD.float32x4.loadXYZ(u16, 4 << 1), [5,6,7,0]); + assertEqX4(SIMD.float32x4.loadXYZ(i8 , 5 << 2), [6,7,8,0]); + assertEqX4(SIMD.float32x4.loadXYZ(u8 , 6 << 2), [7,8,9,0]); + + assertEqX4(SIMD.float32x4.loadXYZ(f64, (16 >> 1) - (4 >> 1)), [13,14,15,0]); + assertEqX4(SIMD.float32x4.loadXYZ(f32, 16 - 4), [13,14,15,0]); + assertEqX4(SIMD.float32x4.loadXYZ(i32, 16 - 4), [13,14,15,0]); + assertEqX4(SIMD.float32x4.loadXYZ(i16, (16 << 1) - (4 << 1)), [13,14,15,0]); + assertEqX4(SIMD.float32x4.loadXYZ(u16, (16 << 1) - (4 << 1)), [13,14,15,0]); + assertEqX4(SIMD.float32x4.loadXYZ(i8, (16 << 2) - (4 << 2)), [13,14,15,0]); + assertEqX4(SIMD.float32x4.loadXYZ(u8, (16 << 2) - (4 << 2)), [13,14,15,0]); + } + + for (var i = 0; i < 150; i++) { + testLoad(); + testLoadX(); + testLoadXY(); + testLoadXYZ(); + } } f(); diff --git a/js/src/jit-test/tests/SIMD/shuffle.js b/js/src/jit-test/tests/SIMD/shuffle.js new file mode 100644 index 00000000000..33a09e68e8d --- /dev/null +++ b/js/src/jit-test/tests/SIMD/shuffle.js @@ -0,0 +1,81 @@ +if (!this.hasOwnProperty("SIMD")) + quit(); + +load(libdir + 'simd.js'); + +setJitCompilerOption("ion.warmup.trigger", 50); + +function f() { + var i1 = SIMD.int32x4(1, 2, 3, 4); + var i2 = SIMD.int32x4(5, 6, 7, 8); + + var leet = Math.fround(13.37); + var f1 = SIMD.float32x4(-.5, -0, Infinity, leet); + var f2 = SIMD.float32x4(42, .5, 23, -10); + + // computes all rotations of a given array + function *gen(arr) { + var previous = arr.slice().splice(0, 4); + var i = 4; + for (var j = 0; j < 8; j++) { + yield previous.slice(); + previous = previous.splice(1, previous.length - 1); + previous.push(arr[i]); + i = (i + 1) % arr.length; + } + } + + var compI = []; + for (var k of gen([i1.x, i1.y, i1.z, i1.w, i2.x, i2.y, i2.z, i2.w])) + compI.push(k); + + var compF = []; + for (var k of gen([f1.x, f1.y, f1.z, f1.w, f2.x, f2.y, f2.z, f2.w])) + compF.push(k); + + for (var i = 0; i < 150; i++) { + // Variable lanes + var r = SIMD.float32x4.shuffle(f1, f2, i % 8, (i + 1) % 8, (i + 2) % 8, (i + 3) % 8); + assertEqX4(r, compF[i % 8]); + + // Constant lanes + assertEqX4(SIMD.float32x4.shuffle(f1, f2, 3, 2, 4, 5), [leet, Infinity, 42, .5]); + + // Variable lanes + var r = SIMD.int32x4.shuffle(i1, i2, i % 8, (i + 1) % 8, (i + 2) % 8, (i + 3) % 8); + assertEqX4(r, compI[i % 8]); + + // Constant lanes + assertEqX4(SIMD.int32x4.shuffle(i1, i2, 3, 2, 4, 5), [4, 3, 5, 6]); + } +} + +function testBailouts(uglyDuckling) { + var i1 = SIMD.int32x4(1, 2, 3, 4); + var i2 = SIMD.int32x4(5, 6, 7, 8); + + for (var i = 0; i < 150; i++) { + // Test bailouts + var value = i == 149 ? uglyDuckling : 3; + var caught = false; + try { + assertEqX4(SIMD.int32x4.shuffle(i1, i2, value, 2, 4, 5), [4, 3, 5, 6]); + } catch(e) { + print(e); + caught = true; + assertEq(i, 149); + assertEq(e instanceof TypeError, true); + } + assertEq(i < 149 || caught, true); + } +} + +f(); +testBailouts(-1); +testBailouts(8); +testBailouts(2.5); +testBailouts(undefined); +testBailouts(null); +testBailouts({}); +testBailouts('one'); +testBailouts(true); diff --git a/js/src/jit-test/tests/SIMD/store.js b/js/src/jit-test/tests/SIMD/store.js index 03374b26a71..c23cac9d4db 100644 --- a/js/src/jit-test/tests/SIMD/store.js +++ b/js/src/jit-test/tests/SIMD/store.js @@ -17,11 +17,11 @@ function f() { var f4 = SIMD.float32x4(42, 43, 44, 45); - function check() { + function check(n) { assertEq(f32[0], 42); - assertEq(f32[1], 43); - assertEq(f32[2], 44); - assertEq(f32[3], 45); + assertEq(f32[1], n > 1 ? 43 : 2); + assertEq(f32[2], n > 2 ? 44 : 3); + assertEq(f32[3], n > 3 ? 45 : 4); f32[0] = 1; f32[1] = 2; @@ -29,23 +29,87 @@ function f() { f32[3] = 4; } - for (var i = 0; i < 150; i++) { + function testStore() { SIMD.float32x4.store(f64, 0, f4); - check(); + check(4); SIMD.float32x4.store(f32, 0, f4); - check(); + check(4); SIMD.float32x4.store(i32, 0, f4); - check(); + check(4); SIMD.float32x4.store(u32, 0, f4); - check(); + check(4); SIMD.float32x4.store(i16, 0, f4); - check(); + check(4); SIMD.float32x4.store(u16, 0, f4); - check(); + check(4); SIMD.float32x4.store(i8, 0, f4); - check(); + check(4); SIMD.float32x4.store(u8, 0, f4); - check(); + check(4); + } + + function testStoreX() { + SIMD.float32x4.storeX(f64, 0, f4); + check(1); + SIMD.float32x4.storeX(f32, 0, f4); + check(1); + SIMD.float32x4.storeX(i32, 0, f4); + check(1); + SIMD.float32x4.storeX(u32, 0, f4); + check(1); + SIMD.float32x4.storeX(i16, 0, f4); + check(1); + SIMD.float32x4.storeX(u16, 0, f4); + check(1); + SIMD.float32x4.storeX(i8, 0, f4); + check(1); + SIMD.float32x4.storeX(u8, 0, f4); + check(1); + } + + function testStoreXY() { + SIMD.float32x4.storeXY(f64, 0, f4); + check(2); + SIMD.float32x4.storeXY(f32, 0, f4); + check(2); + SIMD.float32x4.storeXY(i32, 0, f4); + check(2); + SIMD.float32x4.storeXY(u32, 0, f4); + check(2); + SIMD.float32x4.storeXY(i16, 0, f4); + check(2); + SIMD.float32x4.storeXY(u16, 0, f4); + check(2); + SIMD.float32x4.storeXY(i8, 0, f4); + check(2); + SIMD.float32x4.storeXY(u8, 0, f4); + check(2); + } + + function testStoreXYZ() { + SIMD.float32x4.storeXYZ(f64, 0, f4); + check(3); + SIMD.float32x4.storeXYZ(f32, 0, f4); + check(3); + SIMD.float32x4.storeXYZ(i32, 0, f4); + check(3); + SIMD.float32x4.storeXYZ(u32, 0, f4); + check(3); + SIMD.float32x4.storeXYZ(i16, 0, f4); + check(3); + SIMD.float32x4.storeXYZ(u16, 0, f4); + check(3); + SIMD.float32x4.storeXYZ(i8, 0, f4); + check(3); + SIMD.float32x4.storeXYZ(u8, 0, f4); + check(3); + } + + for (var i = 0; i < 150; i++) { + testStore(); + testStoreX(); + testStoreXY(); + testStoreXYZ(); } } diff --git a/js/src/jit-test/tests/asm.js/testBug893519.js b/js/src/jit-test/tests/asm.js/testBug893519.js index 4528627577f..d4301009310 100644 --- a/js/src/jit-test/tests/asm.js/testBug893519.js +++ b/js/src/jit-test/tests/asm.js/testBug893519.js @@ -1,3 +1,10 @@ +// |jit-test| error:Error + +if (!isAsmJSCompilationAvailable()) { + throw new Error('this test expects an error to be thrown, here it is'); + quit(); +} + var g = newGlobal(); evaluate("function h() { function f() { 'use asm'; function g() { return 42 } return g } return f }", { compileAndGo:false, global:g}); var h = clone(g.h); diff --git a/js/src/jit-test/tests/ion/lexical-check-1.js b/js/src/jit-test/tests/ion/lexical-check-1.js new file mode 100644 index 00000000000..e1ba1baa17b --- /dev/null +++ b/js/src/jit-test/tests/ion/lexical-check-1.js @@ -0,0 +1,15 @@ +function f() { + const x = 42; + function g() { + var s = 0; + for (var i = 100; i--;) + s += x; + return s; + } + return g; +} + +var func = f(); +for (var i = 200; i--;) + assertEq(func(), 4200); + diff --git a/js/src/jit-test/tests/ion/lexical-check-2.js b/js/src/jit-test/tests/ion/lexical-check-2.js new file mode 100644 index 00000000000..30dbb67b97a --- /dev/null +++ b/js/src/jit-test/tests/ion/lexical-check-2.js @@ -0,0 +1,22 @@ +function f(i) { + if (i == 1500) + g(); + const x = 42; + function g() { + return x; + } + return g; +} + +var caught = false; +var i; +try { + for (i = 0; i < 2000; i++) + assertEq(f(i)(), 42); +} catch(e) { + assertEq(e instanceof ReferenceError, true); + assertEq(i, 1500); + caught = true; +} +assertEq(caught, true); + diff --git a/js/src/jit-test/tests/ion/lexical-check-3.js b/js/src/jit-test/tests/ion/lexical-check-3.js new file mode 100644 index 00000000000..dd10b1bc705 --- /dev/null +++ b/js/src/jit-test/tests/ion/lexical-check-3.js @@ -0,0 +1,23 @@ +function f() { + + function g(n) { + n = n|0; + var s = 0; + for (var i = 0; (i = i + 1 |0) < 1000;) { + s = s * i; + if (!n) { + s = x; + } + } + return s; + } + + return g; + let x; +} + +var func = f(); +var r; +for (var i = 0; i < 2000; i++) + r = func(i + 1); +assertEq(r, 0); diff --git a/js/src/jit/BaselineBailouts.cpp b/js/src/jit/BaselineBailouts.cpp index 083dadd536a..c997b593690 100644 --- a/js/src/jit/BaselineBailouts.cpp +++ b/js/src/jit/BaselineBailouts.cpp @@ -1622,6 +1622,28 @@ HandleBaselineInfoBailout(JSContext *cx, JSScript *outerScript, JSScript *innerS return Invalidate(cx, outerScript); } +static bool +HandleLexicalCheckFailure(JSContext *cx, HandleScript outerScript, HandleScript innerScript) +{ + JitSpew(JitSpew_IonBailouts, "Lexical check failure %s:%d, inlined into %s:%d", + innerScript->filename(), innerScript->lineno(), + outerScript->filename(), outerScript->lineno()); + + MOZ_ASSERT(!outerScript->ionScript()->invalidated()); + + if (!innerScript->failedLexicalCheck()) + innerScript->setFailedLexicalCheck(); + + JitSpew(JitSpew_BaselineBailouts, "Invalidating due to lexical check failure"); + if (!Invalidate(cx, outerScript)) + return false; + + if (innerScript->hasIonScript() && !Invalidate(cx, innerScript)) + return false; + + return true; +} + static bool CopyFromRematerializedFrame(JSContext *cx, JitActivation *act, uint8_t *fp, size_t inlineDepth, BaselineFrame *frame) @@ -1833,6 +1855,10 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo *bailoutInfo) if (!HandleShapeGuardFailure(cx, outerScript, innerScript)) return false; break; + case Bailout_UninitializedLexical: + if (!HandleLexicalCheckFailure(cx, outerScript, innerScript)) + return false; + break; case Bailout_IonExceptionDebugMode: // Return false to resume in HandleException with reconstructed // baseline frame. diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 6d065383cef..771fc83445a 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -1223,6 +1223,7 @@ BaselineCompiler::emit_JSOP_VOID() bool BaselineCompiler::emit_JSOP_UNDEFINED() { + // If this ever changes, change what JSOP_GIMPLICITTHIS does too. frame.push(UndefinedValue()); return true; } @@ -2849,6 +2850,17 @@ BaselineCompiler::emit_JSOP_IMPLICITTHIS() return true; } +bool +BaselineCompiler::emit_JSOP_GIMPLICITTHIS() +{ + if (!script->hasPollutedGlobalScope()) { + frame.push(UndefinedValue()); + return true; + } + + return emit_JSOP_IMPLICITTHIS(); +} + bool BaselineCompiler::emit_JSOP_INSTANCEOF() { diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h index 234cfedc605..6abf948359e 100644 --- a/js/src/jit/BaselineCompiler.h +++ b/js/src/jit/BaselineCompiler.h @@ -159,6 +159,7 @@ namespace jit { _(JSOP_SPREADEVAL) \ _(JSOP_STRICTSPREADEVAL) \ _(JSOP_IMPLICITTHIS) \ + _(JSOP_GIMPLICITTHIS) \ _(JSOP_INSTANCEOF) \ _(JSOP_TYPEOF) \ _(JSOP_TYPEOFEXPR) \ diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 9aa8a894b78..743b80fd359 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -168,7 +168,6 @@ ICStub::updateCode(JitCode *code) void ReceiverGuard::trace(JSTracer *trc) { - MOZ_ASSERT(!!shape_ != !!group_); if (shape_) MarkShape(trc, &shape_, "receiver_guard_shape"); else @@ -347,12 +346,12 @@ ICStub::trace(JSTracer *trc) } case ICStub::GetProp_Native: { ICGetProp_Native *propStub = toGetProp_Native(); - MarkShape(trc, &propStub->shape(), "baseline-getpropnative-stub-shape"); + propStub->receiverGuard().trace(trc); break; } case ICStub::GetProp_NativePrototype: { ICGetProp_NativePrototype *propStub = toGetProp_NativePrototype(); - propStub->guard().trace(trc); + propStub->receiverGuard().trace(trc); MarkObject(trc, &propStub->holder(), "baseline-getpropnativeproto-stub-holder"); MarkShape(trc, &propStub->holderShape(), "baseline-getpropnativeproto-stub-holdershape"); break; @@ -3448,8 +3447,8 @@ IsCacheableSetPropWriteSlot(JSObject *obj, Shape *oldShape, JSObject *holder, Sh } static bool -IsCacheableSetPropAddSlot(JSContext *cx, HandleObject obj, HandleShape oldShape, uint32_t oldSlots, - HandleId id, HandleObject holder, HandleShape shape, +IsCacheableSetPropAddSlot(JSContext *cx, JSObject *obj, Shape *oldShape, + jsid id, JSObject *holder, Shape *shape, size_t *protoChainDepth) { if (!shape) @@ -3497,7 +3496,7 @@ IsCacheableSetPropAddSlot(JSContext *cx, HandleObject obj, HandleShape oldShape, // Only add a IC entry if the dynamic slots didn't change when the shapes // changed. Need to ensure that a shape change for a subsequent object // won't involve reallocating the slot array. - if (obj->as().numDynamicSlots() != oldSlots) + if (NativeObject::dynamicSlotsCount(shape) != NativeObject::dynamicSlotsCount(oldShape)) return false; *protoChainDepth = chainDepth; @@ -5778,7 +5777,7 @@ UpdateExistingGetPropCallStubs(ICFallbackStub *fallbackStub, bool isOwnGetter = (holder == receiver); bool foundMatchingStub = false; - ReceiverGuard::Token receiverGuard = ReceiverGuard::objectToken(receiver); + ReceiverGuard::StackGuard receiverGuard(receiver); for (ICStubConstIterator iter = fallbackStub->beginChainConst(); !iter.atEnd(); iter++) { if (iter->kind() == kind) { ICGetPropCallGetter *getPropStub = static_cast(*iter); @@ -5804,10 +5803,12 @@ UpdateExistingGetPropCallStubs(ICFallbackStub *fallbackStub, // matches as protos with the old shape flow into it, but always // matches post-get, which is where we are now. getPropStub->holderShape() = holder->lastProperty(); + // Make sure to update the getter, since a shape change might // have changed which getter we want to use. getPropStub->getter() = getter; - if (receiverGuard == getPropStub->receiverGuard().token()) + + if (getPropStub->receiverGuard().matches(receiverGuard)) foundMatchingStub = true; } } @@ -5822,7 +5823,7 @@ static bool UpdateExistingSetPropCallStubs(ICSetProp_Fallback* fallbackStub, ICStub::Kind kind, NativeObject *holder, - ReceiverGuard::Token receiverGuard, + ReceiverGuard::StackGuard receiverGuard, JSFunction *setter) { MOZ_ASSERT(kind == ICStub::SetProp_CallScripted || @@ -5835,13 +5836,13 @@ UpdateExistingSetPropCallStubs(ICSetProp_Fallback* fallbackStub, // We want to update the holder shape to match the new one no // matter what, even if the receiver shape is different. MOZ_ASSERT(setPropStub->holderShape() != holder->lastProperty() || - setPropStub->guard().token() != receiverGuard, + !setPropStub->guard().matches(receiverGuard), "Why didn't we end up using this stub?"); setPropStub->holderShape() = holder->lastProperty(); // Make sure to update the setter, since a shape change might // have changed which setter we want to use. setPropStub->setter() = setter; - if (receiverGuard == setPropStub->guard().token()) + if (setPropStub->guard().matches(receiverGuard)) foundMatchingStub = true; } } @@ -6712,6 +6713,45 @@ TryAttachUnboxedGetPropStub(JSContext *cx, HandleScript script, return true; } +static bool +TryAttachUnboxedExpandoGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, + ICGetProp_Fallback *stub, HandlePropertyName name, HandleValue val, + bool *attached) +{ + MOZ_ASSERT(!*attached); + + if (!val.isObject() || !val.toObject().is()) + return true; + Rooted obj(cx, &val.toObject().as()); + + Rooted expando(cx, obj->maybeExpando()); + if (!expando) + return true; + + Shape *shape = expando->lookup(cx, name); + if (!shape || !shape->hasDefaultGetter() || !shape->hasSlot()) + return true; + + bool isFixedSlot; + uint32_t offset; + GetFixedOrDynamicSlotOffset(expando, shape->slot(), &isFixedSlot, &offset); + + ICStub *monitorStub = stub->fallbackMonitorStub()->firstMonitorStub(); + + bool isCallProp = (JSOp(*pc) == JSOP_CALLPROP); + ICGetPropNativeCompiler compiler(cx, ICStub::GetProp_Native, isCallProp, monitorStub, obj, obj, + name, isFixedSlot, offset); + ICGetPropNativeStub *newStub = compiler.getStub(compiler.getStubSpace(script)); + if (!newStub) + return false; + + StripPreliminaryObjectStubs(cx, stub); + + stub->addNewStub(newStub); + *attached = true; + return true; +} + static bool TryAttachTypedObjectGetPropStub(JSContext *cx, HandleScript script, ICGetProp_Fallback *stub, HandlePropertyName name, HandleValue val, @@ -6967,6 +7007,11 @@ DoGetPropFallback(JSContext *cx, BaselineFrame *frame, ICGetProp_Fallback *stub_ if (attached) return true; + if (!TryAttachUnboxedExpandoGetPropStub(cx, script, pc, stub, name, val, &attached)) + return false; + if (attached) + return true; + if (!TryAttachTypedObjectGetPropStub(cx, script, stub, name, val, &attached)) return false; if (attached) @@ -7145,16 +7190,16 @@ ICGetProp_Primitive::Compiler::generateStubCode(MacroAssembler &masm) ICGetPropNativeStub * ICGetPropNativeCompiler::getStub(ICStubSpace *space) { + ReceiverGuard::StackGuard guard(obj_); + switch (kind) { case ICStub::GetProp_Native: { MOZ_ASSERT(obj_ == holder_); - RootedShape shape(cx, obj_->as().lastProperty()); - return ICStub::New(space, getStubCode(), firstMonitorStub_, shape, offset_); + return ICStub::New(space, getStubCode(), firstMonitorStub_, guard, offset_); } case ICStub::GetProp_NativePrototype: { MOZ_ASSERT(obj_ != holder_); - ReceiverGuard::Token guard = ReceiverGuard::objectToken(obj_); Shape *holderShape = holder_->as().lastProperty(); return ICStub::New(space, getStubCode(), firstMonitorStub_, guard, offset_, holder_, holderShape); @@ -7166,21 +7211,40 @@ ICGetPropNativeCompiler::getStub(ICStubSpace *space) } static void -GuardNativeOrUnboxedReceiver(MacroAssembler &masm, JSObject *obj, +GuardNativeOrUnboxedReceiver(MacroAssembler &masm, ReceiverGuard::StackGuard guard, Register object, Register scratch, size_t receiverGuardOffset, Label *failure) { - if (obj->isNative()) { - masm.loadPtr(Address(BaselineStubReg, - receiverGuardOffset + ReceiverGuard::offsetOfShape()), - scratch); - masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure); - } else { - MOZ_ASSERT(obj->is()); - masm.loadPtr(Address(BaselineStubReg, - receiverGuardOffset + ReceiverGuard::offsetOfGroup()), - scratch); + Address groupAddress(BaselineStubReg, receiverGuardOffset + ReceiverGuard::offsetOfGroup()); + Address shapeAddress(BaselineStubReg, receiverGuardOffset + ReceiverGuard::offsetOfShape()); + Address expandoAddress(object, UnboxedPlainObject::offsetOfExpando()); + + if (guard.group) { + masm.loadPtr(groupAddress, scratch); masm.branchTestObjGroup(Assembler::NotEqual, object, scratch, failure); + + if (guard.group->maybeUnboxedLayout() && !guard.shape) { + // Guard the unboxed object has no expando object. + masm.branchPtr(Assembler::NotEqual, expandoAddress, ImmWord(0), failure); + } + } + + if (guard.shape) { + masm.loadPtr(shapeAddress, scratch); + if (guard.group && guard.group->maybeUnboxedLayout()) { + // Guard the unboxed object has a matching expando object. + masm.branchPtr(Assembler::Equal, expandoAddress, ImmWord(0), failure); + Label done; + masm.push(object); + masm.loadPtr(expandoAddress, object); + masm.branchTestObjShape(Assembler::Equal, object, scratch, &done); + masm.pop(object); + masm.jump(failure); + masm.bind(&done); + masm.pop(object); + } else { + masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure); + } } } @@ -7204,14 +7268,18 @@ ICGetPropNativeCompiler::generateStubCode(MacroAssembler &masm) Register scratch = regs.takeAnyExcluding(BaselineTailCallReg); // Shape/group guard. - MOZ_ASSERT(ICGetProp_Native::offsetOfShape() == - ICGetProp_NativePrototype::offsetOfGuard() + ReceiverGuard::offsetOfShape()); - GuardNativeOrUnboxedReceiver(masm, obj_, objReg, scratch, - ICGetProp_NativePrototype::offsetOfGuard(), &failure); + GuardNativeOrUnboxedReceiver(masm, ReceiverGuard::StackGuard(obj_), objReg, scratch, + ICGetPropNativeStub::offsetOfReceiverGuard(), &failure); Register holderReg; if (obj_ == holder_) { - holderReg = objReg; + if (obj_->is()) { + // We are loading off the expando object, so use that for the holder. + holderReg = regs.takeAny(); + masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg); + } else { + holderReg = objReg; + } } else { // Shape guard holder. holderReg = regs.takeAny(); @@ -7348,7 +7416,7 @@ ICGetPropNativeDoesNotExistCompiler::generateStubCode(MacroAssembler &masm) // Unbox and guard against old shape/group. Register objReg = masm.extractObject(R0, ExtractTemp0); - GuardNativeOrUnboxedReceiver(masm, obj_, objReg, scratch, + GuardNativeOrUnboxedReceiver(masm, ReceiverGuard::StackGuard(obj_), objReg, scratch, ICGetProp_NativeDoesNotExist::offsetOfGuard(), &failure); Register protoReg = regs.takeAny(); @@ -7387,7 +7455,7 @@ ICGetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm) // Unbox and shape guard. Register objReg = masm.extractObject(R0, ExtractTemp0); - GuardNativeOrUnboxedReceiver(masm, receiver_, objReg, scratch, + GuardNativeOrUnboxedReceiver(masm, ReceiverGuard::StackGuard(receiver_), objReg, scratch, ICGetProp_CallScripted::offsetOfReceiverGuard(), &failure); if (receiver_ != holder_) { @@ -7495,7 +7563,7 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler &masm) Register scratch = regs.takeAnyExcluding(BaselineTailCallReg); // Shape guard. - GuardNativeOrUnboxedReceiver(masm, receiver_, objReg, scratch, + GuardNativeOrUnboxedReceiver(masm, ReceiverGuard::StackGuard(receiver_), objReg, scratch, ICGetProp_CallNative::offsetOfReceiverGuard(), &failure); if (receiver_ != holder_ ) { @@ -7985,7 +8053,7 @@ BaselineScript::noteAccessedGetter(uint32_t pcOffset) // value property. static bool TryAttachSetValuePropStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICSetProp_Fallback *stub, - HandleObject obj, HandleShape oldShape, HandleObjectGroup oldGroup, uint32_t oldSlots, + HandleObject obj, HandleShape oldShape, HandleObjectGroup oldGroup, HandlePropertyName name, HandleId id, HandleValue rhs, bool *attached) { MOZ_ASSERT(!*attached); @@ -7999,7 +8067,7 @@ TryAttachSetValuePropStub(JSContext *cx, HandleScript script, jsbytecode *pc, IC return false; size_t chainDepth; - if (IsCacheableSetPropAddSlot(cx, obj, oldShape, oldSlots, id, holder, shape, &chainDepth)) { + if (IsCacheableSetPropAddSlot(cx, obj, oldShape, id, holder, shape, &chainDepth)) { // Don't attach if proto chain depth is too high. if (chainDepth > ICSetProp_NativeAdd::MAX_PROTO_CHAIN_DEPTH) return true; @@ -8072,8 +8140,10 @@ TryAttachSetValuePropStub(JSContext *cx, HandleScript script, jsbytecode *pc, IC // Attach an optimized property set stub for a SETPROP/SETGNAME/SETNAME op on // an accessor property. static bool -TryAttachSetAccessorPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICSetProp_Fallback *stub, - HandleObject obj, ReceiverGuard::Token receiverGuard, HandlePropertyName name, +TryAttachSetAccessorPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, + ICSetProp_Fallback *stub, + HandleObject obj, const ReceiverGuard::RootedStackGuard &receiverGuard, + HandlePropertyName name, HandleId id, HandleValue rhs, bool *attached, bool *isTemporarilyUnoptimizable) { @@ -8255,12 +8325,11 @@ DoSetPropFallback(JSContext *cx, BaselineFrame *frame, ICSetProp_Fallback *stub_ RootedObject obj(cx, ToObjectFromStack(cx, lhs)); if (!obj) return false; - ReceiverGuard::Token oldGuard = ReceiverGuard::objectToken(obj); RootedShape oldShape(cx, obj->maybeShape()); RootedObjectGroup oldGroup(cx, obj->getGroup(cx)); if (!oldGroup) return false; - uint32_t oldSlots = obj->isNative() ? obj->as().numDynamicSlots() : 0; + ReceiverGuard::RootedStackGuard oldGuard(cx, ReceiverGuard::StackGuard(obj)); bool attached = false; // There are some reasons we can fail to attach a stub that are temporary. @@ -8313,8 +8382,8 @@ DoSetPropFallback(JSContext *cx, BaselineFrame *frame, ICSetProp_Fallback *stub_ if (!attached && lhs.isObject() && - !TryAttachSetValuePropStub(cx, script, pc, stub, obj, oldShape, - oldGroup, oldSlots, name, id, rhs, &attached)) + !TryAttachSetValuePropStub(cx, script, pc, stub, obj, oldShape, oldGroup, + name, id, rhs, &attached)) { return false; } @@ -8823,7 +8892,7 @@ ICSetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm) // Unbox and shape guard. Register objReg = masm.extractObject(R0, ExtractTemp0); - GuardNativeOrUnboxedReceiver(masm, obj_, objReg, scratch, + GuardNativeOrUnboxedReceiver(masm, ReceiverGuard::StackGuard(obj_), objReg, scratch, ICSetProp_CallScripted::offsetOfGuard(), &failureUnstow); Register holderReg = regs.takeAny(); @@ -8942,7 +9011,7 @@ ICSetProp_CallNative::Compiler::generateStubCode(MacroAssembler &masm) // Unbox and shape guard. Register objReg = masm.extractObject(R0, ExtractTemp0); - GuardNativeOrUnboxedReceiver(masm, obj_, objReg, scratch, + GuardNativeOrUnboxedReceiver(masm, ReceiverGuard::StackGuard(obj_), objReg, scratch, ICSetProp_CallNative::offsetOfGuard(), &failureUnstow); Register holderReg = regs.takeAny(); @@ -11765,8 +11834,10 @@ ICGetProp_Primitive::ICGetProp_Primitive(JitCode *stubCode, ICStub *firstMonitor { } ICGetPropNativeStub::ICGetPropNativeStub(ICStub::Kind kind, JitCode *stubCode, - ICStub *firstMonitorStub, uint32_t offset) + ICStub *firstMonitorStub, + ReceiverGuard::StackGuard guard, uint32_t offset) : ICMonitoredStub(kind, stubCode, firstMonitorStub), + receiverGuard_(guard), offset_(offset) { } @@ -11774,15 +11845,14 @@ ICGetPropNativeStub::ICGetPropNativeStub(ICStub::Kind kind, JitCode *stubCode, ICGetProp_Native::Clone(ICStubSpace *space, ICStub *firstMonitorStub, ICGetProp_Native &other) { - return New(space, other.jitCode(), firstMonitorStub, other.shape(), + return New(space, other.jitCode(), firstMonitorStub, other.receiverGuard(), other.offset()); } ICGetProp_NativePrototype::ICGetProp_NativePrototype(JitCode *stubCode, ICStub *firstMonitorStub, - ReceiverGuard::Token guard, uint32_t offset, + ReceiverGuard::StackGuard guard, uint32_t offset, JSObject *holder, Shape *holderShape) - : ICGetPropNativeStub(GetProp_NativePrototype, stubCode, firstMonitorStub, offset), - guard_(guard), + : ICGetPropNativeStub(GetProp_NativePrototype, stubCode, firstMonitorStub, guard, offset), holder_(holder), holderShape_(holderShape) { } @@ -11792,12 +11862,13 @@ ICGetProp_NativePrototype::Clone(ICStubSpace *space, ICStub *firstMonitorStub, ICGetProp_NativePrototype &other) { return New(space, other.jitCode(), firstMonitorStub, - other.guard().token(), - other.offset(), other.holder_, other.holderShape_); + other.receiverGuard(), other.offset(), + other.holder_, other.holderShape_); } ICGetProp_NativeDoesNotExist::ICGetProp_NativeDoesNotExist( - JitCode *stubCode, ICStub *firstMonitorStub, ReceiverGuard::Token guard, size_t protoChainDepth) + JitCode *stubCode, ICStub *firstMonitorStub, ReceiverGuard::StackGuard guard, + size_t protoChainDepth) : ICMonitoredStub(GetProp_NativeDoesNotExist, stubCode, firstMonitorStub), guard_(guard) { @@ -11816,7 +11887,7 @@ ICGetProp_NativeDoesNotExist::offsetOfShape(size_t idx) template ICGetProp_NativeDoesNotExistImpl::ICGetProp_NativeDoesNotExistImpl( - JitCode *stubCode, ICStub *firstMonitorStub, ReceiverGuard::Token guard, + JitCode *stubCode, ICStub *firstMonitorStub, ReceiverGuard::StackGuard guard, const AutoShapeVector *shapes) : ICGetProp_NativeDoesNotExist(stubCode, firstMonitorStub, guard, ProtoChainDepth) { @@ -11838,7 +11909,7 @@ ICGetPropNativeDoesNotExistCompiler::ICGetPropNativeDoesNotExistCompiler( } ICGetPropCallGetter::ICGetPropCallGetter(Kind kind, JitCode *stubCode, ICStub *firstMonitorStub, - ReceiverGuard::Token receiverGuard, JSObject *holder, + ReceiverGuard::StackGuard receiverGuard, JSObject *holder, Shape *holderShape, JSFunction *getter, uint32_t pcOffset) : ICMonitoredStub(kind, stubCode, firstMonitorStub), @@ -11867,7 +11938,7 @@ ICGetProp_CallScripted::Clone(ICStubSpace *space, ICStub *firstMonitorStub, ICGetProp_CallScripted &other) { return New(space, other.jitCode(), firstMonitorStub, - other.receiverGuard().token(), + other.receiverGuard(), other.holder_, other.holderShape_, other.getter_, other.pcOffset_); } @@ -11877,7 +11948,7 @@ ICGetProp_CallNative::Clone(ICStubSpace *space, ICStub *firstMonitorStub, ICGetProp_CallNative &other) { return New(space, other.jitCode(), firstMonitorStub, - other.receiverGuard().token(), other.holder_, + other.receiverGuard(), other.holder_, other.holderShape_, other.getter_, other.pcOffset_); } @@ -11949,7 +12020,7 @@ ICSetPropNativeAddCompiler::ICSetPropNativeAddCompiler(JSContext *cx, HandleObje MOZ_ASSERT(protoChainDepth_ <= ICSetProp_NativeAdd::MAX_PROTO_CHAIN_DEPTH); } -ICSetPropCallSetter::ICSetPropCallSetter(Kind kind, JitCode *stubCode, ReceiverGuard::Token guard, +ICSetPropCallSetter::ICSetPropCallSetter(Kind kind, JitCode *stubCode, ReceiverGuard::StackGuard guard, JSObject *holder, Shape *holderShape, JSFunction *setter, uint32_t pcOffset) : ICStub(kind, stubCode), @@ -11965,14 +12036,14 @@ ICSetPropCallSetter::ICSetPropCallSetter(Kind kind, JitCode *stubCode, ReceiverG /* static */ ICSetProp_CallScripted * ICSetProp_CallScripted::Clone(ICStubSpace *space, ICStub *, ICSetProp_CallScripted &other) { - return New(space, other.jitCode(), other.guard().token(), other.holder_, + return New(space, other.jitCode(), other.guard(), other.holder_, other.holderShape_, other.setter_, other.pcOffset_); } /* static */ ICSetProp_CallNative * ICSetProp_CallNative::Clone(ICStubSpace *space, ICStub *, ICSetProp_CallNative &other) { - return New(space, other.jitCode(), other.guard().token(), other.holder_, + return New(space, other.jitCode(), other.guard(), other.holder_, other.holderShape_, other.setter_, other.pcOffset_); } @@ -12082,8 +12153,8 @@ ICGetPropCallDOMProxyNativeStub::ICGetPropCallDOMProxyNativeStub(Kind kind, JitC Shape *holderShape, JSFunction *getter, uint32_t pcOffset) -: ICGetPropCallGetter(kind, stubCode, firstMonitorStub, ReceiverGuard::shapeToken(shape), - holder, holderShape, getter, pcOffset), + : ICGetPropCallGetter(kind, stubCode, firstMonitorStub, ReceiverGuard::StackGuard(shape), + holder, holderShape, getter, pcOffset), expandoShape_(expandoShape) { } diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index c7c7105b02e..f7c685c5812 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -3841,26 +3841,144 @@ class ICGetProp_StringLength : public ICStub }; }; +// Structure encapsulating the guarding that needs to be done on an object +// before it can be accessed or modified. +class ReceiverGuard +{ + // Group to guard on, or null. If the object is not unboxed and the IC does + // not require the object to have a specific group, this is null. + // Otherwise, this is the object's group. + HeapPtrObjectGroup group_; + + // Shape to guard on, or null. If the object is not unboxed then this is + // the object's shape. If the object is unboxed, then this is the shape of + // the object's expando, null if the object has no expando. + HeapPtrShape shape_; + + public: + struct StackGuard; + + struct RootedStackGuard + { + RootedObjectGroup group; + RootedShape shape; + + RootedStackGuard(JSContext *cx, const StackGuard &guard) + : group(cx, guard.group), shape(cx, guard.shape) + {} + }; + + struct StackGuard + { + ObjectGroup *group; + Shape *shape; + + MOZ_IMPLICIT StackGuard(const ReceiverGuard &guard) + : group(guard.group_), shape(guard.shape_) + {} + + MOZ_IMPLICIT StackGuard(const RootedStackGuard &guard) + : group(guard.group), shape(guard.shape) + {} + + explicit StackGuard(JSObject *obj) + : group(nullptr), shape(nullptr) + { + if (obj) { + shape = obj->maybeShape(); + if (!shape) { + group = obj->group(); + if (UnboxedExpandoObject *expando = obj->as().maybeExpando()) + shape = expando->lastProperty(); + } + } + } + + explicit StackGuard(Shape *shape) + : group(nullptr), shape(shape) + {} + + Shape *ownShape() const { + // Get a shape belonging to the object itself, rather than an unboxed expando. + if (!group || !group->maybeUnboxedLayout()) + return shape; + return nullptr; + } + }; + + explicit ReceiverGuard(const StackGuard &guard) + : group_(guard.group), shape_(guard.shape) + {} + + bool matches(const StackGuard &guard) { + return group_ == guard.group && shape_ == guard.shape; + } + + void update(const StackGuard &other) { + group_ = other.group; + shape_ = other.shape; + } + + void trace(JSTracer *trc); + + Shape *shape() const { + return shape_; + } + ObjectGroup *group() const { + return group_; + } + + Shape *ownShape() const { + return StackGuard(*this).ownShape(); + } + + static size_t offsetOfShape() { + return offsetof(ReceiverGuard, shape_); + } + static size_t offsetOfGroup() { + return offsetof(ReceiverGuard, group_); + } + + // Bits to munge into IC compiler keys when that IC has a ReceiverGuard. + // This uses at two bits for data. + static int32_t keyBits(JSObject *obj) { + if (obj->maybeShape()) + return 0; + return obj->as().maybeExpando() ? 1 : 2; + } +}; + // Base class for native GetProp stubs. class ICGetPropNativeStub : public ICMonitoredStub { + // Object shape/group. + ReceiverGuard receiverGuard_; + // Fixed or dynamic slot offset. uint32_t offset_; protected: ICGetPropNativeStub(ICStub::Kind kind, JitCode *stubCode, ICStub *firstMonitorStub, - uint32_t offset); + ReceiverGuard::StackGuard guard, uint32_t offset); public: + ReceiverGuard &receiverGuard() { + return receiverGuard_; + } uint32_t offset() const { return offset_; } + void notePreliminaryObject() { extra_ = 1; } bool hasPreliminaryObject() const { return extra_; } + + static size_t offsetOfReceiverGuard() { + return offsetof(ICGetPropNativeStub, receiverGuard_); + } static size_t offsetOfOffset() { return offsetof(ICGetPropNativeStub, offset_); } @@ -3871,103 +3989,16 @@ class ICGetProp_Native : public ICGetPropNativeStub { friend class ICStubSpace; - // Object shape (lastProperty). - HeapPtrShape shape_; - - ICGetProp_Native(JitCode *stubCode, ICStub *firstMonitorStub, Shape *shape, + ICGetProp_Native(JitCode *stubCode, ICStub *firstMonitorStub, ReceiverGuard::StackGuard guard, uint32_t offset) - : ICGetPropNativeStub(GetProp_Native, stubCode, firstMonitorStub, offset), - shape_(shape) + : ICGetPropNativeStub(GetProp_Native, stubCode, firstMonitorStub, guard, offset) {} public: - HeapPtrShape &shape() { - return shape_; - } - static size_t offsetOfShape() { - return offsetof(ICGetProp_Native, shape_); - } - static ICGetProp_Native *Clone(ICStubSpace *space, ICStub *firstMonitorStub, ICGetProp_Native &other); }; -// Structure encapsulating the guarding that needs to be done on an object -// which might be either native or unboxed. In the former case, only the -// object's shape needs to be guarded. In the latter case, only the object's -// group needs to be guarded. -class ReceiverGuard -{ - HeapPtrShape shape_; - HeapPtrObjectGroup group_; - - public: - typedef uintptr_t Token; - - static Token shapeToken(Shape *shape) { - return reinterpret_cast(shape) | 1; - } - - static Token groupToken(ObjectGroup *group) { - return reinterpret_cast(group); - } - - static Shape *tokenShape(Token token) { - if (token & 1) - return reinterpret_cast(token & ~1); - return nullptr; - } - - static ObjectGroup *tokenGroup(Token token) { - if (!(token & 1)) - return reinterpret_cast(token); - return nullptr; - } - - static Token objectToken(JSObject *obj) { - if (obj->is()) - return groupToken(obj->group()); - return shapeToken(obj->maybeShape()); - } - - explicit ReceiverGuard(Token token) - : shape_(tokenShape(token)), group_(tokenGroup(token)) - { - MOZ_ASSERT(shape_ || group_); - } - - void update(Token token) { - MOZ_ASSERT(!!shape_ == !!tokenShape(token)); - MOZ_ASSERT(!!group_ == !!tokenGroup(token)); - shape_ = tokenShape(token); - group_ = tokenGroup(token); - MOZ_ASSERT(shape_ || group_); - } - - void trace(JSTracer *trc); - - Token token() { - MOZ_ASSERT(!!shape_ != !!group_); - if (shape_) - return shapeToken(shape_); - return groupToken(group_); - } - - Shape *shape() const { - return shape_; - } - ObjectGroup *group() const { - return group_; - } - - static size_t offsetOfShape() { - return offsetof(ReceiverGuard, shape_); - } - static size_t offsetOfGroup() { - return offsetof(ReceiverGuard, group_); - } -}; - // Stub for accessing a property on the native prototype of a native or unboxed // object. Note that due to the shape teleporting optimization, we only have to // guard on the object's shape/group and the holder's shape. @@ -3976,15 +4007,12 @@ class ICGetProp_NativePrototype : public ICGetPropNativeStub friend class ICStubSpace; protected: - // Object shape/group. - ReceiverGuard guard_; - // Holder and its shape. HeapPtrObject holder_; HeapPtrShape holderShape_; ICGetProp_NativePrototype(JitCode *stubCode, ICStub *firstMonitorStub, - ReceiverGuard::Token guard, + ReceiverGuard::StackGuard guard, uint32_t offset, JSObject *holder, Shape *holderShape); public: @@ -3993,18 +4021,12 @@ class ICGetProp_NativePrototype : public ICGetPropNativeStub ICGetProp_NativePrototype &other); public: - ReceiverGuard &guard() { - return guard_; - } HeapPtrObject &holder() { return holder_; } HeapPtrShape &holderShape() { return holderShape_; } - static size_t offsetOfGuard() { - return offsetof(ICGetProp_NativePrototype, guard_); - } static size_t offsetOfHolder() { return offsetof(ICGetProp_NativePrototype, holder_); } @@ -4033,7 +4055,7 @@ class ICGetPropNativeCompiler : public ICStubCompiler (static_cast(isCallProp_) << 16) | (static_cast(isFixedSlot_) << 17) | (static_cast(inputDefinitelyObject_) << 18) | - (static_cast(obj_->isNative()) << 19); + (ReceiverGuard::keyBits(obj_) << 19); } public: @@ -4067,7 +4089,7 @@ class ICGetProp_NativeDoesNotExist : public ICMonitoredStub protected: ICGetProp_NativeDoesNotExist(JitCode *stubCode, ICStub *firstMonitorStub, - ReceiverGuard::Token guard, + ReceiverGuard::StackGuard guard, size_t protoChainDepth); public: @@ -4105,7 +4127,7 @@ class ICGetProp_NativeDoesNotExistImpl : public ICGetProp_NativeDoesNotExist mozilla::Array shapes_; ICGetProp_NativeDoesNotExistImpl(JitCode *stubCode, ICStub *firstMonitorStub, - ReceiverGuard::Token guard, + ReceiverGuard::StackGuard guard, const AutoShapeVector *shapes); public: @@ -4129,8 +4151,8 @@ class ICGetPropNativeDoesNotExistCompiler : public ICStubCompiler protected: virtual int32_t getKey() const { return static_cast(kind) | - (static_cast(obj_->isNative()) << 16) | - (static_cast(protoChainDepth_) << 17); + (ReceiverGuard::keyBits(obj_) << 16) | + (static_cast(protoChainDepth_) << 18); } bool generateStubCode(MacroAssembler &masm); @@ -4141,8 +4163,9 @@ class ICGetPropNativeDoesNotExistCompiler : public ICStubCompiler template ICStub *getStubSpecific(ICStubSpace *space, const AutoShapeVector *shapes) { + ReceiverGuard::StackGuard guard(obj_); return ICStub::New > - (space, getStubCode(), firstMonitorStub_, ReceiverGuard::objectToken(obj_), shapes); + (space, getStubCode(), firstMonitorStub_, guard, shapes); } ICStub *getStub(ICStubSpace *space); @@ -4299,7 +4322,7 @@ class ICGetPropCallGetter : public ICMonitoredStub uint32_t pcOffset_; ICGetPropCallGetter(Kind kind, JitCode *stubCode, ICStub *firstMonitorStub, - ReceiverGuard::Token receiverGuard, JSObject *holder, + ReceiverGuard::StackGuard receiverGuard, JSObject *holder, Shape *holderShape, JSFunction *getter, uint32_t pcOffset); public: @@ -4351,9 +4374,9 @@ class ICGetPropCallGetter : public ICMonitoredStub // ICGetProp_CallNative::Compiler::getKey adds more bits to our // return value, so be careful when making changes here. return static_cast(kind) | - (static_cast(receiver_->isNative()) << 16) | - (static_cast(!!outerClass_) << 17) | - (static_cast(receiver_ != holder_) << 18); + (ReceiverGuard::keyBits(receiver_) << 16) | + (static_cast(!!outerClass_) << 18) | + (static_cast(receiver_ != holder_) << 19); } public: @@ -4382,7 +4405,7 @@ class ICGetProp_CallScripted : public ICGetPropCallGetter protected: ICGetProp_CallScripted(JitCode *stubCode, ICStub *firstMonitorStub, - ReceiverGuard::Token receiverGuard, + ReceiverGuard::StackGuard receiverGuard, JSObject *holder, Shape *holderShape, JSFunction *getter, uint32_t pcOffset) : ICGetPropCallGetter(GetProp_CallScripted, stubCode, firstMonitorStub, @@ -4406,7 +4429,7 @@ class ICGetProp_CallScripted : public ICGetPropCallGetter {} ICStub *getStub(ICStubSpace *space) { - ReceiverGuard::Token guard = ReceiverGuard::objectToken(receiver_); + ReceiverGuard::StackGuard guard(receiver_); Shape *holderShape = holder_->as().lastProperty(); return ICStub::New(space, getStubCode(), firstMonitorStub_, guard, holder_, holderShape, getter_, @@ -4423,7 +4446,8 @@ class ICGetProp_CallNative : public ICGetPropCallGetter protected: ICGetProp_CallNative(JitCode *stubCode, ICStub *firstMonitorStub, - ReceiverGuard::Token receiverGuard, JSObject *holder, Shape *holderShape, + ReceiverGuard::StackGuard receiverGuard, + JSObject *holder, Shape *holderShape, JSFunction *getter, uint32_t pcOffset) : ICGetPropCallGetter(GetProp_CallNative, stubCode, firstMonitorStub, receiverGuard, holder, holderShape, getter, pcOffset) @@ -4441,8 +4465,8 @@ class ICGetProp_CallNative : public ICGetPropCallGetter virtual int32_t getKey() const { int32_t baseKey = ICGetPropCallGetter::Compiler::getKey(); - MOZ_ASSERT((baseKey >> 19) == 0); - return baseKey | (static_cast(inputDefinitelyObject_) << 19); + MOZ_ASSERT((baseKey >> 20) == 0); + return baseKey | (static_cast(inputDefinitelyObject_) << 20); } public: @@ -4456,7 +4480,7 @@ class ICGetProp_CallNative : public ICGetPropCallGetter {} ICStub *getStub(ICStubSpace *space) { - ReceiverGuard::Token guard = ReceiverGuard::objectToken(receiver_); + ReceiverGuard::StackGuard guard(receiver_); Shape *holderShape = holder_->as().lastProperty(); return ICStub::New(space, getStubCode(), firstMonitorStub_, guard, holder_, holderShape, @@ -5076,8 +5100,9 @@ class ICSetPropCallSetter : public ICStub // PC of call, for profiler uint32_t pcOffset_; - ICSetPropCallSetter(Kind kind, JitCode *stubCode, ReceiverGuard::Token guard, JSObject *holder, - Shape *holderShape, JSFunction *setter, uint32_t pcOffset); + ICSetPropCallSetter(Kind kind, JitCode *stubCode, ReceiverGuard::StackGuard guard, + JSObject *holder, Shape *holderShape, JSFunction *setter, + uint32_t pcOffset); public: ReceiverGuard &guard() { @@ -5118,7 +5143,7 @@ class ICSetPropCallSetter : public ICStub virtual int32_t getKey() const { return static_cast(kind) | - (static_cast(obj_->isNative()) << 16); + (ReceiverGuard::keyBits(obj_) << 16); } public: @@ -5141,7 +5166,7 @@ class ICSetProp_CallScripted : public ICSetPropCallSetter friend class ICStubSpace; protected: - ICSetProp_CallScripted(JitCode *stubCode, ReceiverGuard::Token guard, JSObject *holder, + ICSetProp_CallScripted(JitCode *stubCode, ReceiverGuard::StackGuard guard, JSObject *holder, Shape *holderShape, JSFunction *setter, uint32_t pcOffset) : ICSetPropCallSetter(SetProp_CallScripted, stubCode, guard, holder, holderShape, setter, pcOffset) @@ -5163,7 +5188,7 @@ class ICSetProp_CallScripted : public ICSetPropCallSetter {} ICStub *getStub(ICStubSpace *space) { - ReceiverGuard::Token guard = ReceiverGuard::objectToken(obj_); + ReceiverGuard::StackGuard guard(obj_); Shape *holderShape = holder_->as().lastProperty(); return ICStub::New(space, getStubCode(), guard, holder_, holderShape, setter_, pcOffset_); @@ -5177,7 +5202,7 @@ class ICSetProp_CallNative : public ICSetPropCallSetter friend class ICStubSpace; protected: - ICSetProp_CallNative(JitCode *stubCode, ReceiverGuard::Token guard, JSObject *holder, + ICSetProp_CallNative(JitCode *stubCode, ReceiverGuard::StackGuard guard, JSObject *holder, Shape *holderShape, JSFunction *setter, uint32_t pcOffset) : ICSetPropCallSetter(SetProp_CallNative, stubCode, guard, holder, holderShape, setter, pcOffset) @@ -5199,7 +5224,7 @@ class ICSetProp_CallNative : public ICSetPropCallSetter {} ICStub *getStub(ICStubSpace *space) { - ReceiverGuard::Token guard = ReceiverGuard::objectToken(obj_); + ReceiverGuard::StackGuard guard(obj_); Shape *holderShape = holder_->as().lastProperty(); return ICStub::New(space, getStubCode(), guard, holder_, holderShape, setter_, pcOffset_); diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp index 35f29df88f2..e55f966dbd0 100644 --- a/js/src/jit/BaselineInspector.cpp +++ b/js/src/jit/BaselineInspector.cpp @@ -116,14 +116,16 @@ BaselineInspector::maybeInfoForPropertyOp(jsbytecode *pc, Shape *shape = nullptr; ObjectGroup *group = nullptr; if (stub->isGetProp_Native()) { - shape = stub->toGetProp_Native()->shape(); + shape = stub->toGetProp_Native()->receiverGuard().ownShape(); } else if (stub->isSetProp_Native()) { shape = stub->toSetProp_Native()->shape(); } else if (stub->isGetProp_Unboxed()) { group = stub->toGetProp_Unboxed()->group(); } else if (stub->isSetProp_Unboxed()) { group = stub->toSetProp_Unboxed()->group(); - } else { + } + + if (!shape && !group) { nativeShapes.clear(); unboxedGroups.clear(); return true; @@ -589,12 +591,17 @@ GlobalShapeForGetPropFunction(ICStub *stub) static bool AddReceiver(BaselineInspector::ShapeVector &nativeShapes, BaselineInspector::ObjectGroupVector &unboxedGroups, - ReceiverGuard::Token receiver) + ReceiverGuard::StackGuard receiver) { - if (Shape *shape = ReceiverGuard::tokenShape(receiver)) + if (Shape *shape = receiver.ownShape()) return VectorAppendNoDuplicate(nativeShapes, shape); - ObjectGroup *group = ReceiverGuard::tokenGroup(receiver); - return VectorAppendNoDuplicate(unboxedGroups, group); + + // Only unboxed objects with no expandos are handled by the common + // getprop/setprop optimizations. + if (!receiver.shape) + return VectorAppendNoDuplicate(unboxedGroups, receiver.group); + + return false; } static bool @@ -605,13 +612,7 @@ AddReceiverForGetPropFunction(BaselineInspector::ShapeVector &nativeShapes, if (stub->isOwnGetter()) return true; - ReceiverGuard::Token token; - if (stub->isGetProp_CallScripted()) - token = stub->toGetProp_CallScripted()->receiverGuard().token(); - else - token = stub->toGetProp_CallNative()->receiverGuard().token(); - - return AddReceiver(nativeShapes, unboxedGroups, token); + return AddReceiver(nativeShapes, unboxedGroups, stub->receiverGuard()); } bool @@ -690,7 +691,7 @@ BaselineInspector::commonSetPropFunction(jsbytecode *pc, JSObject **holder, Shap for (ICStub *stub = entry.firstStub(); stub; stub = stub->next()) { if (stub->isSetProp_CallScripted() || stub->isSetProp_CallNative()) { ICSetPropCallSetter *nstub = static_cast(stub); - if (!AddReceiver(nativeShapes, unboxedGroups, nstub->guard().token())) + if (!AddReceiver(nativeShapes, unboxedGroups, nstub->guard())) return false; if (!*holder) { diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp index b0b2f2ad30e..6e8c1a16d46 100644 --- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -65,7 +65,8 @@ BaselineScript::BaselineScript(uint32_t prologueOffset, uint32_t epilogueOffset, traceLoggerScriptEvent_(), #endif postDebugPrologueOffset_(postDebugPrologueOffset), - flags_(0) + flags_(0), + maxInliningDepth_(UINT8_MAX) { } static const unsigned BASELINE_MAX_ARGS_LENGTH = 20000; diff --git a/js/src/jit/BaselineJIT.h b/js/src/jit/BaselineJIT.h index 171bef3efdd..f3a3b382c03 100644 --- a/js/src/jit/BaselineJIT.h +++ b/js/src/jit/BaselineJIT.h @@ -212,6 +212,13 @@ struct BaselineScript // instruction. uint32_t yieldEntriesOffset_; + // The max inlining depth where we can still inline all functions we inlined + // when we Ion-compiled this script. This starts as UINT8_MAX, since we have + // no data yet, and won't affect inlining heuristics in that case. The value + // is updated when we Ion-compile this script. See makeInliningDecision for + // more info. + uint8_t maxInliningDepth_; + public: // Do not call directly, use BaselineScript::New. This is public for cx->new_. BaselineScript(uint32_t prologueOffset, uint32_t epilogueOffset, @@ -424,6 +431,17 @@ struct BaselineScript MOZ_ASSERT(bytecodeTypeMapOffset_); return reinterpret_cast(reinterpret_cast(this) + bytecodeTypeMapOffset_); } + + uint8_t maxInliningDepth() const { + return maxInliningDepth_; + } + void setMaxInliningDepth(uint32_t depth) { + MOZ_ASSERT(depth <= UINT8_MAX); + maxInliningDepth_ = depth; + } + void resetMaxInliningDepth() { + maxInliningDepth_ = UINT8_MAX; + } }; static_assert(sizeof(BaselineScript) % sizeof(uintptr_t) == 0, "The data attached to the script must be aligned for fast JIT access."); diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 5c61d00352d..88378d89b0a 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -8694,19 +8694,22 @@ CodeGenerator::visitLoadUnboxedScalar(LLoadUnboxedScalar *lir) Register temp = lir->temp()->isBogusTemp() ? InvalidReg : ToRegister(lir->temp()); AnyRegister out = ToAnyRegister(lir->output()); - Scalar::Type readType = lir->mir()->readType(); - int width = Scalar::byteSize(lir->mir()->indexType()); + const MLoadUnboxedScalar *mir = lir->mir(); + + Scalar::Type readType = mir->readType(); + unsigned numElems = mir->numElems(); + + int width = Scalar::byteSize(mir->indexType()); + bool canonicalizeDouble = mir->canonicalizeDoubles(); Label fail; if (lir->index()->isConstant()) { - Address source(elements, ToInt32(lir->index()) * width + lir->mir()->offsetAdjustment()); - masm.loadFromTypedArray(readType, source, out, temp, &fail, - lir->mir()->canonicalizeDoubles()); + Address source(elements, ToInt32(lir->index()) * width + mir->offsetAdjustment()); + masm.loadFromTypedArray(readType, source, out, temp, &fail, canonicalizeDouble, numElems); } else { BaseIndex source(elements, ToRegister(lir->index()), ScaleFromElemWidth(width), - lir->mir()->offsetAdjustment()); - masm.loadFromTypedArray(readType, source, out, temp, &fail, - lir->mir()->canonicalizeDoubles()); + mir->offsetAdjustment()); + masm.loadFromTypedArray(readType, source, out, temp, &fail, canonicalizeDouble, numElems); } if (fail.used()) @@ -8756,13 +8759,14 @@ CodeGenerator::visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole *lir) template static inline void -StoreToTypedArray(MacroAssembler &masm, Scalar::Type writeType, const LAllocation *value, const T &dest) +StoreToTypedArray(MacroAssembler &masm, Scalar::Type writeType, const LAllocation *value, + const T &dest, unsigned numElems = 0) { if (Scalar::isSimdType(writeType) || writeType == Scalar::Float32 || writeType == Scalar::Float64) { - masm.storeToTypedFloatArray(writeType, ToFloatRegister(value), dest); + masm.storeToTypedFloatArray(writeType, ToFloatRegister(value), dest, numElems); } else { if (value->isConstant()) masm.storeToTypedIntArray(writeType, Imm32(ToInt32(value)), dest); @@ -8777,16 +8781,20 @@ CodeGenerator::visitStoreUnboxedScalar(LStoreUnboxedScalar *lir) Register elements = ToRegister(lir->elements()); const LAllocation *value = lir->value(); - Scalar::Type writeType = lir->mir()->writeType(); - int width = Scalar::byteSize(lir->mir()->indexType()); + const MStoreUnboxedScalar *mir = lir->mir(); + + Scalar::Type writeType = mir->writeType(); + unsigned numElems = mir->numElems(); + + int width = Scalar::byteSize(mir->indexType()); if (lir->index()->isConstant()) { - Address dest(elements, ToInt32(lir->index()) * width + lir->mir()->offsetAdjustment()); - StoreToTypedArray(masm, writeType, value, dest); + Address dest(elements, ToInt32(lir->index()) * width + mir->offsetAdjustment()); + StoreToTypedArray(masm, writeType, value, dest, numElems); } else { BaseIndex dest(elements, ToRegister(lir->index()), ScaleFromElemWidth(width), - lir->mir()->offsetAdjustment()); - StoreToTypedArray(masm, writeType, value, dest); + mir->offsetAdjustment()); + StoreToTypedArray(masm, writeType, value, dest, numElems); } } @@ -9721,21 +9729,19 @@ CodeGenerator::visitRecompileCheck(LRecompileCheck *ins) masm.bind(&done); } -typedef bool (*ThrowUninitializedLexicalFn)(JSContext *); -static const VMFunction ThrowUninitializedLexicalInfo = - FunctionInfo(ThrowUninitializedLexical); - void CodeGenerator::visitLexicalCheck(LLexicalCheck *ins) { - OutOfLineCode *ool = oolCallVM(ThrowUninitializedLexicalInfo, ins, (ArgList()), - StoreNothing()); ValueOperand inputValue = ToValue(ins, LLexicalCheck::Input); - masm.branchTestMagicValue(Assembler::Equal, inputValue, JS_UNINITIALIZED_LEXICAL, - ool->entry()); - masm.bind(ool->rejoin()); + Label bail; + masm.branchTestMagicValue(Assembler::Equal, inputValue, JS_UNINITIALIZED_LEXICAL, &bail); + bailoutFrom(&bail, ins->snapshot()); } +typedef bool (*ThrowUninitializedLexicalFn)(JSContext *); +static const VMFunction ThrowUninitializedLexicalInfo = + FunctionInfo(ThrowUninitializedLexical); + void CodeGenerator::visitThrowUninitializedLexical(LThrowUninitializedLexical *ins) { diff --git a/js/src/jit/CompileWrappers.cpp b/js/src/jit/CompileWrappers.cpp index 630022144e1..991bb22be65 100644 --- a/js/src/jit/CompileWrappers.cpp +++ b/js/src/jit/CompileWrappers.cpp @@ -276,7 +276,8 @@ CompileCompartment::setSingletonsAsValues() JitCompileOptions::JitCompileOptions() : cloneSingletons_(false), - spsSlowAssertionsEnabled_(false) + spsSlowAssertionsEnabled_(false), + offThreadCompilationAvailable_(false) { } @@ -286,4 +287,5 @@ JitCompileOptions::JitCompileOptions(JSContext *cx) cloneSingletons_ = options.cloneSingletons(); spsSlowAssertionsEnabled_ = cx->runtime()->spsProfiler.enabled() && cx->runtime()->spsProfiler.slowAssertionsEnabled(); + offThreadCompilationAvailable_ = OffThreadCompilationAvailable(cx); } diff --git a/js/src/jit/CompileWrappers.h b/js/src/jit/CompileWrappers.h index f06b45c6714..2d5ee812e2a 100644 --- a/js/src/jit/CompileWrappers.h +++ b/js/src/jit/CompileWrappers.h @@ -135,9 +135,14 @@ class JitCompileOptions return spsSlowAssertionsEnabled_; } + bool offThreadCompilationAvailable() const { + return offThreadCompilationAvailable_; + } + private: bool cloneSingletons_; bool spsSlowAssertionsEnabled_; + bool offThreadCompilationAvailable_; }; } // namespace jit diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index 438a4d3d1b9..e1971b99c61 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -1773,19 +1773,6 @@ MarkOffThreadNurseryObjects::mark(JSTracer *trc) } } -static inline bool -OffThreadCompilationAvailable(JSContext *cx) -{ - // Even if off thread compilation is enabled, compilation must still occur - // on the main thread in some cases. - // - // Require cpuCount > 1 so that Ion compilation jobs and main-thread - // execution are not competing for the same resources. - return cx->runtime()->canUseOffthreadIonCompilation() - && HelperThreadState().cpuCount > 1 - && CanUseExtraThreads(); -} - static void TrackAllProperties(JSContext *cx, JSObject *obj) { @@ -1967,7 +1954,7 @@ IonCompile(JSContext *cx, JSScript *script, } // If possible, compile the script off thread. - if (OffThreadCompilationAvailable(cx)) { + if (options.offThreadCompilationAvailable()) { if (!recompile) builderScript->setIonScript(cx, ION_COMPILING_SCRIPT); @@ -2170,6 +2157,19 @@ Compile(JSContext *cx, HandleScript script, BaselineFrame *osrFrame, jsbytecode } // namespace jit } // namespace js +bool +jit::OffThreadCompilationAvailable(JSContext *cx) +{ + // Even if off thread compilation is enabled, compilation must still occur + // on the main thread in some cases. + // + // Require cpuCount > 1 so that Ion compilation jobs and main-thread + // execution are not competing for the same resources. + return cx->runtime()->canUseOffthreadIonCompilation() + && HelperThreadState().cpuCount > 1 + && CanUseExtraThreads(); +} + // Decide if a transition from interpreter execution to Ion code should occur. // May compile or recompile the target JSScript. MethodStatus diff --git a/js/src/jit/Ion.h b/js/src/jit/Ion.h index 749907ecd09..b7d562d1353 100644 --- a/js/src/jit/Ion.h +++ b/js/src/jit/Ion.h @@ -190,6 +190,8 @@ NumLocalsAndArgs(JSScript *script) return num; } +bool OffThreadCompilationAvailable(JSContext *cx); + void ForbidCompilation(JSContext *cx, JSScript *script); void PurgeCaches(JSScript *script); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 0d935deb5d5..8ea07451759 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -146,9 +146,11 @@ IonBuilder::IonBuilder(JSContext *analysisContext, CompileCompartment *comp, loopHeaders_(*temp), inspector(inspector), inliningDepth_(inliningDepth), + inlinedBytecodeLength_(0), numLoopRestarts_(0), failedBoundsCheck_(info->script()->failedBoundsCheck()), failedShapeGuard_(info->script()->failedShapeGuard()), + failedLexicalCheck_(info->script()->failedLexicalCheck()), nonStringIteration_(false), lazyArguments_(nullptr), inlineCallInfo_(nullptr), @@ -639,6 +641,10 @@ IonBuilder::analyzeNewLoopTypes(MBasicBlock *entry, jsbytecode *start, jsbytecod case JSOP_UNDEFINED: type = MIRType_Undefined; break; + case JSOP_GIMPLICITTHIS: + if (!script()->hasPollutedGlobalScope()) + type = MIRType_Undefined; + break; case JSOP_NULL: type = MIRType_Null; break; @@ -771,6 +777,9 @@ IonBuilder::build() if (!init()) return false; + if (script()->hasBaselineScript()) + script()->baselineScript()->resetMaxInliningDepth(); + if (!setCurrentAndSpecializePhis(newBlock(pc))) return false; if (!current) @@ -954,6 +963,9 @@ IonBuilder::buildInline(IonBuilder *callerBuilder, MResumePoint *callerResumePoi if (callerBuilder->failedShapeGuard_) failedShapeGuard_ = true; + if (callerBuilder->failedLexicalCheck_) + failedLexicalCheck_ = true; + // Generate single entrance block. if (!setCurrentAndSpecializePhis(newBlock(pc))) return false; @@ -1579,6 +1591,7 @@ IonBuilder::inspectOpcode(JSOp op) return jsop_label(); case JSOP_UNDEFINED: + // If this ever changes, change what JSOP_GIMPLICITTHIS does too. return pushConstant(UndefinedValue()); case JSOP_IFEQ: @@ -1972,17 +1985,26 @@ IonBuilder::inspectOpcode(JSOp op) case JSOP_DEBUGGER: return jsop_debugger(); + case JSOP_GIMPLICITTHIS: + if (!script()->hasPollutedGlobalScope()) + return pushConstant(UndefinedValue()); + + // Just fall through to the unsupported bytecode case. + break; + default: - // Track a simpler message, since the actionable abort message is a - // static string, and the internal opcode name isn't an actionable - // thing anyways. - trackActionableAbort("Unsupported bytecode"); -#ifdef DEBUG - return abort("Unsupported opcode: %s", js_CodeName[op]); -#else - return abort("Unsupported opcode: %d", op); -#endif + break; } + + // Track a simpler message, since the actionable abort message is a + // static string, and the internal opcode name isn't an actionable + // thing anyways. + trackActionableAbort("Unsupported bytecode"); +#ifdef DEBUG + return abort("Unsupported opcode: %s", js_CodeName[op]); +#else + return abort("Unsupported opcode: %d", op); +#endif } // Given that the current control flow structure has ended forcefully, @@ -4826,59 +4848,10 @@ IonBuilder::makeInliningDecision(JSObject *targetArg, CallInfo &callInfo) // Heuristics! JSScript *targetScript = target->nonLazyScript(); - // Cap the inlining depth. - if (js_JitOptions.isSmallFunction(targetScript)) { - if (inliningDepth_ >= optimizationInfo().smallFunctionMaxInlineDepth()) { - trackOptimizationOutcome(TrackedOutcome::CantInlineExceededDepth); - return DontInline(targetScript, "Vetoed: exceeding allowed inline depth"); - } - } else { - if (inliningDepth_ >= optimizationInfo().maxInlineDepth()) { - trackOptimizationOutcome(TrackedOutcome::CantInlineExceededDepth); - return DontInline(targetScript, "Vetoed: exceeding allowed inline depth"); - } - - if (targetScript->hasLoops()) { - // Currently, we are not inlining function which have loops because - // the cost inherent to inlining the function overcome the cost - // calling it. The reason is not yet clear to everybody, and we - // hope that we might be able to remove this restriction in the - // future. - // - // In the mean time, if we have opportunities to optimize the - // loop better, then we should try it. Such opportunity might be - // suggested by: - // - // - Constant as argument. Inlining a function called with a - // constant, might help GVN, as well as UCE, and potentially - // improve bound check removal. - // - // - Inner function as argument. Inlining a function called - // with an inner function might help scalar replacement at - // removing the scope chain, and thus using registers within - // the loop instead of writting everything back to memory. - bool hasOpportunities = false; - for (size_t i = 0, e = callInfo.argv().length(); !hasOpportunities && i < e; i++) { - MDefinition *arg = callInfo.argv()[i]; - hasOpportunities = arg->isLambda() || arg->isConstantValue(); - } - - if (!hasOpportunities) { - trackOptimizationOutcome(TrackedOutcome::CantInlineBigLoop); - return DontInline(targetScript, "Vetoed: big function that contains a loop"); - } - } - - // Caller must not be excessively large. - if (script()->length() >= optimizationInfo().inliningMaxCallerBytecodeLength()) { - trackOptimizationOutcome(TrackedOutcome::CantInlineBigCaller); - return DontInline(targetScript, "Vetoed: caller excessively large"); - } - } - // Callee must not be excessively large. // This heuristic also applies to the callsite as a whole. - if (targetScript->length() > optimizationInfo().inlineMaxTotalBytecodeLength()) { + bool offThread = options.offThreadCompilationAvailable(); + if (targetScript->length() > optimizationInfo().inlineMaxBytecodePerCallSite(offThread)) { trackOptimizationOutcome(TrackedOutcome::CantInlineBigCallee); return DontInline(targetScript, "Vetoed: callee excessively large"); } @@ -4896,10 +4869,81 @@ IonBuilder::makeInliningDecision(JSObject *targetArg, CallInfo &callInfo) return InliningDecision_WarmUpCountTooLow; } + IonBuilder *outerBuilder = outermostBuilder(); + + // Cap the total bytecode length we inline under a single script, to avoid + // excessive inlining in pathological cases. + size_t totalBytecodeLength = outerBuilder->inlinedBytecodeLength_ + targetScript->length(); + if (totalBytecodeLength > optimizationInfo().inlineMaxTotalBytecodeLength()) { + trackOptimizationOutcome(TrackedOutcome::CantInlineExceededTotalBytecodeLength); + return DontInline(targetScript, "Vetoed: exceeding max total bytecode length"); + } + + // Cap the inlining depth. + + uint32_t maxInlineDepth; + if (js_JitOptions.isSmallFunction(targetScript)) { + maxInlineDepth = optimizationInfo().smallFunctionMaxInlineDepth(); + } else { + maxInlineDepth = optimizationInfo().maxInlineDepth(); + + // Caller must not be excessively large. + if (script()->length() >= optimizationInfo().inliningMaxCallerBytecodeLength()) { + trackOptimizationOutcome(TrackedOutcome::CantInlineBigCaller); + return DontInline(targetScript, "Vetoed: caller excessively large"); + } + } + + BaselineScript *outerBaseline = outermostBuilder()->script()->baselineScript(); + if (inliningDepth_ >= maxInlineDepth) { + // We hit the depth limit and won't inline this function. Give the + // outermost script a max inlining depth of 0, so that it won't be + // inlined in other scripts. This heuristic is currently only used + // when we're inlining scripts with loops, see the comment below. + outerBaseline->setMaxInliningDepth(0); + + trackOptimizationOutcome(TrackedOutcome::CantInlineExceededDepth); + return DontInline(targetScript, "Vetoed: exceeding allowed inline depth"); + } + + // Inlining functions with loops can be complicated. For instance, if we're + // close to the inlining depth limit and we inline the function f below, we + // can no longer inline the call to g: + // + // function f() { + // while (cond) { + // g(); + // } + // } + // + // If the loop has many iterations, it's more efficient to call f and inline + // g in f. + // + // To avoid this problem, we record a separate max inlining depth for each + // script, indicating at which depth we won't be able to inline all functions + // we inlined this time. This solves the issue above, because we will only + // inline f if it means we can also inline g. + if (targetScript->hasLoops() && + inliningDepth_ >= targetScript->baselineScript()->maxInliningDepth()) + { + trackOptimizationOutcome(TrackedOutcome::CantInlineExceededDepth); + return DontInline(targetScript, "Vetoed: exceeding allowed script inline depth"); + } + + // Update the max depth at which we can inline the outer script. + MOZ_ASSERT(maxInlineDepth > inliningDepth_); + uint32_t scriptInlineDepth = maxInlineDepth - inliningDepth_ - 1; + if (scriptInlineDepth < outerBaseline->maxInliningDepth()) + outerBaseline->setMaxInliningDepth(scriptInlineDepth); + + // End of heuristics, we will inline this function. + // TI calls ObjectStateChange to trigger invalidation of the caller. TypeSet::ObjectKey *targetKey = TypeSet::ObjectKey::get(target); targetKey->watchStateChangeForInlinedCall(constraints()); + outerBuilder->inlinedBytecodeLength_ += targetScript->length(); + return InliningDecision_Inline; } @@ -4945,7 +4989,8 @@ IonBuilder::selectInliningTargets(const ObjectVector &targets, CallInfo &callInf // Enforce a maximum inlined bytecode limit at the callsite. if (inlineable && target->as().isInterpreted()) { totalSize += target->as().nonLazyScript()->length(); - if (totalSize > optimizationInfo().inlineMaxTotalBytecodeLength()) + bool offThread = options.offThreadCompilationAvailable(); + if (totalSize > optimizationInfo().inlineMaxBytecodePerCallSite(offThread)) inlineable = false; } } else { @@ -12761,17 +12806,24 @@ IonBuilder::addLexicalCheck(MDefinition *input) { MOZ_ASSERT(JSOp(*pc) == JSOP_CHECKLEXICAL || JSOp(*pc) == JSOP_CHECKALIASEDLEXICAL); - // If we're guaranteed to not be JS_UNINITIALIZED_LEXICAL, no need to check. MInstruction *lexicalCheck; - if (input->type() == MIRType_MagicUninitializedLexical) - lexicalCheck = MThrowUninitializedLexical::New(alloc()); - else if (input->type() == MIRType_Value) - lexicalCheck = MLexicalCheck::New(alloc(), input); - else - return input; - current->add(lexicalCheck); - if (!resumeAfter(lexicalCheck)) - return nullptr; - return lexicalCheck->isLexicalCheck() ? lexicalCheck : constant(UndefinedValue()); + // If we're guaranteed to not be JS_UNINITIALIZED_LEXICAL, no need to check. + if (input->type() == MIRType_MagicUninitializedLexical) { + lexicalCheck = MThrowUninitializedLexical::New(alloc()); + current->add(lexicalCheck); + if (!resumeAfter(lexicalCheck)) + return nullptr; + return constant(UndefinedValue()); + } + + if (input->type() == MIRType_Value) { + lexicalCheck = MLexicalCheck::New(alloc(), input); + current->add(lexicalCheck); + if (failedLexicalCheck_) + lexicalCheck->setNotMovableUnchecked(); + return lexicalCheck; + } + + return input; } diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index d7d0601f4be..4c8e0c82ccd 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -832,7 +832,8 @@ class IonBuilder InliningStatus inlineSimdWith(CallInfo &callInfo, JSNative native, SimdLane lane, SimdTypeDescr::Type type); InliningStatus inlineSimdSplat(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type); - InliningStatus inlineSimdSwizzle(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type); + InliningStatus inlineSimdShuffle(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type, + unsigned numVectors, unsigned numLanes); InliningStatus inlineSimdCheck(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type); InliningStatus inlineSimdConvert(CallInfo &callInfo, JSNative native, bool isCast, SimdTypeDescr::Type from, SimdTypeDescr::Type to); @@ -841,8 +842,10 @@ class IonBuilder bool prepareForSimdLoadStore(CallInfo &callInfo, Scalar::Type simdType, MInstruction **elements, MDefinition **index, Scalar::Type *arrayType); - InliningStatus inlineSimdLoad(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type); - InliningStatus inlineSimdStore(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type); + InliningStatus inlineSimdLoad(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type, + unsigned numElems); + InliningStatus inlineSimdStore(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type, + unsigned numElems); // Utility intrinsics. InliningStatus inlineIsCallable(CallInfo &callInfo); @@ -1094,6 +1097,10 @@ class IonBuilder size_t inliningDepth_; + // Total bytecode length of all inlined scripts. Only tracked for the + // outermost builder. + size_t inlinedBytecodeLength_; + // Cutoff to disable compilation if excessive time is spent reanalyzing // loop bodies to compute a fixpoint of the types for loop variables. static const size_t MAX_LOOP_RESTARTS = 40; @@ -1107,6 +1114,10 @@ class IonBuilder // an outer script. bool failedShapeGuard_; + // True if script->failedLexicalCheck_ is set for the current script or + // an outer script. + bool failedLexicalCheck_; + // Has an iterator other than 'for in'. bool nonStringIteration_; diff --git a/js/src/jit/IonOptimizationLevels.cpp b/js/src/jit/IonOptimizationLevels.cpp index ef89adde456..1334b806663 100644 --- a/js/src/jit/IonOptimizationLevels.cpp +++ b/js/src/jit/IonOptimizationLevels.cpp @@ -37,7 +37,9 @@ OptimizationInfo::initNormalOptimizationInfo() sink_ = true; registerAllocator_ = RegisterAllocator_Backtracking; - inlineMaxTotalBytecodeLength_ = 1000; + inlineMaxBytecodePerCallSiteMainThread_ = 500; + inlineMaxBytecodePerCallSiteOffThread_ = 1000; + inlineMaxTotalBytecodeLength_ = 80000; inliningMaxCallerBytecodeLength_ = 10000; maxInlineDepth_ = 3; scalarReplacement_ = true; diff --git a/js/src/jit/IonOptimizationLevels.h b/js/src/jit/IonOptimizationLevels.h index 8688f276ddd..d1eda68488e 100644 --- a/js/src/jit/IonOptimizationLevels.h +++ b/js/src/jit/IonOptimizationLevels.h @@ -88,7 +88,13 @@ class OptimizationInfo // Describes which register allocator to use. IonRegisterAllocator registerAllocator_; - // The maximum total bytecode size of an inline call site. + // The maximum total bytecode size of an inline call site. We use a lower + // value if off-thread compilation is not available, to avoid stalling the + // main thread. + uint32_t inlineMaxBytecodePerCallSiteOffThread_; + uint32_t inlineMaxBytecodePerCallSiteMainThread_; + + // The maximum bytecode length we'll inline in a single compilation. uint32_t inlineMaxTotalBytecodeLength_; // The maximum bytecode length the caller may have, @@ -209,12 +215,18 @@ class OptimizationInfo return maxInlineDepth_; } + uint32_t inlineMaxBytecodePerCallSite(bool offThread) const { + return (offThread || !js_JitOptions.limitScriptSize) + ? inlineMaxBytecodePerCallSiteOffThread_ + : inlineMaxBytecodePerCallSiteMainThread_; + } + uint32_t inlineMaxTotalBytecodeLength() const { return inlineMaxTotalBytecodeLength_; } uint32_t inliningMaxCallerBytecodeLength() const { - return inlineMaxTotalBytecodeLength_; + return inliningMaxCallerBytecodeLength_; } uint32_t inliningWarmUpThreshold() const { diff --git a/js/src/jit/IonTypes.h b/js/src/jit/IonTypes.h index 41967c6e25a..b0f40003606 100644 --- a/js/src/jit/IonTypes.h +++ b/js/src/jit/IonTypes.h @@ -147,6 +147,9 @@ enum BailoutKind // by the baseline IC.) Bailout_ShapeGuard, + // When we're trying to use an uninitialized lexical. + Bailout_UninitializedLexical, + // A bailout to baseline from Ion on exception to handle Debugger hooks. Bailout_IonExceptionDebugMode, }; @@ -224,6 +227,8 @@ BailoutKindString(BailoutKind kind) return "Bailout_Neutered"; case Bailout_ShapeGuard: return "Bailout_ShapeGuard"; + case Bailout_UninitializedLexical: + return "Bailout_UninitializedLexical"; case Bailout_IonExceptionDebugMode: return "Bailout_IonExceptionDebugMode"; default: diff --git a/js/src/jit/JitOptions.cpp b/js/src/jit/JitOptions.cpp index 6d91f4d1bbf..16d347437b4 100644 --- a/js/src/jit/JitOptions.cpp +++ b/js/src/jit/JitOptions.cpp @@ -160,10 +160,6 @@ JitOptions::JitOptions() SET_DEFAULT(osrPcMismatchesBeforeRecompile, 6000); // The bytecode length limit for small function. - // - // The default for this was arrived at empirically via benchmarking. - // We may want to tune it further after other optimizations have gone - // in. SET_DEFAULT(smallFunctionMaxBytecodeLength_, 100); } diff --git a/js/src/jit/JitcodeMap.cpp b/js/src/jit/JitcodeMap.cpp index 5d56d8c9591..85b7f3f87e1 100644 --- a/js/src/jit/JitcodeMap.cpp +++ b/js/src/jit/JitcodeMap.cpp @@ -447,11 +447,11 @@ JitcodeGlobalTable::lookupForSampler(void *ptr, JitcodeGlobalEntry *result, JSRu } #ifdef DEBUG - // JitcodeGlobalEntries are marked during the beginning of the sweep phase - // (PHASE_SWEEP_MARK_JITCODE_GLOBAL_TABLE). A read barrier is not needed, - // as any JS frames sampled during the sweep phase of the GC must be on - // stack, and on-stack frames must already be marked at the beginning of - // the sweep phase. This assumption is verified below. + // JitcodeGlobalEntries are marked during the beginning of the sweep + // phase. A read barrier is not needed, as any JS frames sampled during + // the sweep phase of the GC must be on stack, and on-stack frames must + // already be marked at the beginning of the sweep phase. This assumption + // is verified below. if (rt->isHeapBusy() && rt->gc.stats.currentPhase() >= gcstats::PHASE_SWEEP && rt->gc.stats.currentPhase() <= gcstats::PHASE_GC_END) @@ -798,7 +798,7 @@ JitcodeGlobalTable::sweep(JSRuntime *rt) bool JitcodeGlobalEntry::BaseEntry::markJitcodeIfUnmarked(JSTracer *trc) { - if (!isJitcodeMarkedFromAnyThread()) { + if (!IsJitCodeMarkedFromAnyThread(&jitcode_)) { MarkJitCodeUnbarriered(trc, &jitcode_, "jitcodglobaltable-baseentry-jitcode"); return true; } @@ -808,9 +808,8 @@ JitcodeGlobalEntry::BaseEntry::markJitcodeIfUnmarked(JSTracer *trc) bool JitcodeGlobalEntry::BaseEntry::isJitcodeMarkedFromAnyThread() { - if (jitcode_->asTenured().arenaHeader()->allocatedDuringIncremental) - return false; - return IsJitCodeMarkedFromAnyThread(&jitcode_); + return IsJitCodeMarkedFromAnyThread(&jitcode_) || + jitcode_->arenaHeader()->allocatedDuringIncremental; } bool @@ -822,7 +821,7 @@ JitcodeGlobalEntry::BaseEntry::isJitcodeAboutToBeFinalized() bool JitcodeGlobalEntry::BaselineEntry::markIfUnmarked(JSTracer *trc) { - if (!isMarkedFromAnyThread()) { + if (!IsScriptMarkedFromAnyThread(&script_)) { MarkScriptUnbarriered(trc, &script_, "jitcodeglobaltable-baselineentry-script"); return true; } @@ -838,7 +837,8 @@ JitcodeGlobalEntry::BaselineEntry::sweep() bool JitcodeGlobalEntry::BaselineEntry::isMarkedFromAnyThread() { - return IsScriptMarkedFromAnyThread(&script_); + return IsScriptMarkedFromAnyThread(&script_) || + script_->arenaHeader()->allocatedDuringIncremental; } bool @@ -904,8 +904,11 @@ bool JitcodeGlobalEntry::IonEntry::isMarkedFromAnyThread() { for (unsigned i = 0; i < numScripts(); i++) { - if (!IsScriptMarkedFromAnyThread(&sizedScriptList()->pairs[i].script)) + if (!IsScriptMarkedFromAnyThread(&sizedScriptList()->pairs[i].script) && + !sizedScriptList()->pairs[i].script->arenaHeader()->allocatedDuringIncremental) + { return false; + } } if (!optsAllTypes_) @@ -914,8 +917,11 @@ JitcodeGlobalEntry::IonEntry::isMarkedFromAnyThread() for (IonTrackedTypeWithAddendum *iter = optsAllTypes_->begin(); iter != optsAllTypes_->end(); iter++) { - if (!TypeSet::IsTypeMarkedFromAnyThread(&iter->type)) + if (!TypeSet::IsTypeMarkedFromAnyThread(&iter->type) && + !TypeSet::IsTypeAllocatedDuringIncremental(iter->type)) + { return false; + } } return true; @@ -1502,3 +1508,18 @@ JitcodeIonTable::WriteIonTable(CompactBufferWriter &writer, } // namespace jit } // namespace js + + +JS_PUBLIC_API(JS::ProfilingFrameIterator::FrameKind) +JS::GetProfilingFrameKindFromNativeAddr(JSRuntime *rt, void *addr) +{ + JitcodeGlobalTable *table = rt->jitRuntime()->getJitcodeGlobalTable(); + JitcodeGlobalEntry entry; + table->lookupInfallible(addr, &entry, rt); + MOZ_ASSERT(entry.isIon() || entry.isIonCache() || entry.isBaseline()); + + if (entry.isBaseline()) + return JS::ProfilingFrameIterator::Frame_Baseline; + + return JS::ProfilingFrameIterator::Frame_Ion; +} diff --git a/js/src/jit/JitcodeMap.h b/js/src/jit/JitcodeMap.h index b398f12b4c0..d0a473168b6 100644 --- a/js/src/jit/JitcodeMap.h +++ b/js/src/jit/JitcodeMap.h @@ -356,7 +356,7 @@ class JitcodeGlobalEntry return optsAllTypes_; } - mozilla::Maybe trackedOptimizationIndexAtAddr(void *ptr); + mozilla::Maybe trackedOptimizationIndexAtAddr(void *ptr, uint32_t *entryOffsetOut); bool markIfUnmarked(JSTracer *trc); void sweep(); @@ -785,10 +785,10 @@ class JitcodeGlobalEntry return false; } - mozilla::Maybe trackedOptimizationIndexAtAddr(void *addr) { + mozilla::Maybe trackedOptimizationIndexAtAddr(void *addr, uint32_t *entryOffsetOut) { switch (kind()) { case Ion: - return ionEntry().trackedOptimizationIndexAtAddr(addr); + return ionEntry().trackedOptimizationIndexAtAddr(addr, entryOffsetOut); case Baseline: case IonCache: case Dummy: diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h index 503802b1e19..7317a0d947d 100644 --- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -374,46 +374,43 @@ class LSimdSwizzleF : public LSimdSwizzleBase {} }; -class LSimdGeneralSwizzleBase : public LInstructionHelper<1, 5, 1> +class LSimdGeneralShuffleBase : public LVariadicInstruction<1, 1> { public: - LSimdGeneralSwizzleBase(const LAllocation &base, const LAllocation lanes[4], - const LDefinition &temp) - { - setOperand(0, base); - for (size_t i = 0; i < 4; i++) - setOperand(1 + i, lanes[i]); + explicit LSimdGeneralShuffleBase(const LDefinition &temp) { setTemp(0, temp); } - - const LAllocation *base() { - return getOperand(0); + const LAllocation *vector(unsigned i) { + MOZ_ASSERT(i < mir()->numVectors()); + return getOperand(i); } - const LAllocation *lane(size_t i) { - return getOperand(1 + i); + const LAllocation *lane(unsigned i) { + MOZ_ASSERT(i < mir()->numLanes()); + return getOperand(mir()->numVectors() + i); } const LDefinition *temp() { return getTemp(0); } + MSimdGeneralShuffle *mir() const { + return mir_->toSimdGeneralShuffle(); + } }; -class LSimdGeneralSwizzleI : public LSimdGeneralSwizzleBase +class LSimdGeneralShuffleI : public LSimdGeneralShuffleBase { public: - LIR_HEADER(SimdGeneralSwizzleI); - LSimdGeneralSwizzleI(const LAllocation &base, const LAllocation lanes[4], - const LDefinition &temp) - : LSimdGeneralSwizzleBase(base, lanes, temp) + LIR_HEADER(SimdGeneralShuffleI); + explicit LSimdGeneralShuffleI(const LDefinition &temp) + : LSimdGeneralShuffleBase(temp) {} }; -class LSimdGeneralSwizzleF : public LSimdGeneralSwizzleBase +class LSimdGeneralShuffleF : public LSimdGeneralShuffleBase { public: - LIR_HEADER(SimdGeneralSwizzleF); - LSimdGeneralSwizzleF(const LAllocation &base, const LAllocation lanes[4], - const LDefinition &temp) - : LSimdGeneralSwizzleBase(base, lanes, temp) + LIR_HEADER(SimdGeneralShuffleF); + explicit LSimdGeneralShuffleF(const LDefinition &temp) + : LSimdGeneralShuffleBase(temp) {} }; diff --git a/js/src/jit/LIR.h b/js/src/jit/LIR.h index 48647ad0eb8..ae02d9b593a 100644 --- a/js/src/jit/LIR.h +++ b/js/src/jit/LIR.h @@ -13,6 +13,7 @@ #include "mozilla/Array.h" #include "jit/Bailouts.h" +#include "jit/FixedList.h" #include "jit/InlineList.h" #include "jit/JitAllocPolicy.h" #include "jit/LOpcodes.h" @@ -1003,62 +1004,91 @@ class LBlock void dump(); }; +namespace details { + template + class LInstructionFixedDefsTempsHelper : public LInstruction + { + mozilla::Array defs_; + mozilla::Array temps_; + + public: + size_t numDefs() const MOZ_FINAL MOZ_OVERRIDE { + return Defs; + } + LDefinition *getDef(size_t index) MOZ_FINAL MOZ_OVERRIDE { + return &defs_[index]; + } + size_t numTemps() const MOZ_FINAL MOZ_OVERRIDE { + return Temps; + } + LDefinition *getTemp(size_t index) MOZ_FINAL MOZ_OVERRIDE { + return &temps_[index]; + } + + void setDef(size_t index, const LDefinition &def) MOZ_FINAL MOZ_OVERRIDE { + defs_[index] = def; + } + void setTemp(size_t index, const LDefinition &a) MOZ_FINAL MOZ_OVERRIDE { + temps_[index] = a; + } + + size_t numSuccessors() const MOZ_OVERRIDE { + return 0; + } + MBasicBlock *getSuccessor(size_t i) const MOZ_OVERRIDE { + MOZ_ASSERT(false); + return nullptr; + } + void setSuccessor(size_t i, MBasicBlock *successor) MOZ_OVERRIDE { + MOZ_ASSERT(false); + } + + // Default accessors, assuming a single input and output, respectively. + const LAllocation *input() { + MOZ_ASSERT(numOperands() == 1); + return getOperand(0); + } + const LDefinition *output() { + MOZ_ASSERT(numDefs() == 1); + return getDef(0); + } + }; +} + template -class LInstructionHelper : public LInstruction +class LInstructionHelper : public details::LInstructionFixedDefsTempsHelper { - mozilla::Array defs_; mozilla::Array operands_; - mozilla::Array temps_; public: - size_t numDefs() const MOZ_FINAL MOZ_OVERRIDE { - return Defs; - } - LDefinition *getDef(size_t index) MOZ_FINAL MOZ_OVERRIDE { - return &defs_[index]; - } size_t numOperands() const MOZ_FINAL MOZ_OVERRIDE { return Operands; } LAllocation *getOperand(size_t index) MOZ_FINAL MOZ_OVERRIDE { return &operands_[index]; } - size_t numTemps() const MOZ_FINAL MOZ_OVERRIDE { - return Temps; - } - LDefinition *getTemp(size_t index) MOZ_FINAL MOZ_OVERRIDE { - return &temps_[index]; - } - - void setDef(size_t index, const LDefinition &def) MOZ_FINAL MOZ_OVERRIDE { - defs_[index] = def; - } void setOperand(size_t index, const LAllocation &a) MOZ_FINAL MOZ_OVERRIDE { operands_[index] = a; } - void setTemp(size_t index, const LDefinition &a) MOZ_FINAL MOZ_OVERRIDE { - temps_[index] = a; - } +}; - size_t numSuccessors() const MOZ_OVERRIDE { - return 0; - } - MBasicBlock *getSuccessor(size_t i) const MOZ_OVERRIDE { - MOZ_ASSERT(false); - return nullptr; - } - void setSuccessor(size_t i, MBasicBlock *successor) MOZ_OVERRIDE { - MOZ_ASSERT(false); - } +template +class LVariadicInstruction : public details::LInstructionFixedDefsTempsHelper +{ + FixedList operands_; - // Default accessors, assuming a single input and output, respectively. - const LAllocation *input() { - MOZ_ASSERT(numOperands() == 1); - return getOperand(0); + public: + bool init(TempAllocator &alloc, size_t length) { + return operands_.init(alloc, length); } - const LDefinition *output() { - MOZ_ASSERT(numDefs() == 1); - return getDef(0); + size_t numOperands() const MOZ_FINAL MOZ_OVERRIDE { + return operands_.length(); + } + LAllocation *getOperand(size_t index) MOZ_FINAL MOZ_OVERRIDE { + return &operands_[index]; + } + void setOperand(size_t index, const LAllocation &a) MOZ_FINAL MOZ_OVERRIDE { + operands_[index] = a; } }; diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index 136da45aeb3..e87f519e6e9 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -28,8 +28,8 @@ _(SimdInsertElementI) \ _(SimdInsertElementF) \ _(SimdSignMaskX4) \ - _(SimdGeneralSwizzleI) \ - _(SimdGeneralSwizzleF) \ + _(SimdGeneralShuffleI) \ + _(SimdGeneralShuffleF) \ _(SimdSwizzleI) \ _(SimdSwizzleF) \ _(SimdShuffle) \ diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index feba5784cce..323758d1ecd 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -3957,28 +3957,33 @@ LIRGenerator::visitSimdSwizzle(MSimdSwizzle *ins) } void -LIRGenerator::visitSimdGeneralSwizzle(MSimdGeneralSwizzle *ins) +LIRGenerator::visitSimdGeneralShuffle(MSimdGeneralShuffle*ins) { - MOZ_ASSERT(IsSimdType(ins->input()->type())); MOZ_ASSERT(IsSimdType(ins->type())); - LAllocation lanesUses[4]; - for (size_t i = 0; i < 4; i++) - lanesUses[i] = use(ins->lane(i)); + LSimdGeneralShuffleBase *lir; + if (ins->type() == MIRType_Int32x4) + lir = new (alloc()) LSimdGeneralShuffleI(temp()); + else if (ins->type() == MIRType_Float32x4) + lir = new (alloc()) LSimdGeneralShuffleF(temp()); + else + MOZ_CRASH("Unknown SIMD kind when doing a shuffle"); - if (ins->input()->type() == MIRType_Int32x4) { - LSimdGeneralSwizzleI *lir = new (alloc()) LSimdGeneralSwizzleI(useRegister(ins->input()), - lanesUses, temp()); - assignSnapshot(lir, Bailout_BoundsCheck); - define(lir, ins); - } else if (ins->input()->type() == MIRType_Float32x4) { - LSimdGeneralSwizzleF *lir = new (alloc()) LSimdGeneralSwizzleF(useRegister(ins->input()), - lanesUses, temp()); - assignSnapshot(lir, Bailout_BoundsCheck); - define(lir, ins); - } else { - MOZ_CRASH("Unknown SIMD kind when getting lane"); + if (!lir->init(alloc(), ins->numVectors() + ins->numLanes())) + return; + + for (unsigned i = 0; i < ins->numVectors(); i++) { + MOZ_ASSERT(IsSimdType(ins->vector(i)->type())); + lir->setOperand(i, useRegister(ins->vector(i))); } + + for (unsigned i = 0; i < ins->numLanes(); i++) { + MOZ_ASSERT(ins->lane(i)->type() == MIRType_Int32); + lir->setOperand(i + ins->numVectors(), useRegister(ins->lane(i))); + } + + assignSnapshot(lir, Bailout_BoundsCheck); + define(lir, ins); } void @@ -4079,8 +4084,8 @@ LIRGenerator::visitLexicalCheck(MLexicalCheck *ins) MOZ_ASSERT(input->type() == MIRType_Value); LLexicalCheck *lir = new(alloc()) LLexicalCheck(); useBox(lir, LLexicalCheck::Input, input); + assignSnapshot(lir, Bailout_UninitializedLexical); add(lir, ins); - assignSafepoint(lir, ins); redefine(ins, input); } diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index 81c5d219fae..4977131f1ab 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -269,7 +269,7 @@ class LIRGenerator : public LIRGeneratorSpecific void visitSimdInsertElement(MSimdInsertElement *ins); void visitSimdSignMask(MSimdSignMask *ins); void visitSimdSwizzle(MSimdSwizzle *ins); - void visitSimdGeneralSwizzle(MSimdGeneralSwizzle *ins); + void visitSimdGeneralShuffle(MSimdGeneralShuffle *ins); void visitSimdShuffle(MSimdShuffle *ins); void visitSimdUnaryArith(MSimdUnaryArith *ins); void visitSimdBinaryComp(MSimdBinaryComp *ins); diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 0cad20a13e4..115419c440f 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -351,19 +351,48 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSFunction *target) return inlineSimdSelect(callInfo, native, IsElementWise(false), SimdTypeDescr::TYPE_FLOAT32); if (native == js::simd_int32x4_swizzle) - return inlineSimdSwizzle(callInfo, native, SimdTypeDescr::TYPE_INT32); + return inlineSimdShuffle(callInfo, native, SimdTypeDescr::TYPE_INT32, 1, 4); if (native == js::simd_float32x4_swizzle) - return inlineSimdSwizzle(callInfo, native, SimdTypeDescr::TYPE_FLOAT32); + return inlineSimdShuffle(callInfo, native, SimdTypeDescr::TYPE_FLOAT32, 1, 4); + if (native == js::simd_int32x4_shuffle) + return inlineSimdShuffle(callInfo, native, SimdTypeDescr::TYPE_INT32, 2, 4); + if (native == js::simd_float32x4_shuffle) + return inlineSimdShuffle(callInfo, native, SimdTypeDescr::TYPE_FLOAT32, 2, 4); if (native == js::simd_int32x4_load) - return inlineSimdLoad(callInfo, native, SimdTypeDescr::TYPE_INT32); + return inlineSimdLoad(callInfo, native, SimdTypeDescr::TYPE_INT32, 4); + if (native == js::simd_int32x4_loadX) + return inlineSimdLoad(callInfo, native, SimdTypeDescr::TYPE_INT32, 1); + if (native == js::simd_int32x4_loadXY) + return inlineSimdLoad(callInfo, native, SimdTypeDescr::TYPE_INT32, 2); + if (native == js::simd_int32x4_loadXYZ) + return inlineSimdLoad(callInfo, native, SimdTypeDescr::TYPE_INT32, 3); + if (native == js::simd_float32x4_load) - return inlineSimdLoad(callInfo, native, SimdTypeDescr::TYPE_FLOAT32); + return inlineSimdLoad(callInfo, native, SimdTypeDescr::TYPE_FLOAT32, 4); + if (native == js::simd_float32x4_loadX) + return inlineSimdLoad(callInfo, native, SimdTypeDescr::TYPE_FLOAT32, 1); + if (native == js::simd_float32x4_loadXY) + return inlineSimdLoad(callInfo, native, SimdTypeDescr::TYPE_FLOAT32, 2); + if (native == js::simd_float32x4_loadXYZ) + return inlineSimdLoad(callInfo, native, SimdTypeDescr::TYPE_FLOAT32, 3); if (native == js::simd_int32x4_store) - return inlineSimdStore(callInfo, native, SimdTypeDescr::TYPE_INT32); + return inlineSimdStore(callInfo, native, SimdTypeDescr::TYPE_INT32, 4); + if (native == js::simd_int32x4_storeX) + return inlineSimdStore(callInfo, native, SimdTypeDescr::TYPE_INT32, 1); + if (native == js::simd_int32x4_storeXY) + return inlineSimdStore(callInfo, native, SimdTypeDescr::TYPE_INT32, 2); + if (native == js::simd_int32x4_storeXYZ) + return inlineSimdStore(callInfo, native, SimdTypeDescr::TYPE_INT32, 3); if (native == js::simd_float32x4_store) - return inlineSimdStore(callInfo, native, SimdTypeDescr::TYPE_FLOAT32); + return inlineSimdStore(callInfo, native, SimdTypeDescr::TYPE_FLOAT32, 4); + if (native == js::simd_float32x4_storeX) + return inlineSimdStore(callInfo, native, SimdTypeDescr::TYPE_FLOAT32, 1); + if (native == js::simd_float32x4_storeXY) + return inlineSimdStore(callInfo, native, SimdTypeDescr::TYPE_FLOAT32, 2); + if (native == js::simd_float32x4_storeXYZ) + return inlineSimdStore(callInfo, native, SimdTypeDescr::TYPE_FLOAT32, 3); return InliningStatus_NotInlined; } @@ -3113,18 +3142,24 @@ IonBuilder::inlineSimdCheck(CallInfo &callInfo, JSNative native, SimdTypeDescr:: } IonBuilder::InliningStatus -IonBuilder::inlineSimdSwizzle(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type) +IonBuilder::inlineSimdShuffle(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type, + unsigned numVectors, unsigned numLanes) { InlineTypedObject *templateObj = nullptr; - if (!checkInlineSimd(callInfo, native, type, 5, &templateObj)) + if (!checkInlineSimd(callInfo, native, type, numVectors + numLanes, &templateObj)) return InliningStatus_NotInlined; - MDefinition *lanes[4]; - for (size_t i = 0; i < 4; i++) - lanes[i] = callInfo.getArg(1 + i); - MIRType mirType = SimdTypeDescrToMIRType(type); - MSimdGeneralSwizzle *ins = MSimdGeneralSwizzle::New(alloc(), callInfo.getArg(0), lanes, mirType); + MSimdGeneralShuffle *ins = MSimdGeneralShuffle::New(alloc(), numVectors, numLanes, mirType); + + if (!ins->init(alloc())) + return InliningStatus_Error; + + for (unsigned i = 0; i < numVectors; i++) + ins->setVector(i, callInfo.getArg(i)); + for (size_t i = 0; i < numLanes; i++) + ins->setLane(i, callInfo.getArg(numVectors + i)); + return boxSimd(callInfo, ins, templateObj); } @@ -3184,7 +3219,8 @@ IonBuilder::prepareForSimdLoadStore(CallInfo &callInfo, Scalar::Type simdType, M } IonBuilder::InliningStatus -IonBuilder::inlineSimdLoad(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type) +IonBuilder::inlineSimdLoad(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type, + unsigned numElems) { InlineTypedObject *templateObj = nullptr; if (!checkInlineSimd(callInfo, native, type, 2, &templateObj)) @@ -3200,13 +3236,14 @@ IonBuilder::inlineSimdLoad(CallInfo &callInfo, JSNative native, SimdTypeDescr::T MLoadUnboxedScalar *load = MLoadUnboxedScalar::New(alloc(), elements, index, arrayType); load->setResultType(SimdTypeDescrToMIRType(type)); - load->setReadType(simdType); + load->setSimdRead(simdType, numElems); return boxSimd(callInfo, load, templateObj); } IonBuilder::InliningStatus -IonBuilder::inlineSimdStore(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type) +IonBuilder::inlineSimdStore(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type, + unsigned numElems) { InlineTypedObject *templateObj = nullptr; if (!checkInlineSimd(callInfo, native, type, 3, &templateObj)) @@ -3223,7 +3260,7 @@ IonBuilder::inlineSimdStore(CallInfo &callInfo, JSNative native, SimdTypeDescr:: MDefinition *valueToWrite = callInfo.getArg(2); MStoreUnboxedScalar *store = MStoreUnboxedScalar::New(alloc(), elements, index, valueToWrite, arrayType); - store->setWriteType(simdType); + store->setSimdWrite(simdType, numElems); current->add(store); current->push(valueToWrite); diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 610dc1b61ca..680984b09d5 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -965,17 +965,26 @@ MSimdSwizzle::foldsTo(TempAllocator &alloc) } MDefinition * -MSimdGeneralSwizzle::foldsTo(TempAllocator &alloc) +MSimdGeneralShuffle::foldsTo(TempAllocator &alloc) { - int32_t lanes[4]; - for (size_t i = 0; i < 4; i++) { + FixedList lanes; + if (!lanes.init(alloc, numLanes())) + return this; + + for (size_t i = 0; i < numLanes(); i++) { if (!lane(i)->isConstant() || lane(i)->type() != MIRType_Int32) return this; - lanes[i] = lane(i)->toConstant()->value().toInt32(); - if (lanes[i] < 0 || lanes[i] >= 4) + int32_t temp = lane(i)->toConstant()->value().toInt32(); + if (temp < 0 || uint32_t(temp) >= numLanes() * numVectors()) return this; + lanes[i] = uint32_t(temp); } - return MSimdSwizzle::New(alloc, input(), type(), lanes[0], lanes[1], lanes[2], lanes[3]); + + if (numVectors() == 1) + return MSimdSwizzle::New(alloc, vector(0), type(), lanes[0], lanes[1], lanes[2], lanes[3]); + + MOZ_ASSERT(numVectors() == 2); + return MSimdShuffle::New(alloc, vector(0), vector(1), type(), lanes[0], lanes[1], lanes[2], lanes[3]); } template diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index fd1f9939131..bb1b12dabbc 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -1814,12 +1814,6 @@ class MSimdSwizzle public: INSTRUCTION_HEADER(SimdSwizzle) - static MSimdSwizzle *NewAsmJS(TempAllocator &alloc, MDefinition *obj, MIRType type, - uint32_t laneX, uint32_t laneY, uint32_t laneZ, uint32_t laneW) - { - return new(alloc) MSimdSwizzle(obj, type, laneX, laneY, laneZ, laneW); - } - static MSimdSwizzle *New(TempAllocator &alloc, MDefinition *obj, MIRType type, uint32_t laneX, uint32_t laneY, uint32_t laneZ, uint32_t laneW) { @@ -1842,23 +1836,24 @@ class MSimdSwizzle ALLOW_CLONE(MSimdSwizzle) }; -// A "general swizzle" is a swizzle with non-constant lane indices. This is the -// one that Ion inlines and it can be folded into a MSimdSwizzle if lane indices -// are constant. Performance of general swizzle does not really matter, as we -// expect to always get constant indices. -class MSimdGeneralSwizzle : - public MAryInstruction<5>, - public SimdSwizzlePolicy::Data +// A "general swizzle" is a swizzle or a shuffle with non-constant lane +// indices. This is the one that Ion inlines and it can be folded into a +// MSimdSwizzle/MSimdShuffle if lane indices are constant. Performance of +// general swizzle/shuffle does not really matter, as we expect to get +// constant indices most of the time. +class MSimdGeneralShuffle : + public MVariadicInstruction, + public SimdShufflePolicy::Data { + unsigned numVectors_; + unsigned numLanes_; + protected: - MSimdGeneralSwizzle(MDefinition *vec, MDefinition *lanes[4], MIRType type) + MSimdGeneralShuffle(unsigned numVectors, unsigned numLanes, MIRType type) + : numVectors_(numVectors), numLanes_(numLanes) { MOZ_ASSERT(IsSimdType(type)); - MOZ_ASSERT(SimdTypeToLength(type) == 4); - - initOperand(0, vec); - for (unsigned i = 0; i < 4; i++) - initOperand(1 + i, lanes[i]); + MOZ_ASSERT(SimdTypeToLength(type) == numLanes_); setResultType(type); specialization_ = type; @@ -1866,24 +1861,48 @@ class MSimdGeneralSwizzle : } public: - INSTRUCTION_HEADER(SimdGeneralSwizzle); - ALLOW_CLONE(MSimdGeneralSwizzle); + INSTRUCTION_HEADER(SimdGeneralShuffle); - static MSimdGeneralSwizzle *New(TempAllocator &alloc, MDefinition *vec, MDefinition *lanes[4], + static MSimdGeneralShuffle *New(TempAllocator &alloc, unsigned numVectors, unsigned numLanes, MIRType type) { - return new(alloc) MSimdGeneralSwizzle(vec, lanes, type); + return new(alloc) MSimdGeneralShuffle(numVectors, numLanes, type); } - MDefinition *input() const { - return getOperand(0); + bool init(TempAllocator &alloc) { + return MVariadicInstruction::init(alloc, numVectors_ + numLanes_); } - MDefinition *lane(size_t i) const { - return getOperand(1 + i); + void setVector(unsigned i, MDefinition* vec) { + MOZ_ASSERT(i < numVectors_); + initOperand(i, vec); + } + void setLane(unsigned i, MDefinition* laneIndex) { + MOZ_ASSERT(i < numLanes_); + initOperand(numVectors_ + i, laneIndex); + } + + unsigned numVectors() const { + return numVectors_; + } + unsigned numLanes() const { + return numLanes_; + } + MDefinition *vector(unsigned i) const { + MOZ_ASSERT(i < numVectors_); + return getOperand(i); + } + MDefinition *lane(unsigned i) const { + MOZ_ASSERT(i < numLanes_); + return getOperand(numVectors_ + i); } bool congruentTo(const MDefinition *ins) const MOZ_OVERRIDE { - return congruentIfOperandsEqual(ins); + if (!ins->isSimdGeneralShuffle()) + return false; + const MSimdGeneralShuffle *other = ins->toSimdGeneralShuffle(); + return numVectors_ == other->numVectors() && + numLanes_ == other->numLanes() && + congruentIfOperandsEqual(other); } MDefinition *foldsTo(TempAllocator &alloc) MOZ_OVERRIDE; @@ -1918,9 +1937,9 @@ class MSimdShuffle public: INSTRUCTION_HEADER(SimdShuffle) - static MInstruction *NewAsmJS(TempAllocator &alloc, MDefinition *lhs, MDefinition *rhs, - MIRType type, uint32_t laneX, uint32_t laneY, uint32_t laneZ, - uint32_t laneW) + static MInstruction *New(TempAllocator &alloc, MDefinition *lhs, MDefinition *rhs, + MIRType type, uint32_t laneX, uint32_t laneY, uint32_t laneZ, + uint32_t laneW) { // Swap operands so that new lanes come from LHS in majority. // In the balanced case, swap operands if needs be, in order to be able @@ -1936,7 +1955,7 @@ class MSimdShuffle // If all lanes come from the same vector, just use swizzle instead. if (laneX < 4 && laneY < 4 && laneZ < 4 && laneW < 4) - return MSimdSwizzle::NewAsmJS(alloc, lhs, type, laneX, laneY, laneZ, laneW); + return MSimdSwizzle::New(alloc, lhs, type, laneX, laneY, laneZ, laneW); return new(alloc) MSimdShuffle(lhs, rhs, type, laneX, laneY, laneZ, laneW); } @@ -3340,6 +3359,9 @@ class MObjectState replaceOperand(slot + 1, def); } + bool hasFixedSlot(uint32_t slot) const { + return slot < numSlots() && slot < numFixedSlots(); + } MDefinition *getFixedSlot(uint32_t slot) const { MOZ_ASSERT(slot < numFixedSlots()); return getSlot(slot); @@ -3349,6 +3371,9 @@ class MObjectState setSlot(slot, def); } + bool hasDynamicSlot(uint32_t slot) const { + return numFixedSlots() < numSlots() && slot < numSlots() - numFixedSlots(); + } MDefinition *getDynamicSlot(uint32_t slot) const { return getSlot(slot + numFixedSlots()); } @@ -6960,7 +6985,8 @@ class MAsmJSInterruptCheck } }; -// Checks if a value is JS_UNINITIALIZED_LEXICAL, throwing if so. +// Checks if a value is JS_UNINITIALIZED_LEXICAL, bailout out if so, leaving +// it to baseline to throw at the correct pc. class MLexicalCheck : public MUnaryInstruction, public BoxPolicy<0>::Data @@ -6968,9 +6994,9 @@ class MLexicalCheck explicit MLexicalCheck(MDefinition *input) : MUnaryInstruction(input) { - setGuard(); setResultType(MIRType_Value); setResultTypeSet(input->resultTypeSet()); + setMovable(); } public: @@ -6987,6 +7013,10 @@ class MLexicalCheck MDefinition *input() const { return getOperand(0); } + + bool congruentTo(const MDefinition *ins) const MOZ_OVERRIDE { + return congruentIfOperandsEqual(ins); + } }; // Unconditionally throw an uninitialized let error. @@ -8835,6 +8865,7 @@ class MLoadUnboxedScalar { Scalar::Type indexType_; Scalar::Type readType_; + unsigned numElems_; // used only for SIMD bool requiresBarrier_; int32_t offsetAdjustment_; bool canonicalizeDoubles_; @@ -8845,6 +8876,7 @@ class MLoadUnboxedScalar : MBinaryInstruction(elements, index), indexType_(indexType), readType_(indexType), + numElems_(1), requiresBarrier_(requiresBarrier == DoesRequireMemoryBarrier), offsetAdjustment_(offsetAdjustment), canonicalizeDoubles_(canonicalizeDoubles) @@ -8874,8 +8906,12 @@ class MLoadUnboxedScalar canonicalizeDoubles); } - void setReadType(Scalar::Type type) { + void setSimdRead(Scalar::Type type, unsigned numElems) { readType_ = type; + numElems_ = numElems; + } + unsigned numElems() const { + return numElems_; } Scalar::Type readType() const { return readType_; @@ -8921,6 +8957,8 @@ class MLoadUnboxedScalar return false; if (readType_ != other->readType_) return false; + if (numElems_ != other->numElems_) + return false; if (offsetAdjustment() != other->offsetAdjustment()) return false; if (canonicalizeDoubles() != other->canonicalizeDoubles()) @@ -9114,6 +9152,7 @@ class MStoreUnboxedScalar Scalar::Type indexType_; bool requiresBarrier_; int32_t offsetAdjustment_; + unsigned numElems_; // used only for SIMD MStoreUnboxedScalar(MDefinition *elements, MDefinition *index, MDefinition *value, Scalar::Type indexType, MemoryBarrierRequirement requiresBarrier, @@ -9122,7 +9161,8 @@ class MStoreUnboxedScalar StoreUnboxedScalarBase(indexType), indexType_(indexType), requiresBarrier_(requiresBarrier == DoesRequireMemoryBarrier), - offsetAdjustment_(offsetAdjustment) + offsetAdjustment_(offsetAdjustment), + numElems_(1) { if (requiresBarrier_) setGuard(); // Not removable or movable @@ -9147,6 +9187,14 @@ class MStoreUnboxedScalar requiresBarrier, offsetAdjustment); } + void setSimdWrite(Scalar::Type writeType, unsigned numElems) { + MOZ_ASSERT(Scalar::isSimdType(writeType)); + setWriteType(writeType); + numElems_ = numElems; + } + unsigned numElems() const { + return numElems_; + } Scalar::Type indexType() const { return indexType_; } diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index 39097ad1a60..74b3e56b7b0 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -24,7 +24,7 @@ namespace jit { _(SimdInsertElement) \ _(SimdSignMask) \ _(SimdSwizzle) \ - _(SimdGeneralSwizzle) \ + _(SimdGeneralShuffle) \ _(SimdShuffle) \ _(SimdUnaryArith) \ _(SimdBinaryComp) \ diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index 45ad0f6f5ed..1a3428d23a9 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -280,7 +280,8 @@ template void MacroAssembler::guardType(const ValueOperand &value, TypeSet::Type template static void -StoreToTypedFloatArray(MacroAssembler &masm, int arrayType, const S &value, const T &dest) +StoreToTypedFloatArray(MacroAssembler &masm, int arrayType, const S &value, const T &dest, + unsigned numElems) { switch (arrayType) { case Scalar::Float32: @@ -294,10 +295,38 @@ StoreToTypedFloatArray(MacroAssembler &masm, int arrayType, const S &value, cons masm.storeDouble(value, dest); break; case Scalar::Float32x4: - masm.storeUnalignedFloat32x4(value, dest); + switch (numElems) { + case 1: + masm.storeFloat32(value, dest); + break; + case 2: + masm.storeDouble(value, dest); + break; + case 3: + masm.storeFloat32x3(value, dest); + break; + case 4: + masm.storeUnalignedFloat32x4(value, dest); + break; + default: MOZ_CRASH("unexpected number of elements in simd write"); + } break; case Scalar::Int32x4: - masm.storeUnalignedInt32x4(value, dest); + switch (numElems) { + case 1: + masm.storeInt32x1(value, dest); + break; + case 2: + masm.storeInt32x2(value, dest); + break; + case 3: + masm.storeInt32x3(value, dest); + break; + case 4: + masm.storeUnalignedInt32x4(value, dest); + break; + default: MOZ_CRASH("unexpected number of elements in simd write"); + } break; default: MOZ_CRASH("Invalid typed array type"); @@ -306,21 +335,21 @@ StoreToTypedFloatArray(MacroAssembler &masm, int arrayType, const S &value, cons void MacroAssembler::storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, - const BaseIndex &dest) + const BaseIndex &dest, unsigned numElems) { - StoreToTypedFloatArray(*this, arrayType, value, dest); + StoreToTypedFloatArray(*this, arrayType, value, dest, numElems); } void MacroAssembler::storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, - const Address &dest) + const Address &dest, unsigned numElems) { - StoreToTypedFloatArray(*this, arrayType, value, dest); + StoreToTypedFloatArray(*this, arrayType, value, dest, numElems); } template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const T &src, AnyRegister dest, Register temp, - Label *fail, bool canonicalizeDoubles) + Label *fail, bool canonicalizeDoubles, unsigned numElems) { switch (arrayType) { case Scalar::Int8: @@ -362,10 +391,38 @@ MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const T &src, AnyRegi canonicalizeDouble(dest.fpu()); break; case Scalar::Int32x4: - loadUnalignedInt32x4(src, dest.fpu()); + switch (numElems) { + case 1: + loadInt32x1(src, dest.fpu()); + break; + case 2: + loadInt32x2(src, dest.fpu()); + break; + case 3: + loadInt32x3(src, dest.fpu()); + break; + case 4: + loadUnalignedInt32x4(src, dest.fpu()); + break; + default: MOZ_CRASH("unexpected number of elements in SIMD load"); + } break; case Scalar::Float32x4: - loadUnalignedFloat32x4(src, dest.fpu()); + switch (numElems) { + case 1: + loadFloat32(src, dest.fpu()); + break; + case 2: + loadDouble(src, dest.fpu()); + break; + case 3: + loadFloat32x3(src, dest.fpu()); + break; + case 4: + loadUnalignedFloat32x4(src, dest.fpu()); + break; + default: MOZ_CRASH("unexpected number of elements in SIMD load"); + } break; default: MOZ_CRASH("Invalid typed array type"); @@ -373,9 +430,11 @@ MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const T &src, AnyRegi } template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const Address &src, AnyRegister dest, - Register temp, Label *fail, bool canonicalizeDoubles); + Register temp, Label *fail, bool canonicalizeDoubles, + unsigned numElems); template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const BaseIndex &src, AnyRegister dest, - Register temp, Label *fail, bool canonicalizeDoubles); + Register temp, Label *fail, bool canonicalizeDoubles, + unsigned numElems); template void diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index e22c8186c09..837989c8a8b 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -717,7 +717,7 @@ class MacroAssembler : public MacroAssemblerSpecific template void loadFromTypedArray(Scalar::Type arrayType, const T &src, AnyRegister dest, Register temp, Label *fail, - bool canonicalizeDoubles = true); + bool canonicalizeDoubles = true, unsigned numElems = 0); template void loadFromTypedArray(Scalar::Type arrayType, const T &src, const ValueOperand &dest, bool allowDouble, @@ -757,8 +757,10 @@ class MacroAssembler : public MacroAssemblerSpecific template void atomicBinopToTypedIntArray(AtomicOp op, Scalar::Type arrayType, const S &value, const T &mem); - void storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, const BaseIndex &dest); - void storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, const Address &dest); + void storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, const BaseIndex &dest, + unsigned numElems = 0); + void storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, const Address &dest, + unsigned numElems = 0); // Load a property from an UnboxedPlainObject. template diff --git a/js/src/jit/OptimizationTracking.cpp b/js/src/jit/OptimizationTracking.cpp index f3f3cd2847b..be78e56a7b3 100644 --- a/js/src/jit/OptimizationTracking.cpp +++ b/js/src/jit/OptimizationTracking.cpp @@ -91,9 +91,9 @@ JS_PUBLIC_API(const char *) JS::TrackedStrategyString(TrackedStrategy strategy) { switch (strategy) { -#define STRATEGY_CASE(name, msg) \ +#define STRATEGY_CASE(name) \ case TrackedStrategy::name: \ - return msg; + return #name; TRACKED_STRATEGY_LIST(STRATEGY_CASE) #undef STRATEGY_CASE @@ -106,9 +106,9 @@ JS_PUBLIC_API(const char *) JS::TrackedOutcomeString(TrackedOutcome outcome) { switch (outcome) { -#define OUTCOME_CASE(name, msg) \ +#define OUTCOME_CASE(name) \ case TrackedOutcome::name: \ - return msg; + return #name; TRACKED_OUTCOME_LIST(OUTCOME_CASE) #undef OUTCOME_CASE @@ -121,9 +121,9 @@ JS_PUBLIC_API(const char *) JS::TrackedTypeSiteString(TrackedTypeSite site) { switch (site) { -#define TYPESITE_CASE(name, msg) \ +#define TYPESITE_CASE(name) \ case TrackedTypeSite::name: \ - return msg; + return #name; TRACKED_TYPESITE_LIST(TYPESITE_CASE) #undef TYPESITE_CASE @@ -445,7 +445,7 @@ IonTrackedOptimizationsRegion::RangeIterator::readNext(uint32_t *startOffset, ui } Maybe -JitcodeGlobalEntry::IonEntry::trackedOptimizationIndexAtAddr(void *ptr) +JitcodeGlobalEntry::IonEntry::trackedOptimizationIndexAtAddr(void *ptr, uint32_t *entryOffsetOut) { MOZ_ASSERT(hasTrackedOptimizations()); MOZ_ASSERT(containsPointer(ptr)); @@ -453,7 +453,7 @@ JitcodeGlobalEntry::IonEntry::trackedOptimizationIndexAtAddr(void *ptr) Maybe region = optsRegionTable_->findRegion(ptrOffset); if (region.isNothing()) return Nothing(); - return region->findIndex(ptrOffset); + return region->findIndex(ptrOffset, entryOffsetOut); } void @@ -491,9 +491,9 @@ IonTrackedOptimizationsTypeInfo::forEach(ForEachOp &op, const IonTrackedTypeVect } Maybe -IonTrackedOptimizationsRegion::findIndex(uint32_t offset) const +IonTrackedOptimizationsRegion::findIndex(uint32_t offset, uint32_t *entryOffsetOut) const { - if (offset < startOffset_ || offset >= endOffset_) + if (offset <= startOffset_ || offset > endOffset_) return Nothing(); // Linear search through the run. @@ -502,8 +502,10 @@ IonTrackedOptimizationsRegion::findIndex(uint32_t offset) const uint32_t startOffset, endOffset; uint8_t index; iter.readNext(&startOffset, &endOffset, &index); - if (startOffset <= offset && offset <= endOffset) + if (startOffset < offset && offset <= endOffset) { + *entryOffsetOut = endOffset; return Some(index); + } } return Nothing(); } @@ -525,7 +527,7 @@ IonTrackedOptimizationsRegionTable::findRegion(uint32_t offset) const if (regions <= LINEAR_SEARCH_THRESHOLD) { for (uint32_t i = 0; i < regions; i++) { IonTrackedOptimizationsRegion region = entry(i); - if (region.startOffset() <= offset && offset <= region.endOffset()) { + if (region.startOffset() < offset && offset <= region.endOffset()) { return Some(entry(i)); } } @@ -539,7 +541,7 @@ IonTrackedOptimizationsRegionTable::findRegion(uint32_t offset) const uint32_t mid = i + step; IonTrackedOptimizationsRegion region = entry(mid); - if (offset < region.startOffset()) { + if (offset <= region.startOffset()) { // Entry is below mid. regions = step; } else if (offset > region.endOffset()) { @@ -1126,7 +1128,7 @@ IonBuilder::trackInlineSuccessUnchecked(InliningStatus status) } JS_PUBLIC_API(void) -JS::ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr, +JS::ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr, uint8_t index, ForEachTrackedOptimizationAttemptOp &op, JSScript **scriptOut, jsbytecode **pcOut) { @@ -1134,8 +1136,7 @@ JS::ForEachTrackedOptimizationAttempt(JSRuntime *rt, void *addr, JitcodeGlobalEntry entry; table->lookupInfallible(addr, &entry, rt); entry.youngestFrameLocationAtAddr(rt, addr, scriptOut, pcOut); - Maybe index = entry.trackedOptimizationIndexAtAddr(addr); - entry.trackedOptimizationAttempts(index.value()).forEach(op); + entry.trackedOptimizationAttempts(index).forEach(op); } static void @@ -1242,13 +1243,27 @@ IonTrackedOptimizationsTypeInfo::ForEachOpAdapter::operator()(JS::TrackedTypeSit } JS_PUBLIC_API(void) -JS::ForEachTrackedOptimizationTypeInfo(JSRuntime *rt, void *addr, +JS::ForEachTrackedOptimizationTypeInfo(JSRuntime *rt, void *addr, uint8_t index, ForEachTrackedOptimizationTypeInfoOp &op) { JitcodeGlobalTable *table = rt->jitRuntime()->getJitcodeGlobalTable(); JitcodeGlobalEntry entry; table->lookupInfallible(addr, &entry, rt); IonTrackedOptimizationsTypeInfo::ForEachOpAdapter adapter(op); - Maybe index = entry.trackedOptimizationIndexAtAddr(addr); - entry.trackedOptimizationTypeInfo(index.value()).forEach(adapter, entry.allTrackedTypes()); + entry.trackedOptimizationTypeInfo(index).forEach(adapter, entry.allTrackedTypes()); +} + +JS_PUBLIC_API(Maybe) +JS::TrackedOptimizationIndexAtAddr(JSRuntime *rt, void *addr, void **entryAddr) +{ + JitcodeGlobalTable *table = rt->jitRuntime()->getJitcodeGlobalTable(); + JitcodeGlobalEntry entry; + table->lookupInfallible(addr, &entry, rt); + if (!entry.hasTrackedOptimizations()) + return Nothing(); + uint32_t entryOffset = 0; + Maybe index = entry.trackedOptimizationIndexAtAddr(addr, &entryOffset); + if (index.isSome()) + *entryAddr = (void *)(((uint8_t *) entry.nativeStartAddr()) + entryOffset); + return index; } diff --git a/js/src/jit/OptimizationTracking.h b/js/src/jit/OptimizationTracking.h index f8eebb7d67b..2350bd0d1ce 100644 --- a/js/src/jit/OptimizationTracking.h +++ b/js/src/jit/OptimizationTracking.h @@ -316,7 +316,7 @@ class IonTrackedOptimizationsRegion // Find the index of tracked optimization info (e.g., type info and // attempts) at a native code offset. - mozilla::Maybe findIndex(uint32_t offset) const; + mozilla::Maybe findIndex(uint32_t offset, uint32_t *entryOffsetOut) const; // For the variants below, S stands for startDelta, L for length, and I // for index. These were automatically generated from training on the diff --git a/js/src/jit/ScalarReplacement.cpp b/js/src/jit/ScalarReplacement.cpp index 8e8a539b859..c731eccb5d5 100644 --- a/js/src/jit/ScalarReplacement.cpp +++ b/js/src/jit/ScalarReplacement.cpp @@ -436,9 +436,14 @@ ObjectMemoryView::visitStoreFixedSlot(MStoreFixedSlot *ins) return; // Clone the state and update the slot value. - state_ = BlockState::Copy(alloc_, state_); - state_->setFixedSlot(ins->slot(), ins->value()); - ins->block()->insertBefore(ins->toInstruction(), state_); + if (state_->hasFixedSlot(ins->slot())) { + state_ = BlockState::Copy(alloc_, state_); + state_->setFixedSlot(ins->slot(), ins->value()); + ins->block()->insertBefore(ins->toInstruction(), state_); + } else { + MBail *bailout = MBail::New(alloc_, Bailout_Inevitable); + ins->block()->insertBefore(ins, bailout); + } // Remove original instruction. ins->block()->discard(ins); @@ -452,7 +457,13 @@ ObjectMemoryView::visitLoadFixedSlot(MLoadFixedSlot *ins) return; // Replace load by the slot value. - ins->replaceAllUsesWith(state_->getFixedSlot(ins->slot())); + if (state_->hasFixedSlot(ins->slot())) { + ins->replaceAllUsesWith(state_->getFixedSlot(ins->slot())); + } else { + MBail *bailout = MBail::New(alloc_, Bailout_Inevitable); + ins->block()->insertBefore(ins, bailout); + ins->replaceAllUsesWith(undefinedVal_); + } // Remove original instruction. ins->block()->discard(ins); @@ -481,9 +492,14 @@ ObjectMemoryView::visitStoreSlot(MStoreSlot *ins) } // Clone the state and update the slot value. - state_ = BlockState::Copy(alloc_, state_); - state_->setDynamicSlot(ins->slot(), ins->value()); - ins->block()->insertBefore(ins->toInstruction(), state_); + if (state_->hasDynamicSlot(ins->slot())) { + state_ = BlockState::Copy(alloc_, state_); + state_->setDynamicSlot(ins->slot(), ins->value()); + ins->block()->insertBefore(ins->toInstruction(), state_); + } else { + MBail *bailout = MBail::New(alloc_, Bailout_Inevitable); + ins->block()->insertBefore(ins, bailout); + } // Remove original instruction. ins->block()->discard(ins); @@ -501,7 +517,13 @@ ObjectMemoryView::visitLoadSlot(MLoadSlot *ins) } // Replace load by the slot value. - ins->replaceAllUsesWith(state_->getDynamicSlot(ins->slot())); + if (state_->hasDynamicSlot(ins->slot())) { + ins->replaceAllUsesWith(state_->getDynamicSlot(ins->slot())); + } else { + MBail *bailout = MBail::New(alloc_, Bailout_Inevitable); + ins->block()->insertBefore(ins, bailout); + ins->replaceAllUsesWith(undefinedVal_); + } // Remove original instruction. ins->block()->discard(ins); diff --git a/js/src/jit/TypePolicy.cpp b/js/src/jit/TypePolicy.cpp index 8528644aa95..b7f9e95701e 100644 --- a/js/src/jit/TypePolicy.cpp +++ b/js/src/jit/TypePolicy.cpp @@ -786,23 +786,26 @@ template bool SimdPolicy<0>::adjustInputs(TempAllocator &alloc, MInstruction *ins); bool -SimdSwizzlePolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins) +SimdShufflePolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins) { MIRType specialization = ins->typePolicySpecialization(); - // First input is the vector input. - if (!MaybeSimdUnbox(alloc, ins, specialization, 0)) - return false; + MSimdGeneralShuffle *s = ins->toSimdGeneralShuffle(); + + for (unsigned i = 0; i < s->numVectors(); i++) { + if (!MaybeSimdUnbox(alloc, ins, specialization, i)) + return false; + } // Next inputs are the lanes, which need to be int32 - for (unsigned i = 0; i < 4; i++) { - MDefinition *in = ins->getOperand(i + 1); + for (unsigned i = 0; i < s->numLanes(); i++) { + MDefinition *in = ins->getOperand(s->numVectors() + i); if (in->type() == MIRType_Int32) continue; MInstruction *replace = MToInt32::New(alloc, in, MacroAssembler::IntConversion_NumbersOnly); ins->block()->insertBefore(ins, replace); - ins->replaceOperand(i + 1, replace); + ins->replaceOperand(s->numVectors() + i, replace); if (!replace->typePolicy()->adjustInputs(alloc, replace)) return false; } @@ -1115,7 +1118,7 @@ FilterTypeSetPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins) _(PowPolicy) \ _(SimdAllPolicy) \ _(SimdSelectPolicy) \ - _(SimdSwizzlePolicy) \ + _(SimdShufflePolicy) \ _(StoreTypedArrayElementStaticPolicy) \ _(StoreTypedArrayHolePolicy) \ _(StoreUnboxedScalarPolicy) \ diff --git a/js/src/jit/TypePolicy.h b/js/src/jit/TypePolicy.h index 5f6cf4b6380..013f027b40c 100644 --- a/js/src/jit/TypePolicy.h +++ b/js/src/jit/TypePolicy.h @@ -330,7 +330,7 @@ class SimdSelectPolicy MOZ_FINAL : public TypePolicy virtual bool adjustInputs(TempAllocator &alloc, MInstruction *ins) MOZ_OVERRIDE; }; -class SimdSwizzlePolicy MOZ_FINAL : public TypePolicy +class SimdShufflePolicy MOZ_FINAL : public TypePolicy { public: SPECIALIZATION_DATA_; diff --git a/js/src/jit/arm/CodeGenerator-arm.h b/js/src/jit/arm/CodeGenerator-arm.h index 54cbdc37d7e..2e6d31d33e2 100644 --- a/js/src/jit/arm/CodeGenerator-arm.h +++ b/js/src/jit/arm/CodeGenerator-arm.h @@ -245,8 +245,8 @@ class CodeGeneratorARM : public CodeGeneratorShared void visitSimdExtractElementI(LSimdExtractElementI *ins) { MOZ_CRASH("NYI"); } void visitSimdExtractElementF(LSimdExtractElementF *ins) { MOZ_CRASH("NYI"); } void visitSimdSignMaskX4(LSimdSignMaskX4 *ins) { MOZ_CRASH("NYI"); } - void visitSimdGeneralSwizzleI(LSimdGeneralSwizzleI *lir) { MOZ_CRASH("NYI"); } - void visitSimdGeneralSwizzleF(LSimdGeneralSwizzleF *lir) { MOZ_CRASH("NYI"); } + void visitSimdGeneralShuffleI(LSimdGeneralShuffleI *lir) { MOZ_CRASH("NYI"); } + void visitSimdGeneralShuffleF(LSimdGeneralShuffleF *lir) { MOZ_CRASH("NYI"); } void visitSimdSwizzleI(LSimdSwizzleI *lir) { MOZ_CRASH("NYI"); } void visitSimdSwizzleF(LSimdSwizzleF *lir) { MOZ_CRASH("NYI"); } void visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *lir) { MOZ_CRASH("NYI"); } diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 6cf13ad98e9..ae99327d186 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -1395,6 +1395,18 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void loadPrivate(const Address &address, Register dest); + void loadInt32x1(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } + void loadInt32x1(const BaseIndex &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } + void loadInt32x2(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } + void loadInt32x2(const BaseIndex &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } + void loadInt32x3(const Address &src, FloatRegister dest) { MOZ_CRASH("NYI"); } + void loadInt32x3(const BaseIndex &src, FloatRegister dest) { MOZ_CRASH("NYI"); } + void storeInt32x1(FloatRegister src, const Address &dest) { MOZ_CRASH("NYI"); } + void storeInt32x1(FloatRegister src, const BaseIndex &dest) { MOZ_CRASH("NYI"); } + void storeInt32x2(FloatRegister src, const Address &dest) { MOZ_CRASH("NYI"); } + void storeInt32x2(FloatRegister src, const BaseIndex &dest) { MOZ_CRASH("NYI"); } + void storeInt32x3(FloatRegister src, const Address &dest) { MOZ_CRASH("NYI"); } + void storeInt32x3(FloatRegister src, const BaseIndex &dest) { MOZ_CRASH("NYI"); } void loadAlignedInt32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } void storeAlignedInt32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); } void loadUnalignedInt32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } @@ -1402,6 +1414,10 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void storeUnalignedInt32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); } void storeUnalignedInt32x4(FloatRegister src, BaseIndex addr) { MOZ_CRASH("NYI"); } + void loadFloat32x3(const Address &src, FloatRegister dest) { MOZ_CRASH("NYI"); } + void loadFloat32x3(const BaseIndex &src, FloatRegister dest) { MOZ_CRASH("NYI"); } + void storeFloat32x3(FloatRegister src, const Address &dest) { MOZ_CRASH("NYI"); } + void storeFloat32x3(FloatRegister src, const BaseIndex &dest) { MOZ_CRASH("NYI"); } void loadAlignedFloat32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } void storeAlignedFloat32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); } void loadUnalignedFloat32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } diff --git a/js/src/jit/mips/CodeGenerator-mips.h b/js/src/jit/mips/CodeGenerator-mips.h index 8f3273dae66..7ba07cab280 100644 --- a/js/src/jit/mips/CodeGenerator-mips.h +++ b/js/src/jit/mips/CodeGenerator-mips.h @@ -290,8 +290,8 @@ class CodeGeneratorMIPS : public CodeGeneratorShared void visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *lir) { MOZ_CRASH("NYI"); } void visitSimdBinaryArithFx4(LSimdBinaryArithFx4 *lir) { MOZ_CRASH("NYI"); } void visitSimdBinaryBitwiseX4(LSimdBinaryBitwiseX4 *lir) { MOZ_CRASH("NYI"); } - void visitSimdGeneralSwizzleI(LSimdGeneralSwizzleI *lir) { MOZ_CRASH("NYI"); } - void visitSimdGeneralSwizzleF(LSimdGeneralSwizzleF *lir) { MOZ_CRASH("NYI"); } + void visitSimdGeneralShuffleI(LSimdGeneralShuffleI *lir) { MOZ_CRASH("NYI"); } + void visitSimdGeneralShuffleF(LSimdGeneralShuffleF *lir) { MOZ_CRASH("NYI"); } }; typedef CodeGeneratorMIPS CodeGeneratorSpecific; diff --git a/js/src/jit/mips/MacroAssembler-mips.h b/js/src/jit/mips/MacroAssembler-mips.h index 0db62586a9d..77fc3f48c7b 100644 --- a/js/src/jit/mips/MacroAssembler-mips.h +++ b/js/src/jit/mips/MacroAssembler-mips.h @@ -1313,6 +1313,18 @@ public: void loadPrivate(const Address &address, Register dest); + void loadInt32x1(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } + void loadInt32x1(const BaseIndex &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } + void loadInt32x2(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } + void loadInt32x2(const BaseIndex &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } + void loadInt32x3(const Address &src, FloatRegister dest) { MOZ_CRASH("NYI"); } + void loadInt32x3(const BaseIndex &src, FloatRegister dest) { MOZ_CRASH("NYI"); } + void storeInt32x1(FloatRegister src, const Address &dest) { MOZ_CRASH("NYI"); } + void storeInt32x1(FloatRegister src, const BaseIndex &dest) { MOZ_CRASH("NYI"); } + void storeInt32x2(FloatRegister src, const Address &dest) { MOZ_CRASH("NYI"); } + void storeInt32x2(FloatRegister src, const BaseIndex &dest) { MOZ_CRASH("NYI"); } + void storeInt32x3(FloatRegister src, const Address &dest) { MOZ_CRASH("NYI"); } + void storeInt32x3(FloatRegister src, const BaseIndex &dest) { MOZ_CRASH("NYI"); } void loadAlignedInt32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } void storeAlignedInt32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); } void loadUnalignedInt32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } @@ -1320,6 +1332,10 @@ public: void storeUnalignedInt32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); } void storeUnalignedInt32x4(FloatRegister src, BaseIndex addr) { MOZ_CRASH("NYI"); } + void loadFloat32x3(const Address &src, FloatRegister dest) { MOZ_CRASH("NYI"); } + void loadFloat32x3(const BaseIndex &src, FloatRegister dest) { MOZ_CRASH("NYI"); } + void storeFloat32x3(FloatRegister src, const Address &dest) { MOZ_CRASH("NYI"); } + void storeFloat32x(FloatRegister src, const BaseIndex &dest) { MOZ_CRASH("NYI"); } void loadAlignedFloat32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } void storeAlignedFloat32x4(FloatRegister src, Address addr) { MOZ_CRASH("NYI"); } void loadUnalignedFloat32x4(const Address &addr, FloatRegister dest) { MOZ_CRASH("NYI"); } diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index 7b224121fd7..553722900dd 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -286,6 +286,11 @@ class MacroAssemblerNone : public Assembler template void moveDouble(T, S) { MOZ_CRASH(); } template CodeOffsetLabel movWithPatch(T, Register) { MOZ_CRASH(); } + template void loadInt32x1(T, FloatRegister dest) { MOZ_CRASH(); } + template void loadInt32x2(T, FloatRegister dest) { MOZ_CRASH(); } + template void loadInt32x3(T, FloatRegister dest) { MOZ_CRASH(); } + template void loadFloat32x3(T, FloatRegister dest) { MOZ_CRASH(); } + template void loadPtr(T, Register) { MOZ_CRASH(); } template void load32(T, Register) { MOZ_CRASH(); } template void loadFloat32(T, FloatRegister) { MOZ_CRASH(); } @@ -311,6 +316,10 @@ class MacroAssemblerNone : public Assembler template void storeUnalignedFloat32x4(T, S) { MOZ_CRASH(); } template void store8(T, S) { MOZ_CRASH(); } template void store16(T, S) { MOZ_CRASH(); } + template void storeInt32x1(T, S) { MOZ_CRASH(); } + template void storeInt32x2(T, S) { MOZ_CRASH(); } + template void storeInt32x3(T, S) { MOZ_CRASH(); } + template void storeFloat32x3(T, S) { MOZ_CRASH(); } template void computeEffectiveAddress(T, Register) { MOZ_CRASH(); } diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.cpp b/js/src/jit/shared/CodeGenerator-x86-shared.cpp index 971f3c05c53..e8d3655c484 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp @@ -2385,100 +2385,69 @@ CodeGeneratorX86Shared::visitSimdSignMaskX4(LSimdSignMaskX4 *ins) masm.vmovmskps(input, output); } -void -CodeGeneratorX86Shared::visitSimdGeneralSwizzleI(LSimdGeneralSwizzleI *ins) +template void +CodeGeneratorX86Shared::visitSimdGeneralShuffle(LSimdGeneralShuffleBase *ins, Reg tempRegister) { - FloatRegister input = ToFloatRegister(ins->base()); - Register temp = ToRegister(ins->temp()); + MSimdGeneralShuffle *mir = ins->mir(); + unsigned numVectors = mir->numVectors(); + + Register laneTemp = ToRegister(ins->temp()); // This won't generate fast code, but it's fine because we expect users - // to have used constant indices (and thus MSimdGeneralSwizzle to be fold - // into MSimdSwizzle, which are fast). - masm.reserveStack(Simd128DataSize * 2); + // to have used constant indices (and thus MSimdGeneralShuffle to be fold + // into MSimdSwizzle/MSimdShuffle, which are fast). + masm.reserveStack(Simd128DataSize * numVectors); - masm.storeAlignedInt32x4(input, Address(StackPointer, Simd128DataSize)); + for (unsigned i = 0; i < numVectors; i++) { + masm.storeAlignedVector(ToFloatRegister(ins->vector(i)), + Address(StackPointer, Simd128DataSize * (1 + i))); + } Label bail; - for (size_t i = 0; i < 4; i++) { + for (size_t i = 0; i < mir->numLanes(); i++) { Operand lane = ToOperand(ins->lane(i)); - masm.cmp32(lane, Imm32(3)); + masm.cmp32(lane, Imm32(mir->numVectors() * mir->numLanes() - 1)); masm.j(Assembler::Above, &bail); if (lane.kind() == Operand::REG) { - masm.load32(Operand(StackPointer, ToRegister(ins->lane(i)), TimesFour, Simd128DataSize), - temp); + masm.loadScalar(Operand(StackPointer, ToRegister(ins->lane(i)), TimesFour, Simd128DataSize), + tempRegister); } else { - masm.load32(lane, temp); - masm.load32(Operand(StackPointer, temp, TimesFour, Simd128DataSize), temp); + masm.load32(lane, laneTemp); + masm.loadScalar(Operand(StackPointer, laneTemp, TimesFour, Simd128DataSize), tempRegister); } - masm.store32(temp, Address(StackPointer, i * sizeof(int32_t))); + masm.storeScalar(tempRegister, Address(StackPointer, i * sizeof(T))); } FloatRegister output = ToFloatRegister(ins->output()); - masm.loadAlignedInt32x4(Address(StackPointer, 0), output); + masm.loadAlignedVector(Address(StackPointer, 0), output); Label join; masm.jump(&join); { masm.bind(&bail); - masm.freeStack(Simd128DataSize * 2); + masm.freeStack(Simd128DataSize * numVectors); bailout(ins->snapshot()); } masm.bind(&join); - masm.setFramePushed(masm.framePushed() + Simd128DataSize * 2); - masm.freeStack(Simd128DataSize * 2); + masm.setFramePushed(masm.framePushed() + Simd128DataSize * numVectors); + masm.freeStack(Simd128DataSize * numVectors); } void -CodeGeneratorX86Shared::visitSimdGeneralSwizzleF(LSimdGeneralSwizzleF *ins) +CodeGeneratorX86Shared::visitSimdGeneralShuffleI(LSimdGeneralShuffleI *ins) { - FloatRegister input = ToFloatRegister(ins->base()); - Register temp = ToRegister(ins->temp()); - - // See comment in the visitSimdGeneralSwizzleI. - masm.reserveStack(Simd128DataSize * 2); - - masm.storeAlignedFloat32x4(input, Address(StackPointer, Simd128DataSize)); - - Label bail; - - for (size_t i = 0; i < 4; i++) { - Operand lane = ToOperand(ins->lane(i)); - - masm.cmp32(lane, Imm32(3)); - masm.j(Assembler::Above, &bail); - - if (lane.kind() == Operand::REG) { - masm.loadFloat32(Operand(StackPointer, ToRegister(ins->lane(i)), TimesFour, Simd128DataSize), - ScratchFloat32Reg); - } else { - masm.load32(lane, temp); - masm.loadFloat32(Operand(StackPointer, temp, TimesFour, Simd128DataSize), ScratchFloat32Reg); - } - - masm.storeFloat32(ScratchFloat32Reg, Address(StackPointer, i * sizeof(int32_t))); - } - - FloatRegister output = ToFloatRegister(ins->output()); - masm.loadAlignedFloat32x4(Address(StackPointer, 0), output); - - Label join; - masm.jump(&join); - - { - masm.bind(&bail); - masm.freeStack(Simd128DataSize * 2); - bailout(ins->snapshot()); - } - - masm.bind(&join); - masm.setFramePushed(masm.framePushed() + Simd128DataSize * 2); - masm.freeStack(Simd128DataSize * 2); + visitSimdGeneralShuffle(ins, ToRegister(ins->temp())); +} +void +CodeGeneratorX86Shared::visitSimdGeneralShuffleF(LSimdGeneralShuffleF *ins) +{ + visitSimdGeneralShuffle(ins, ScratchFloat32Reg); } void diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.h b/js/src/jit/shared/CodeGenerator-x86-shared.h index 9b13ae7dece..2af60463ebf 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.h +++ b/js/src/jit/shared/CodeGenerator-x86-shared.h @@ -258,8 +258,6 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared void visitSimdInsertElementI(LSimdInsertElementI *lir); void visitSimdInsertElementF(LSimdInsertElementF *lir); void visitSimdSignMaskX4(LSimdSignMaskX4 *ins); - void visitSimdGeneralSwizzleI(LSimdGeneralSwizzleI *lir); - void visitSimdGeneralSwizzleF(LSimdGeneralSwizzleF *lir); void visitSimdSwizzleI(LSimdSwizzleI *lir); void visitSimdSwizzleF(LSimdSwizzleF *lir); void visitSimdShuffle(LSimdShuffle *lir); @@ -273,6 +271,10 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared void visitSimdShift(LSimdShift *lir); void visitSimdSelect(LSimdSelect *ins); + template void visitSimdGeneralShuffle(LSimdGeneralShuffleBase *lir, Reg temp); + void visitSimdGeneralShuffleI(LSimdGeneralShuffleI *lir); + void visitSimdGeneralShuffleF(LSimdGeneralShuffleF *lir); + // Out of line visitors. void visitOutOfLineBailout(OutOfLineBailout *ool); void visitOutOfLineUndoALUOperation(OutOfLineUndoALUOperation *ool); diff --git a/js/src/jit/shared/Lowering-shared-inl.h b/js/src/jit/shared/Lowering-shared-inl.h index 95c55d4f16c..76cdeb6aa3f 100644 --- a/js/src/jit/shared/Lowering-shared-inl.h +++ b/js/src/jit/shared/Lowering-shared-inl.h @@ -35,8 +35,17 @@ LIRGeneratorShared::use(MDefinition *mir, LUse policy) return policy; } -template void -LIRGeneratorShared::define(LInstructionHelper<1, X, Y> *lir, MDefinition *mir, const LDefinition &def) +template void +LIRGeneratorShared::define(details::LInstructionFixedDefsTempsHelper<1, X> *lir, MDefinition *mir, + LDefinition::Policy policy) +{ + LDefinition::Type type = LDefinition::TypeFrom(mir->type()); + define(lir, mir, LDefinition(type, policy)); +} + +template void +LIRGeneratorShared::define(details::LInstructionFixedDefsTempsHelper<1, X> *lir, MDefinition *mir, + const LDefinition &def) { // Call instructions should use defineReturn. MOZ_ASSERT(!lir->isCall()); @@ -52,13 +61,6 @@ LIRGeneratorShared::define(LInstructionHelper<1, X, Y> *lir, MDefinition *mir, c add(lir); } -template void -LIRGeneratorShared::define(LInstructionHelper<1, X, Y> *lir, MDefinition *mir, LDefinition::Policy policy) -{ - LDefinition::Type type = LDefinition::TypeFrom(mir->type()); - define(lir, mir, LDefinition(type, policy)); -} - template void LIRGeneratorShared::defineFixed(LInstructionHelper<1, X, Y> *lir, MDefinition *mir, const LAllocation &output) { diff --git a/js/src/jit/shared/Lowering-shared.h b/js/src/jit/shared/Lowering-shared.h index d002175c90f..b9ca3f1e953 100644 --- a/js/src/jit/shared/Lowering-shared.h +++ b/js/src/jit/shared/Lowering-shared.h @@ -145,13 +145,12 @@ class LIRGeneratorShared : public MDefinitionVisitor inline void defineReturn(LInstruction *lir, MDefinition *mir); - template - inline void define(LInstructionHelper<1, Ops, Temps> *lir, MDefinition *mir, - const LDefinition &def); - - template - inline void define(LInstructionHelper<1, Ops, Temps> *lir, MDefinition *mir, + template + inline void define(details::LInstructionFixedDefsTempsHelper<1, X> *lir, MDefinition *mir, LDefinition::Policy policy = LDefinition::REGISTER); + template + inline void define(details::LInstructionFixedDefsTempsHelper<1, X> *lir, MDefinition *mir, + const LDefinition &def); template inline void defineReuseInput(LInstructionHelper<1, Ops, Temps> *lir, MDefinition *mir, uint32_t operand); diff --git a/js/src/jit/shared/MacroAssembler-x86-shared.h b/js/src/jit/shared/MacroAssembler-x86-shared.h index cf46881ed47..da5d4f2bc4d 100644 --- a/js/src/jit/shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/shared/MacroAssembler-x86-shared.h @@ -974,6 +974,40 @@ class MacroAssemblerX86Shared : public Assembler vpxor(dest, dest, dest); } + template inline void loadScalar(const Operand &src, Reg dest); + template inline void storeScalar(Reg src, const Address &dest); + template inline void loadAlignedVector(const Address &src, FloatRegister dest); + template inline void storeAlignedVector(FloatRegister src, const Address &dest); + + void loadInt32x1(const Address &src, FloatRegister dest) { + vmovd(Operand(src), dest); + } + void loadInt32x1(const BaseIndex &src, FloatRegister dest) { + vmovd(Operand(src), dest); + } + void loadInt32x2(const Address &src, FloatRegister dest) { + vmovq(Operand(src), dest); + } + void loadInt32x2(const BaseIndex &src, FloatRegister dest) { + vmovq(Operand(src), dest); + } + void loadInt32x3(const BaseIndex &src, FloatRegister dest) { + BaseIndex srcZ(src); + srcZ.offset += 2 * sizeof(int32_t); + + vmovq(Operand(src), dest); + vmovd(Operand(srcZ), ScratchSimdReg); + vmovlhps(ScratchSimdReg, dest, dest); + } + void loadInt32x3(const Address &src, FloatRegister dest) { + Address srcZ(src); + srcZ.offset += 2 * sizeof(int32_t); + + vmovq(Operand(src), dest); + vmovd(Operand(srcZ), ScratchSimdReg); + vmovlhps(ScratchSimdReg, dest, dest); + } + void loadAlignedInt32x4(const Address &src, FloatRegister dest) { vmovdqa(Operand(src), dest); } @@ -1007,6 +1041,34 @@ class MacroAssemblerX86Shared : public Assembler void loadUnalignedInt32x4(const Operand &src, FloatRegister dest) { vmovdqu(src, dest); } + + void storeInt32x1(FloatRegister src, const Address &dest) { + vmovd(src, Operand(dest)); + } + void storeInt32x1(FloatRegister src, const BaseIndex &dest) { + vmovd(src, Operand(dest)); + } + void storeInt32x2(FloatRegister src, const Address &dest) { + vmovq(src, Operand(dest)); + } + void storeInt32x2(FloatRegister src, const BaseIndex &dest) { + vmovq(src, Operand(dest)); + } + void storeInt32x3(FloatRegister src, const Address &dest) { + Address destZ(dest); + destZ.offset += 2 * sizeof(int32_t); + vmovq(src, Operand(dest)); + vmovhlps(src, ScratchSimdReg, ScratchSimdReg); + vmovd(ScratchSimdReg, Operand(destZ)); + } + void storeInt32x3(FloatRegister src, const BaseIndex &dest) { + BaseIndex destZ(dest); + destZ.offset += 2 * sizeof(int32_t); + vmovq(src, Operand(dest)); + vmovhlps(src, ScratchSimdReg, ScratchSimdReg); + vmovd(ScratchSimdReg, Operand(destZ)); + } + void storeUnalignedInt32x4(FloatRegister src, const Address &dest) { vmovdqu(src, Operand(dest)); } @@ -1061,12 +1123,42 @@ class MacroAssemblerX86Shared : public Assembler vpsrld(count, dest, dest); } + void loadFloat32x3(const Address &src, FloatRegister dest) { + Address srcZ(src); + srcZ.offset += 2 * sizeof(float); + vmovsd(src, dest); + vmovss(srcZ, ScratchSimdReg); + vmovlhps(ScratchSimdReg, dest, dest); + } + void loadFloat32x3(const BaseIndex &src, FloatRegister dest) { + BaseIndex srcZ(src); + srcZ.offset += 2 * sizeof(float); + vmovsd(src, dest); + vmovss(srcZ, ScratchSimdReg); + vmovlhps(ScratchSimdReg, dest, dest); + } + void loadAlignedFloat32x4(const Address &src, FloatRegister dest) { vmovaps(Operand(src), dest); } void loadAlignedFloat32x4(const Operand &src, FloatRegister dest) { vmovaps(src, dest); } + + void storeFloat32x3(FloatRegister src, const Address &dest) { + Address destZ(dest); + destZ.offset += 2 * sizeof(int32_t); + storeDouble(src, dest); + vmovhlps(src, ScratchSimdReg, ScratchSimdReg); + storeFloat32(ScratchSimdReg, destZ); + } + void storeFloat32x3(FloatRegister src, const BaseIndex &dest) { + BaseIndex destZ(dest); + destZ.offset += 2 * sizeof(int32_t); + storeDouble(src, dest); + vmovhlps(src, ScratchSimdReg, ScratchSimdReg); + storeFloat32(ScratchSimdReg, destZ); + } void storeAlignedFloat32x4(FloatRegister src, const Address &dest) { vmovaps(src, Operand(dest)); } @@ -1412,6 +1504,42 @@ class MacroAssemblerX86Shared : public Assembler bool buildOOLFakeExitFrame(void *fakeReturnAddr); }; +template <> inline void +MacroAssemblerX86Shared::loadAlignedVector(const Address &src, FloatRegister dest) { + loadAlignedInt32x4(src, dest); +} +template <> inline void +MacroAssemblerX86Shared::loadAlignedVector(const Address &src, FloatRegister dest) { + loadAlignedFloat32x4(src, dest); +} + +template <> inline void +MacroAssemblerX86Shared::storeAlignedVector(FloatRegister src, const Address &dest) { + storeAlignedInt32x4(src, dest); +} +template <> inline void +MacroAssemblerX86Shared::storeAlignedVector(FloatRegister src, const Address &dest) { + storeAlignedFloat32x4(src, dest); +} + +template <> inline void +MacroAssemblerX86Shared::loadScalar(const Operand &src, Register dest) { + load32(src, dest); +} +template <> inline void +MacroAssemblerX86Shared::loadScalar(const Operand &src, FloatRegister dest) { + loadFloat32(src, dest); +} + +template <> inline void +MacroAssemblerX86Shared::storeScalar(Register src, const Address &dest) { + store32(src, dest); +} +template <> inline void +MacroAssemblerX86Shared::storeScalar(FloatRegister src, const Address &dest) { + storeFloat32(src, dest); +} + } // namespace jit } // namespace js diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 10f13485af8..e1809307419 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -3956,7 +3956,7 @@ JS_GetFunctionScript(JSContext *cx, HandleFunction fun) * enclosingDynamicScope is a dynamic scope to use, if it's not the global. */ static bool -CompileFunction(JSContext *cx, const ReadOnlyCompileOptions &options, +CompileFunction(JSContext *cx, const ReadOnlyCompileOptions &optionsArg, const char *name, unsigned nargs, const char *const *argnames, SourceBufferHolder &srcBuf, HandleObject enclosingDynamicScope, @@ -3990,6 +3990,13 @@ CompileFunction(JSContext *cx, const ReadOnlyCompileOptions &options, if (!fun) return false; + // Make sure to handle cases when we have a polluted scopechain. + OwningCompileOptions options(cx); + if (!options.copy(cx, optionsArg)) + return false; + if (!enclosingDynamicScope->is()) + options.setHasPollutedScope(true); + if (!frontend::CompileFunctionBody(cx, fun, options, formals, srcBuf, enclosingStaticScope)) return false; @@ -4087,6 +4094,13 @@ ExecuteScript(JSContext *cx, HandleObject obj, HandleScript scriptArg, jsval *rv AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, obj, scriptArg); + + if (!script->hasPollutedGlobalScope() && !obj->is()) { + script = CloneScript(cx, NullPtr(), NullPtr(), script, HasPollutedGlobalScope); + if (!script) + return false; + js::Debugger::onNewScript(cx, script); + } AutoLastFrameCheck lfc(cx); return Execute(cx, script, *obj, rval); } @@ -4127,10 +4141,9 @@ JS_ExecuteScript(JSContext *cx, AutoObjectVector &scopeChain, HandleScript scrip } JS_PUBLIC_API(bool) -JS::CloneAndExecuteScript(JSContext *cx, HandleObject obj, HandleScript scriptArg) +JS::CloneAndExecuteScript(JSContext *cx, HandleScript scriptArg) { CHECK_REQUEST(cx); - assertSameCompartment(cx, obj); RootedScript script(cx, scriptArg); if (script->compartment() != cx->compartment()) { script = CloneScript(cx, NullPtr(), NullPtr(), script); @@ -4139,7 +4152,7 @@ JS::CloneAndExecuteScript(JSContext *cx, HandleObject obj, HandleScript scriptAr js::Debugger::onNewScript(cx, script); } - return ExecuteScript(cx, obj, script, nullptr); + return ExecuteScript(cx, cx->global(), script, nullptr); } static const unsigned LARGE_SCRIPT_LENGTH = 500*1024; @@ -4157,6 +4170,7 @@ Evaluate(JSContext *cx, HandleObject scope, const ReadOnlyCompileOptions &option AutoLastFrameCheck lfc(cx); options.setCompileAndGo(scope->is()); + options.setHasPollutedScope(!scope->is()); SourceCompressionTask sct(cx); RootedScript script(cx, frontend::CompileScript(cx, &cx->tempLifoAlloc(), scope, NullPtr(), NullPtr(), options, diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 417cda4156a..9d6660b4d94 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -1488,8 +1488,7 @@ typedef void (*JSIterateCompartmentCallback)(JSRuntime *rt, void *data, JSCompar /* * This function calls |compartmentCallback| on every compartment. Beware that * there is no guarantee that the compartment will survive after the callback - * returns. Also, if the callback can GC, there is no guarantee that every - * compartment will be visited. + * returns. */ extern JS_PUBLIC_API(void) JS_IterateCompartments(JSRuntime *rt, void *data, @@ -3347,6 +3346,7 @@ class JS_FRIEND_API(ReadOnlyCompileOptions) lineno(1), column(0), compileAndGo(false), + hasPollutedGlobalScope(false), forEval(false), noScriptRval(false), selfHostingMode(false), @@ -3386,6 +3386,7 @@ class JS_FRIEND_API(ReadOnlyCompileOptions) unsigned lineno; unsigned column; bool compileAndGo; + bool hasPollutedGlobalScope; bool forEval; bool noScriptRval; bool selfHostingMode; @@ -3477,6 +3478,7 @@ class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions OwningCompileOptions &setUTF8(bool u) { utf8 = u; return *this; } OwningCompileOptions &setColumn(unsigned c) { column = c; return *this; } OwningCompileOptions &setCompileAndGo(bool cng) { compileAndGo = cng; return *this; } + OwningCompileOptions &setHasPollutedScope(bool p) { hasPollutedGlobalScope = p; return *this; } OwningCompileOptions &setForEval(bool eval) { forEval = eval; return *this; } OwningCompileOptions &setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; } OwningCompileOptions &setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; } @@ -3560,6 +3562,7 @@ class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) : public ReadOnlyCompileOpti CompileOptions &setUTF8(bool u) { utf8 = u; return *this; } CompileOptions &setColumn(unsigned c) { column = c; return *this; } CompileOptions &setCompileAndGo(bool cng) { compileAndGo = cng; return *this; } + CompileOptions &setHasPollutedScope(bool p) { hasPollutedGlobalScope = p; return *this; } CompileOptions &setForEval(bool eval) { forEval = eval; return *this; } CompileOptions &setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; } CompileOptions &setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; } @@ -3745,7 +3748,7 @@ namespace JS { * cross-compartment, it is cloned into the current compartment before executing. */ extern JS_PUBLIC_API(bool) -CloneAndExecuteScript(JSContext *cx, JS::Handle obj, JS::Handle script); +CloneAndExecuteScript(JSContext *cx, JS::Handle script); } /* namespace JS */ diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 6fe1258d069..7e3903767bc 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -549,9 +549,9 @@ JS_GetCustomIteratorCount(JSContext *cx) } JS_FRIEND_API(unsigned) -JS_PCToLineNumber(JSScript *script, jsbytecode *pc) +JS_PCToLineNumber(JSScript *script, jsbytecode *pc, unsigned *columnp) { - return PCToLineNumber(script, pc); + return PCToLineNumber(script, pc, columnp); } JS_FRIEND_API(bool) diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 49dd91ed1af..ac5062f2cef 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -80,7 +80,7 @@ JS_NondeterministicGetWeakMapKeys(JSContext *cx, JS::HandleObject obj, JS::Mutab // Raw JSScript* because this needs to be callable from a signal handler. extern JS_FRIEND_API(unsigned) -JS_PCToLineNumber(JSScript *script, jsbytecode *pc); +JS_PCToLineNumber(JSScript *script, jsbytecode *pc, unsigned *columnp = nullptr); /* * Determine whether the given object is backed by a DeadObjectProxy. diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index cae167faa9c..6eb12b6dc28 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -2081,11 +2081,33 @@ js::NewFunctionWithProto(ExclusiveContext *cx, Native native, } bool -js::CloneFunctionObjectUseSameScript(JSCompartment *compartment, HandleFunction fun) +js::CloneFunctionObjectUseSameScript(JSCompartment *compartment, HandleFunction fun, + HandleObject newParent) { - return compartment == fun->compartment() && - !fun->isSingleton() && - !ObjectGroup::useSingletonForClone(fun); + if (compartment != fun->compartment() || + fun->isSingleton() || + ObjectGroup::useSingletonForClone(fun)) + { + return false; + } + + if (newParent->is()) + return true; + + // Don't need to clone the script if newParent is a syntactic scope, since + // in that case we have some actual scope objects on our scope chain and + // whatnot; whoever put them there should be responsible for setting our + // script's flags appropriately. We hit this case for JSOP_LAMBDA, for + // example. + if (IsSyntacticScope(newParent)) + return true; + + // We need to clone the script if we're interpreted and not already marked + // as having a polluted scope. If we're lazy, go ahead and clone the + // script; see the big comment at the end of CloneScript for the explanation + // of what's going on there. + return !fun->isInterpreted() || + (fun->hasScript() && fun->nonLazyScript()->hasPollutedGlobalScope()); } JSFunction * @@ -2097,7 +2119,7 @@ js::CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent, MOZ_ASSERT(parent); MOZ_ASSERT(!fun->isBoundFunction()); - bool useSameScript = CloneFunctionObjectUseSameScript(cx->compartment(), fun); + bool useSameScript = CloneFunctionObjectUseSameScript(cx->compartment(), fun, parent); if (!useSameScript && fun->isInterpretedLazy()) { JSAutoCompartment ac(cx, fun); @@ -2176,13 +2198,19 @@ js::CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent, RootedFunction cloneRoot(cx, clone); /* - * Across compartments we have to clone the script for interpreted - * functions. Cross-compartment cloning only happens via JSAPI - * (JS::CloneFunctionObject) which dynamically ensures that 'script' has - * no enclosing lexical scope (only the global scope). + * Across compartments or if we have to introduce a polluted scope we have + * to clone the script for interpreted functions. Cross-compartment cloning + * only happens via JSAPI (JS::CloneFunctionObject) which dynamically + * ensures that 'script' has no enclosing lexical scope (only the global + * scope or other non-lexical scope). */ - if (cloneRoot->isInterpreted() && !CloneFunctionScript(cx, fun, cloneRoot, newKindArg)) + PollutedGlobalScopeOption globalScopeOption = parent->is() ? + HasCleanGlobalScope : HasPollutedGlobalScope; + if (cloneRoot->isInterpreted() && + !CloneFunctionScript(cx, fun, cloneRoot, globalScopeOption, newKindArg)) + { return nullptr; + } return cloneRoot; } diff --git a/js/src/jsfun.h b/js/src/jsfun.h index f5a8e93a678..e288157ca3c 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -584,7 +584,8 @@ class FunctionExtended : public JSFunction }; extern bool -CloneFunctionObjectUseSameScript(JSCompartment *compartment, HandleFunction fun); +CloneFunctionObjectUseSameScript(JSCompartment *compartment, HandleFunction fun, + HandleObject newParent); extern JSFunction * CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent, diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 486a9dd0e78..ab2c207a347 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1060,6 +1060,7 @@ GCRuntime::GCRuntime(JSRuntime *rt) : nextFullGCTime(0), lastGCTime(PRMJ_Now()), mode(JSGC_MODE_INCREMENTAL), + numActiveZoneIters(0), decommitThreshold(32 * 1024 * 1024), cleanUpEverything(false), grayBufferState(GCRuntime::GrayBufferState::Unused), @@ -3490,7 +3491,7 @@ GCRuntime::shouldReleaseObservedTypes() * arbitrary compartment in the zone. */ void -Zone::sweepCompartments(FreeOp *fop, bool keepAtleastOne, bool lastGC) +Zone::sweepCompartments(FreeOp *fop, bool keepAtleastOne, bool destroyingRuntime) { JSRuntime *rt = runtimeFromMainThread(); JSDestroyCompartmentCallback callback = rt->destroyCompartmentCallback; @@ -3508,7 +3509,7 @@ Zone::sweepCompartments(FreeOp *fop, bool keepAtleastOne, bool lastGC) * deleted and keepAtleastOne is true. */ bool dontDelete = read == end && !foundOne && keepAtleastOne; - if ((!comp->marked && !dontDelete) || lastGC) { + if ((!comp->marked && !dontDelete) || destroyingRuntime) { if (callback) callback(fop, comp); if (comp->principals) @@ -3524,8 +3525,12 @@ Zone::sweepCompartments(FreeOp *fop, bool keepAtleastOne, bool lastGC) } void -GCRuntime::sweepZones(FreeOp *fop, bool lastGC) +GCRuntime::sweepZones(FreeOp *fop, bool destroyingRuntime) { + MOZ_ASSERT_IF(destroyingRuntime, rt->gc.numActiveZoneIters == 0); + if (rt->gc.numActiveZoneIters) + return; + AutoLockGC lock(rt); // Avoid race with background sweeping. JSZoneCallback callback = rt->destroyZoneCallback; @@ -3543,19 +3548,19 @@ GCRuntime::sweepZones(FreeOp *fop, bool lastGC) if (zone->wasGCStarted()) { if ((!zone->isQueuedForBackgroundSweep() && zone->arenas.arenaListsAreEmpty() && - !zone->hasMarkedCompartments()) || lastGC) + !zone->hasMarkedCompartments()) || destroyingRuntime) { zone->arenas.checkEmptyFreeLists(); AutoUnlockGC unlock(lock); if (callback) callback(zone); - zone->sweepCompartments(fop, false, lastGC); + zone->sweepCompartments(fop, false, destroyingRuntime); MOZ_ASSERT(zone->compartments.empty()); fop->delete_(zone); continue; } - zone->sweepCompartments(fop, true, lastGC); + zone->sweepCompartments(fop, true, destroyingRuntime); } *write++ = zone; } @@ -4969,7 +4974,7 @@ GCRuntime::endSweepingZoneGroup() } void -GCRuntime::beginSweepPhase(bool lastGC) +GCRuntime::beginSweepPhase(bool destroyingRuntime) { /* * Sweep phase. @@ -4988,7 +4993,7 @@ GCRuntime::beginSweepPhase(bool lastGC) gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP); sweepOnBackgroundThread = - !lastGC && !TraceEnabled() && CanUseExtraThreads(); + !destroyingRuntime && !TraceEnabled() && CanUseExtraThreads(); releaseObservedTypes = shouldReleaseObservedTypes(); @@ -5186,12 +5191,12 @@ GCRuntime::sweepPhase(SliceBudget &sliceBudget) } void -GCRuntime::endSweepPhase(bool lastGC) +GCRuntime::endSweepPhase(bool destroyingRuntime) { gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP); FreeOp fop(rt); - MOZ_ASSERT_IF(lastGC, !sweepOnBackgroundThread); + MOZ_ASSERT_IF(destroyingRuntime, !sweepOnBackgroundThread); /* * Recalculate whether GC was full or not as this may have changed due to @@ -5239,8 +5244,8 @@ GCRuntime::endSweepPhase(bool lastGC) * This removes compartments from rt->compartment, so we do it last to make * sure we don't miss sweeping any compartments. */ - if (!lastGC) - sweepZones(&fop, lastGC); + if (!destroyingRuntime) + sweepZones(&fop, destroyingRuntime); } { @@ -5270,8 +5275,8 @@ GCRuntime::endSweepPhase(bool lastGC) } /* Ensure the compartments get swept if it's the last GC. */ - if (lastGC) - sweepZones(&fop, lastGC); + if (destroyingRuntime) + sweepZones(&fop, destroyingRuntime); } finishMarkingValidation(); @@ -5669,7 +5674,7 @@ GCRuntime::incrementalCollectSlice(SliceBudget &budget, JS::gcreason::Reason rea AutoCopyFreeListToArenasForGC copy(rt); AutoGCSlice slice(rt); - bool lastGC = (reason == JS::gcreason::DESTROY_RUNTIME); + bool destroyingRuntime = (reason == JS::gcreason::DESTROY_RUNTIME); gc::State initialState = incrementalState; @@ -5711,7 +5716,7 @@ GCRuntime::incrementalCollectSlice(SliceBudget &budget, JS::gcreason::Reason rea return; } - if (!lastGC) + if (!destroyingRuntime) pushZealSelectedObjects(); incrementalState = MARK; @@ -5754,7 +5759,7 @@ GCRuntime::incrementalCollectSlice(SliceBudget &budget, JS::gcreason::Reason rea * This runs to completion, but we don't continue if the budget is * now exhasted. */ - beginSweepPhase(lastGC); + beginSweepPhase(destroyingRuntime); if (budget.isOverBudget()) break; @@ -5771,7 +5776,7 @@ GCRuntime::incrementalCollectSlice(SliceBudget &budget, JS::gcreason::Reason rea if (sweepPhase(budget) == NotFinished) break; - endSweepPhase(lastGC); + endSweepPhase(destroyingRuntime); incrementalState = COMPACT; MOZ_ASSERT(!startedCompacting); diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 8f8db89c6cd..d348f62ce76 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -1322,7 +1322,7 @@ MaybeVerifyBarriers(JSContext *cx, bool always = false) /* * Instances of this class set the |JSRuntime::suppressGC| flag for the duration * that they are live. Use of this class is highly discouraged. Please carefully - * read the comment in jscntxt.h above |suppressGC| and take all appropriate + * read the comment in vm/Runtime.h above |suppressGC| and take all appropriate * precautions before instantiating this class. */ class AutoSuppressGC diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 725b6972e20..7f762c2181d 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -2151,7 +2151,7 @@ js::CloneObjectLiteral(JSContext *cx, HandleObject srcObj) value = srcArray->getDenseElement(i); MOZ_ASSERT_IF(value.isMarkable(), value.toGCThing()->isTenured() && - cx->runtime()->isAtomsZone(value.toGCThing()->asTenured().zone())); + cx->runtime()->isAtomsZone(value.toGCThing()->asTenured().zoneFromAnyThread())); id = INT_TO_JSID(i); if (!DefineProperty(cx, res, id, value, nullptr, nullptr, JSPROP_ENUMERATE)) diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 85f93d7ff48..6b3eb7fe315 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -576,7 +576,8 @@ js::XDRScript(XDRState *xdr, HandleObject enclosingScope, HandleScript enc IsCompileAndGo, HasSingleton, TreatAsRunOnce, - HasLazyScript + HasLazyScript, + HasPollutedGlobalScope, }; uint32_t length, lineno, column, nslots, staticLevel; @@ -694,6 +695,8 @@ js::XDRScript(XDRState *xdr, HandleObject enclosingScope, HandleScript enc scriptBits |= (1 << TreatAsRunOnce); if (script->isRelazifiable()) scriptBits |= (1 << HasLazyScript); + if (script->hasPollutedGlobalScope()) + scriptBits |= (1 << HasPollutedGlobalScope); } if (!xdr->codeUint32(&prologLength)) @@ -811,6 +814,8 @@ js::XDRScript(XDRState *xdr, HandleObject enclosingScope, HandleScript enc script->hasSingletons_ = true; if (scriptBits & (1 << TreatAsRunOnce)) script->treatAsRunOnce_ = true; + if (scriptBits & (1 << HasPollutedGlobalScope)) + script->hasPollutedGlobalScope_ = true; if (scriptBits & (1 << IsLegacyGenerator)) { MOZ_ASSERT(!(scriptBits & (1 << IsStarGenerator))); @@ -2392,6 +2397,7 @@ JSScript::Create(ExclusiveContext *cx, HandleObject enclosingScope, bool savedCa script->initCompartment(cx); script->compileAndGo_ = options.compileAndGo; + script->hasPollutedGlobalScope_ = options.hasPollutedGlobalScope; script->selfHosted_ = options.selfHostingMode; script->noScriptRval_ = options.noScriptRval; @@ -2953,6 +2959,7 @@ Rebase(JSScript *dst, JSScript *src, T *srcp) JSScript * js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, HandleScript src, + PollutedGlobalScopeOption polluted /* = HasCleanGlobalScope */, NewObjectKind newKind /* = GenericObject */) { /* NB: Keep this in sync with XDRScript. */ @@ -3002,7 +3009,11 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, } else if (obj->is()) { RootedFunction innerFun(cx, &obj->as()); if (innerFun->isNative()) { - assertSameCompartment(cx, innerFun); + if (cx->compartment() != innerFun->compartment()) { + MOZ_ASSERT(innerFun->isAsmJSNative()); + JS_ReportError(cx, "AsmJS modules do not yet support cloning."); + return nullptr; + } clone = innerFun; } else { if (innerFun->isInterpretedLazy()) { @@ -3076,6 +3087,8 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, CompileOptions options(cx); options.setMutedErrors(src->mutedErrors()) .setCompileAndGo(src->compileAndGo()) + .setHasPollutedScope(src->hasPollutedGlobalScope() || + polluted == HasPollutedGlobalScope) .setSelfHostingMode(src->selfHosted()) .setNoScriptRval(src->noScriptRval()) .setVersion(src->getVersion()); @@ -3146,12 +3159,29 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, if (nblockscopes != 0) dst->blockScopes()->vector = Rebase(dst, src, src->blockScopes()->vector); + /* + * Function delazification assumes that their script does not have a + * polluted global scope. We ensure that as follows: + * + * 1) Initial parsing only creates lazy functions if + * !hasPollutedGlobalScope. + * 2) Cloning a lazy function into a non-global scope will always require + * that its script be cloned. See comments in + * CloneFunctionObjectUseSameScript. + * 3) Cloning a script never sets a lazyScript on the clone, so the function + * cannot be relazified. + * + * If you decide that lazy functions should be supported with a polluted + * global scope, make sure delazification can deal. + */ + MOZ_ASSERT_IF(dst->hasPollutedGlobalScope(), !dst->maybeLazyScript()); + MOZ_ASSERT_IF(dst->hasPollutedGlobalScope(), !dst->isRelazifiable()); return dst; } bool js::CloneFunctionScript(JSContext *cx, HandleFunction original, HandleFunction clone, - NewObjectKind newKind /* = GenericObject */) + PollutedGlobalScopeOption polluted, NewObjectKind newKind) { MOZ_ASSERT(clone->isInterpreted()); @@ -3173,7 +3203,7 @@ js::CloneFunctionScript(JSContext *cx, HandleFunction original, HandleFunction c clone->mutableScript().init(nullptr); - JSScript *cscript = CloneScript(cx, scope, clone, script, newKind); + JSScript *cscript = CloneScript(cx, scope, clone, script, polluted, newKind); if (!cscript) return false; diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 019b9a28658..dd08f7adc84 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -748,8 +748,14 @@ bool XDRScript(XDRState *xdr, HandleObject enclosingScope, HandleScript enclosingScript, HandleFunction fun, MutableHandleScript scriptp); +enum PollutedGlobalScopeOption { + HasPollutedGlobalScope, + HasCleanGlobalScope +}; + JSScript * CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, HandleScript script, + PollutedGlobalScopeOption polluted = HasCleanGlobalScope, NewObjectKind newKind = GenericObject); template @@ -775,7 +781,8 @@ class JSScript : public js::gc::TenuredCell js::HandleFunction fun, js::MutableHandleScript scriptp); friend JSScript * - js::CloneScript(JSContext *cx, js::HandleObject enclosingScope, js::HandleFunction fun, js::HandleScript src, + js::CloneScript(JSContext *cx, js::HandleObject enclosingScope, js::HandleFunction fun, + js::HandleScript src, js::PollutedGlobalScopeOption polluted, js::NewObjectKind newKind); public: @@ -918,6 +925,11 @@ class JSScript : public js::gc::TenuredCell // See Parser::compileAndGo. bool compileAndGo_:1; + // True if the script has a non-syntactic scope on its dynamic scope chain. + // That is, there are objects about which we know nothing between the + // outermost syntactic scope and the global. + bool hasPollutedGlobalScope_:1; + // see Parser::selfHostingMode. bool selfHosted_:1; @@ -965,6 +977,9 @@ class JSScript : public js::gc::TenuredCell // Idempotent cache has triggered invalidation. bool invalidatedIdempotentCache_:1; + // Lexical check did fail and bail out. + bool failedLexicalCheck_:1; + // If the generator was created implicitly via a generator expression, // isGeneratorExp will be true. bool isGeneratorExp_:1; @@ -1143,6 +1158,10 @@ class JSScript : public js::gc::TenuredCell return compileAndGo_; } + bool hasPollutedGlobalScope() const { + return hasPollutedGlobalScope_; + } + bool selfHosted() const { return selfHosted_; } bool bindingsAccessedDynamically() const { return bindingsAccessedDynamically_; } bool funHasExtensibleScope() const { @@ -1207,12 +1226,16 @@ class JSScript : public js::gc::TenuredCell bool invalidatedIdempotentCache() const { return invalidatedIdempotentCache_; } + bool failedLexicalCheck() const { + return failedLexicalCheck_; + } void setFailedBoundsCheck() { failedBoundsCheck_ = true; } void setFailedShapeGuard() { failedShapeGuard_ = true; } void setHadFrequentBailouts() { hadFrequentBailouts_ = true; } void setUninlineable() { uninlineable_ = true; } void setInvalidatedIdempotentCache() { invalidatedIdempotentCache_ = true; } + void setFailedLexicalCheck() { failedLexicalCheck_ = true; } bool hasScriptCounts() const { return hasScriptCounts_; } @@ -2159,7 +2182,7 @@ DescribeScriptedCallerForCompilation(JSContext *cx, MutableHandleScript maybeScr bool CloneFunctionScript(JSContext *cx, HandleFunction original, HandleFunction clone, - NewObjectKind newKind = GenericObject); + PollutedGlobalScopeOption polluted, NewObjectKind newKind); } /* namespace js */ diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index ea4e1408075..49108401a58 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -765,7 +765,7 @@ Debugger::wrapEnvironment(JSContext *cx, Handle env, MutableHandleValue rv * DebuggerEnv should only wrap a debug scope chain obtained (transitively) * from GetDebugScopeFor(Frame|Function). */ - MOZ_ASSERT(IsValidTerminatingScope(env)); + MOZ_ASSERT(!IsSyntacticScope(env)); NativeObject *envobj; DependentAddPtr p(cx, environments, env); @@ -6142,6 +6142,7 @@ EvaluateInEnv(JSContext *cx, Handle env, HandleValue thisv, AbstractFrameP return false; CompileOptions options(cx); options.setCompileAndGo(true) + .setHasPollutedScope(true) .setForEval(true) .setNoScriptRval(false) .setFileAndLine(filename, lineno) @@ -7363,7 +7364,7 @@ DebuggerEnv_checkThis(JSContext *cx, const CallArgs &args, const char *fnname, return false; \ Rooted env(cx, static_cast(envobj->getPrivate())); \ MOZ_ASSERT(env); \ - MOZ_ASSERT(IsValidTerminatingScope(env)); + MOZ_ASSERT(!IsSyntacticScope(env)); #define THIS_DEBUGENV_OWNER(cx, argc, vp, fnname, args, envobj, env, dbg) \ THIS_DEBUGENV(cx, argc, vp, fnname, args, envobj, env); \ diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 56164d8c8ce..27af7387717 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -633,13 +633,18 @@ js::ExecuteKernel(JSContext *cx, HandleScript script, JSObject &scopeChainArg, c ExecuteType type, AbstractFramePtr evalInFrame, Value *result) { MOZ_ASSERT_IF(evalInFrame, type == EXECUTE_DEBUG); - MOZ_ASSERT_IF(type == EXECUTE_GLOBAL, IsValidTerminatingScope(&scopeChainArg)); + MOZ_ASSERT_IF(type == EXECUTE_GLOBAL, !IsSyntacticScope(&scopeChainArg)); #ifdef DEBUG if (thisv.isObject()) { RootedObject thisObj(cx, &thisv.toObject()); AutoSuppressGC nogc(cx); MOZ_ASSERT(GetOuterObject(cx, thisObj) == thisObj); } + RootedObject terminatingScope(cx, &scopeChainArg); + while (IsSyntacticScope(terminatingScope)) + terminatingScope = terminatingScope->enclosingScope(); + MOZ_ASSERT(terminatingScope->is() || + script->hasPollutedGlobalScope()); #endif if (script->isEmpty()) { @@ -669,6 +674,9 @@ js::Execute(JSContext *cx, HandleScript script, JSObject &scopeChainArg, Value * MOZ_RELEASE_ASSERT(scopeChain->is() || !script->compileAndGo(), "Only non-compile-and-go scripts can be executed with " "interesting scopechains"); + MOZ_RELEASE_ASSERT(scopeChain->is() || script->hasPollutedGlobalScope(), + "Only scripts with polluted scopes can be executed with " + "interesting scopechains"); /* Ensure the scope chain is all same-compartment and terminates in a global. */ #ifdef DEBUG @@ -1664,7 +1672,6 @@ CASE(JSOP_UNUSED126) CASE(JSOP_UNUSED148) CASE(JSOP_BACKPATCH) CASE(JSOP_UNUSED150) -CASE(JSOP_UNUSED157) CASE(JSOP_UNUSED158) CASE(JSOP_UNUSED159) CASE(JSOP_UNUSED161) @@ -1761,6 +1768,7 @@ CASE(JSOP_FORCEINTERPRETER) END_CASE(JSOP_FORCEINTERPRETER) CASE(JSOP_UNDEFINED) + // If this ever changes, change what JSOP_GIMPLICITTHIS does too. PUSH_UNDEFINED(); END_CASE(JSOP_UNDEFINED) @@ -2691,21 +2699,28 @@ CASE(JSOP_SETCALL) END_CASE(JSOP_SETCALL) CASE(JSOP_IMPLICITTHIS) +CASE(JSOP_GIMPLICITTHIS) { - RootedPropertyName &name = rootName0; - name = script->getName(REGS.pc); + JSOp op = JSOp(*REGS.pc); + if (op == JSOP_IMPLICITTHIS || script->hasPollutedGlobalScope()) { + RootedPropertyName &name = rootName0; + name = script->getName(REGS.pc); - RootedObject &scopeObj = rootObject0; - scopeObj = REGS.fp()->scopeChain(); + RootedObject &scopeObj = rootObject0; + scopeObj = REGS.fp()->scopeChain(); - RootedObject &scope = rootObject1; - if (!LookupNameWithGlobalDefault(cx, name, scopeObj, &scope)) - goto error; + RootedObject &scope = rootObject1; + if (!LookupNameWithGlobalDefault(cx, name, scopeObj, &scope)) + goto error; - RootedValue &v = rootValue0; - if (!ComputeImplicitThis(cx, scope, &v)) - goto error; - PUSH_COPY(v); + RootedValue &v = rootValue0; + if (!ComputeImplicitThis(cx, scope, &v)) + goto error; + PUSH_COPY(v); + } else { + // Treat it like JSOP_UNDEFINED. + PUSH_UNDEFINED(); + } } END_CASE(JSOP_IMPLICITTHIS) diff --git a/js/src/vm/Opcodes.h b/js/src/vm/Opcodes.h index 6e88f565900..d9264fd9186 100644 --- a/js/src/vm/Opcodes.h +++ b/js/src/vm/Opcodes.h @@ -1533,7 +1533,17 @@ * Stack: scope, val => val */ \ macro(JSOP_STRICTSETGNAME, 156, "strict-setgname", NULL, 5, 2, 1, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME|JOF_CHECKSTRICT) \ - macro(JSOP_UNUSED157, 157, "unused157", NULL, 1, 0, 0, JOF_BYTE) \ + /* + * Pushes the implicit 'this' value for calls to the associated name onto + * the stack; only used when we know this implicit this will be our first + * non-syntactic scope. + * + * Category: Variables and Scopes + * Type: This + * Operands: uint32_t nameIndex + * Stack: => this + */ \ + macro(JSOP_GIMPLICITTHIS, 157, "gimplicitthis", "", 5, 0, 1, JOF_ATOM) \ macro(JSOP_UNUSED158, 158, "unused158", NULL, 1, 0, 0, JOF_BYTE) \ macro(JSOP_UNUSED159, 159, "unused159", NULL, 1, 0, 0, JOF_BYTE) \ \ diff --git a/js/src/vm/SavedStacks.cpp b/js/src/vm/SavedStacks.cpp index 1dbafd8dcca..c173e10c485 100644 --- a/js/src/vm/SavedStacks.cpp +++ b/js/src/vm/SavedStacks.cpp @@ -633,49 +633,57 @@ GetSavedFrameParent(JSContext *cx, HandleObject savedFrame, MutableHandleObject JS_PUBLIC_API(bool) StringifySavedFrameStack(JSContext *cx, HandleObject stack, MutableHandleString stringp) { - AutoMaybeEnterFrameCompartment ac(cx, stack); - bool skippedAsync; - js::RootedSavedFrame frame(cx, UnwrapSavedFrame(cx, stack, skippedAsync)); - if (!frame) { - stringp.set(cx->runtime()->emptyString); - return true; - } - js::StringBuffer sb(cx); - DebugOnly subsumes = cx->runtime()->securityCallbacks->subsumes; - DebugOnly principals = cx->compartment()->principals; - js::RootedSavedFrame parent(cx); - do { - MOZ_ASSERT_IF(subsumes, (*subsumes)(principals, frame->getPrincipals())); - - if (!frame->isSelfHosted()) { - RootedString asyncCause(cx, frame->getAsyncCause()); - if (!asyncCause && skippedAsync) { - asyncCause.set(cx->names().Async); - } - js::RootedAtom name(cx, frame->getFunctionDisplayName()); - if ((asyncCause && (!sb.append(asyncCause) || !sb.append('*'))) - || (name && !sb.append(name)) - || !sb.append('@') - || !sb.append(frame->getSource()) - || !sb.append(':') - || !NumberValueToStringBuffer(cx, NumberValue(frame->getLine()), sb) - || !sb.append(':') - || !NumberValueToStringBuffer(cx, NumberValue(frame->getColumn()), sb) - || !sb.append('\n')) - { - return false; - } + // Enter a new block to constrain the scope of possibly entering the stack's + // compartment. This ensures that when we finish the StringBuffer, we are + // back in the cx's original compartment, and fulfill our contract with + // callers to place the output string in the cx's current compartment. + { + AutoMaybeEnterFrameCompartment ac(cx, stack); + bool skippedAsync; + js::RootedSavedFrame frame(cx, UnwrapSavedFrame(cx, stack, skippedAsync)); + if (!frame) { + stringp.set(cx->runtime()->emptyString); + return true; } - parent = frame->getParent(); - frame = js::GetFirstSubsumedFrame(cx, parent, skippedAsync); - } while (frame); + DebugOnly subsumes = cx->runtime()->securityCallbacks->subsumes; + DebugOnly principals = cx->compartment()->principals; + + js::RootedSavedFrame parent(cx); + do { + MOZ_ASSERT_IF(subsumes, (*subsumes)(principals, frame->getPrincipals())); + + if (!frame->isSelfHosted()) { + RootedString asyncCause(cx, frame->getAsyncCause()); + if (!asyncCause && skippedAsync) + asyncCause.set(cx->names().Async); + + js::RootedAtom name(cx, frame->getFunctionDisplayName()); + if ((asyncCause && (!sb.append(asyncCause) || !sb.append('*'))) + || (name && !sb.append(name)) + || !sb.append('@') + || !sb.append(frame->getSource()) + || !sb.append(':') + || !NumberValueToStringBuffer(cx, NumberValue(frame->getLine()), sb) + || !sb.append(':') + || !NumberValueToStringBuffer(cx, NumberValue(frame->getColumn()), sb) + || !sb.append('\n')) + { + return false; + } + } + + parent = frame->getParent(); + frame = js::GetFirstSubsumedFrame(cx, parent, skippedAsync); + } while (frame); + } JSString *str = sb.finishString(); if (!str) return false; + assertSameCompartment(cx, str); stringp.set(str); return true; } diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index 53160c32d4b..921d11708be 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -2441,11 +2441,11 @@ static JSObject * GetDebugScopeForNonScopeObject(const ScopeIter &si) { JSObject &enclosing = si.enclosingScope(); - MOZ_ASSERT(IsValidTerminatingScope(&enclosing)); + MOZ_ASSERT(!IsSyntacticScope(&enclosing)); #ifdef DEBUG JSObject *o = &enclosing; while ((o = o->enclosingScope())) - MOZ_ASSERT(IsValidTerminatingScope(o)); + MOZ_ASSERT(!IsSyntacticScope(o)); #endif return &enclosing; } diff --git a/js/src/vm/ScopeObject.h b/js/src/vm/ScopeObject.h index 75445c63de4..34b2cb9d049 100644 --- a/js/src/vm/ScopeObject.h +++ b/js/src/vm/ScopeObject.h @@ -1034,11 +1034,11 @@ JSObject::is() const namespace js { inline bool -IsValidTerminatingScope(JSObject* scope) +IsSyntacticScope(JSObject* scope) { - return !scope->is() || - (scope->is() && - !scope->as().isSyntactic()); + return scope->is() && + (!scope->is() || + scope->as().isSyntactic()); } inline const Value & @@ -1082,7 +1082,7 @@ ScopeIter::enclosingScope() const // chain; every scope chain must start with zero or more ScopeObjects and // terminate with one or more non-ScopeObjects (viz., GlobalObject). MOZ_ASSERT(done()); - MOZ_ASSERT(IsValidTerminatingScope(scope_)); + MOZ_ASSERT(!IsSyntacticScope(scope_)); return *scope_; } diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index f50de7c1aee..3561614bb99 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -171,7 +171,7 @@ AssertDynamicScopeMatchesStaticScope(JSContext *cx, JSScript *script, JSObject * // The scope chain is always ended by one or more non-syntactic // ScopeObjects (viz. GlobalObject or a non-syntactic WithObject). - MOZ_ASSERT(IsValidTerminatingScope(scope)); + MOZ_ASSERT(!IsSyntacticScope(scope)); #endif } @@ -238,7 +238,7 @@ InterpreterFrame::epilogue(JSContext *cx) DebugScopes::onPopStrictEvalScope(this); } else if (isDirectEvalFrame()) { if (isDebuggerEvalFrame()) - MOZ_ASSERT(IsValidTerminatingScope(scopeChain())); + MOZ_ASSERT(!IsSyntacticScope(scopeChain())); } else { /* * Debugger.Object.prototype.evalInGlobal creates indirect eval @@ -258,7 +258,7 @@ InterpreterFrame::epilogue(JSContext *cx) } if (isGlobalFrame()) { - MOZ_ASSERT(IsValidTerminatingScope(scopeChain())); + MOZ_ASSERT(!IsSyntacticScope(scopeChain())); return; } @@ -1111,7 +1111,8 @@ FrameIter::matchCallee(JSContext *cx, HandleFunction fun) const // Use the same condition as |js::CloneFunctionObject|, to know if we should // expect both functions to have the same JSScript. If so, and if they are // different, then they cannot be equal. - bool useSameScript = CloneFunctionObjectUseSameScript(fun->compartment(), currentCallee); + RootedObject global(cx, &fun->global()); + bool useSameScript = CloneFunctionObjectUseSameScript(fun->compartment(), currentCallee, global); if (useSameScript && (currentCallee->hasScript() != fun->hasScript() || currentCallee->nonLazyScript() != fun->nonLazyScript())) @@ -1908,7 +1909,8 @@ JS::ProfilingFrameIterator::extractStack(Frame *frames, uint32_t offset, uint32_ // FIXMEshu: disabled until we can ensure the optimization info is live // when we write out the JSON stream of the profile. if (false && entry.hasTrackedOptimizations()) { - mozilla::Maybe index = entry.trackedOptimizationIndexAtAddr(returnAddr); + uint32_t dummy; + mozilla::Maybe index = entry.trackedOptimizationIndexAtAddr(returnAddr, &dummy); frames[offset].hasTrackedOptimizations = index.isSome(); } diff --git a/js/src/vm/TypeInference.cpp b/js/src/vm/TypeInference.cpp index 5500c6c024e..2dfdbeb1923 100644 --- a/js/src/vm/TypeInference.cpp +++ b/js/src/vm/TypeInference.cpp @@ -708,7 +708,7 @@ TypeSet::readBarrier(const TypeSet *types) } } -bool +/* static */ bool TypeSet::IsTypeMarkedFromAnyThread(TypeSet::Type *v) { bool rv; @@ -726,6 +726,22 @@ TypeSet::IsTypeMarkedFromAnyThread(TypeSet::Type *v) return rv; } +/* static */ bool +TypeSet::IsTypeAllocatedDuringIncremental(TypeSet::Type v) +{ + bool rv; + if (v.isSingletonUnchecked()) { + JSObject *obj = v.singletonNoBarrier(); + rv = obj->isTenured() && obj->asTenured().arenaHeader()->allocatedDuringIncremental; + } else if (v.isGroupUnchecked()) { + ObjectGroup *group = v.groupNoBarrier(); + rv = group->arenaHeader()->allocatedDuringIncremental; + } else { + rv = false; + } + return rv; +} + static inline bool IsObjectKeyAboutToBeFinalized(TypeSet::ObjectKey **keyp) { diff --git a/js/src/vm/TypeInference.h b/js/src/vm/TypeInference.h index 2c91080d0f4..903dceaf076 100644 --- a/js/src/vm/TypeInference.h +++ b/js/src/vm/TypeInference.h @@ -531,6 +531,7 @@ class TypeSet static void MarkTypeRoot(JSTracer *trc, Type *v, const char *name); static void MarkTypeUnbarriered(JSTracer *trc, Type *v, const char *name); static bool IsTypeMarkedFromAnyThread(Type *v); + static bool IsTypeAllocatedDuringIncremental(Type v); static bool IsTypeAboutToBeFinalized(Type *v); }; diff --git a/js/src/vm/UnboxedObject.cpp b/js/src/vm/UnboxedObject.cpp index fe7467d43db..309e734ef08 100644 --- a/js/src/vm/UnboxedObject.cpp +++ b/js/src/vm/UnboxedObject.cpp @@ -700,8 +700,6 @@ UnboxedPlainObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId return DefineProperty(cx, obj, id, v, getter, setter, attrs); } - // Expandos are currently disabled. FIXME bug 1137180 -#if 0 // Define the property on the expando object. Rooted expando(cx, ensureExpando(cx, obj.as())); if (!expando) @@ -711,12 +709,6 @@ UnboxedPlainObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId AddTypePropertyId(cx, obj, id, v); return DefineProperty(cx, expando, id, v, getter, setter, attrs, result); -#else - if (!convertToNative(cx, obj)) - return false; - - return DefineProperty(cx, obj, id, v, getter, setter, attrs, result); -#endif } /* static */ bool diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h index 5aa1f60409a..00cd5261090 100644 --- a/js/src/vm/Xdr.h +++ b/js/src/vm/Xdr.h @@ -29,7 +29,7 @@ namespace js { * * https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode */ -static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 259; +static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 265; static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND); diff --git a/js/xpconnect/loader/mozJSSubScriptLoader.cpp b/js/xpconnect/loader/mozJSSubScriptLoader.cpp index 6b7ad817a37..2ec9b617d34 100644 --- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp +++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp @@ -177,6 +177,7 @@ mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *targetObj } if (!reuseGlobal) { + options.setHasPollutedScope(!JS_IsGlobalObject(target_obj)); JS::Compile(cx, options, srcBuf, script); } else { AutoObjectVector scopeChain(cx); @@ -192,7 +193,8 @@ mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *targetObj // We only use lazy source when no special encoding is specified because // the lazy source loader doesn't know the encoding. if (!reuseGlobal) { - options.setSourceIsLazy(true); + options.setSourceIsLazy(true) + .setHasPollutedScope(!JS_IsGlobalObject(target_obj)); JS::Compile(cx, options, buf.get(), len, script); } else { AutoObjectVector scopeChain(cx); diff --git a/layout/base/ActiveLayerTracker.cpp b/layout/base/ActiveLayerTracker.cpp index c797c5ab8ee..00fce77fc46 100644 --- a/layout/base/ActiveLayerTracker.cpp +++ b/layout/base/ActiveLayerTracker.cpp @@ -265,13 +265,12 @@ ActiveLayerTracker::IsStyleAnimated(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsCSSProperty aProperty) { // TODO: Add some abuse restrictions - auto willChangeBitField = aFrame->StylePosition()->mWillChangeBitField; - if ((willChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) && + if ((aFrame->StyleDisplay()->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) && aProperty == eCSSProperty_transform && (!aBuilder || aBuilder->IsInWillChangeBudget(aFrame))) { return true; } - if ((willChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) && + if ((aFrame->StyleDisplay()->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) && aProperty == eCSSProperty_opacity && (!aBuilder || aBuilder->IsInWillChangeBudget(aFrame))) { return true; diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index ad8528e76da..591a76b9a35 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -332,12 +332,12 @@ ApplyRenderingChangeToTree(nsPresContext* aPresContext, nsIFrame* aFrame, nsChangeHint aChange) { - // We check StylePosition()->HasTransformStyle() in addition to checking + // We check StyleDisplay()->HasTransformStyle() in addition to checking // IsTransformed() since we can get here for some frames that don't support // CSS transforms. NS_ASSERTION(!(aChange & nsChangeHint_UpdateTransformLayer) || aFrame->IsTransformed() || - aFrame->StylePosition()->HasTransformStyle(), + aFrame->StyleDisplay()->HasTransformStyle(), "Unexpected UpdateTransformLayer hint"); nsIPresShell *shell = aPresContext->PresShell(); @@ -2605,7 +2605,7 @@ ElementRestyler::AddLayerChangesForAnimation() // nsChangeHint_UpdateTransformLayer, ApplyRenderingChangeToTree would // complain that we're updating a transform layer without a transform). if (layerInfo[i].mLayerType == nsDisplayItem::TYPE_TRANSFORM && - !mFrame->StylePosition()->HasTransformStyle()) { + !mFrame->StyleDisplay()->HasTransformStyle()) { continue; } NS_UpdateHint(hint, layerInfo[i].mChangeHint); diff --git a/layout/base/RestyleTracker.cpp b/layout/base/RestyleTracker.cpp index 99425bf50db..294c7144cbc 100644 --- a/layout/base/RestyleTracker.cpp +++ b/layout/base/RestyleTracker.cpp @@ -83,6 +83,7 @@ CollectLaterSiblings(nsISupports* aElement, struct RestyleEnumerateData : RestyleTracker::Hints { nsRefPtr mElement; + UniquePtr mBacktrace; }; struct RestyleCollector { @@ -140,6 +141,7 @@ CollectRestyles(nsISupports* aElement, currentRestyle->mElement = element; currentRestyle->mRestyleHint = aData->mRestyleHint; currentRestyle->mChangeHint = aData->mChangeHint; + currentRestyle->mBacktrace = Move(aData->mBacktrace); #ifdef RESTYLE_LOGGING collector->count++; @@ -305,6 +307,10 @@ RestyleTracker::DoProcessRestyles() continue; } + Maybe profilerRAII; + if (profiler_feature_active("restyle")) { + profilerRAII.emplace("Paint", "Styles", Move(data->mBacktrace)); + } ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint); AddRestyleRootsIfAwaitingRestyle(data->mDescendants); } @@ -340,6 +346,11 @@ RestyleTracker::DoProcessRestyles() FrameTagToString(currentRestyle->mElement).get(), index++, collector.count); LOG_RESTYLE_INDENT(); + + Maybe profilerRAII; + if (profiler_feature_active("restyle")) { + profilerRAII.emplace("Paint", "Styles", Move(currentRestyle->mBacktrace)); + } ProcessOneRestyle(currentRestyle->mElement, currentRestyle->mRestyleHint, currentRestyle->mChangeHint); diff --git a/layout/base/RestyleTracker.h b/layout/base/RestyleTracker.h index a58ee1db4f6..f295c2414fd 100644 --- a/layout/base/RestyleTracker.h +++ b/layout/base/RestyleTracker.h @@ -16,6 +16,8 @@ #include "nsContainerFrame.h" #include "mozilla/SplayTree.h" #include "mozilla/RestyleLogging.h" +#include "ProfilerBacktrace.h" +#include "GeckoProfiler.h" namespace mozilla { @@ -291,6 +293,7 @@ public: // that we called AddPendingRestyle for and found the element this is // the RestyleData for as its nearest restyle root. nsTArray> mDescendants; + UniquePtr mBacktrace; }; /** @@ -388,8 +391,11 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement, } if (!existingData) { - mPendingRestyles.Put(aElement, - new RestyleData(aRestyleHint, aMinChangeHint)); + RestyleData* rd = new RestyleData(aRestyleHint, aMinChangeHint); + if (profiler_feature_active("restyle")) { + rd->mBacktrace.reset(profiler_get_backtrace()); + } + mPendingRestyles.Put(aElement, rd); return false; } diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index e6f8242066f..f7a6beb47d4 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -1059,7 +1059,7 @@ nsFrameConstructorState::PushAbsoluteContainingBlock(nsContainerFrame* aNewAbsol * we're a transformed element. */ mFixedPosIsAbsPos = aPositionedFrame && - aPositionedFrame->StylePosition()->IsFixedPosContainingBlock(aPositionedFrame); + aPositionedFrame->StyleDisplay()->IsFixedPosContainingBlock(aPositionedFrame); if (aNewAbsoluteContainingBlock) { aNewAbsoluteContainingBlock->MarkAsAbsoluteContainingBlock(); @@ -3784,9 +3784,7 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt // If we need to create a block formatting context to wrap our // kids, do it now. - const nsStylePosition* position = styleContext->StylePosition(); const nsStyleDisplay* maybeAbsoluteContainingBlockDisplay = display; - const nsStylePosition* maybeAbsoluteContainingBlockPosition = position; nsIFrame* maybeAbsoluteContainingBlockStyleFrame = primaryFrame; nsIFrame* maybeAbsoluteContainingBlock = newFrame; nsIFrame* possiblyLeafFrame = newFrame; @@ -3813,7 +3811,6 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt const nsStyleDisplay* blockDisplay = blockContext->StyleDisplay(); if (blockDisplay->IsAbsPosContainingBlock(blockFrame)) { maybeAbsoluteContainingBlockDisplay = blockDisplay; - maybeAbsoluteContainingBlockPosition = blockContext->StylePosition(); maybeAbsoluteContainingBlock = blockFrame; maybeAbsoluteContainingBlockStyleFrame = blockFrame; } @@ -3854,7 +3851,7 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt // display for the outer, but make the inner the containing block. if ((maybeAbsoluteContainingBlockDisplay->IsAbsolutelyPositionedStyle() || maybeAbsoluteContainingBlockDisplay->IsRelativelyPositionedStyle() || - maybeAbsoluteContainingBlockPosition->IsFixedPosContainingBlock( + maybeAbsoluteContainingBlockDisplay->IsFixedPosContainingBlock( maybeAbsoluteContainingBlockStyleFrame)) && !maybeAbsoluteContainingBlockStyleFrame->IsSVGText()) { nsContainerFrame* cf = static_cast( @@ -5983,7 +5980,7 @@ nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIFrame* aFrame, // not transformed, skip it. if (!frame->IsAbsPosContaininingBlock() || (aType == FIXED_POS && - !frame->StylePosition()->IsFixedPosContainingBlock(frame))) { + !frame->StyleDisplay()->IsFixedPosContainingBlock(frame))) { continue; } nsIFrame* absPosCBCandidate = frame; diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 4afa515f8df..e149981fdb8 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -332,7 +332,7 @@ static void AddTransformFunctions(nsCSSValueList* aList, } static TimingFunction -ToTimingFunction(ComputedTimingFunction& aCTF) +ToTimingFunction(const ComputedTimingFunction& aCTF) { if (aCTF.GetType() == nsTimingFunction::Function) { const nsSMILKeySpline* spline = aCTF.GetFunction(); @@ -345,7 +345,7 @@ ToTimingFunction(ComputedTimingFunction& aCTF) } static void -AddAnimationForProperty(nsIFrame* aFrame, nsCSSProperty aProperty, +AddAnimationForProperty(nsIFrame* aFrame, const AnimationProperty& aProperty, AnimationPlayer* aPlayer, Layer* aLayer, AnimationData& aData, bool aPending) { @@ -373,44 +373,33 @@ AddAnimationForProperty(nsIFrame* aFrame, nsCSSProperty aProperty, animation->duration() = timing.mIterationDuration; animation->iterationCount() = timing.mIterationCount; animation->direction() = timing.mDirection; - animation->property() = aProperty; + animation->property() = aProperty.mProperty; animation->data() = aData; - dom::Animation* anim = aPlayer->GetSource(); - for (size_t propIdx = 0; - propIdx < anim->Properties().Length(); - propIdx++) { - AnimationProperty& property = anim->Properties()[propIdx]; + for (uint32_t segIdx = 0; segIdx < aProperty.mSegments.Length(); segIdx++) { + const AnimationPropertySegment& segment = aProperty.mSegments[segIdx]; - if (aProperty != property.mProperty) { - continue; + AnimationSegment* animSegment = animation->segments().AppendElement(); + if (aProperty.mProperty == eCSSProperty_transform) { + animSegment->startState() = InfallibleTArray(); + animSegment->endState() = InfallibleTArray(); + + nsCSSValueSharedList* list = + segment.mFromValue.GetCSSValueSharedListValue(); + AddTransformFunctions(list->mHead, styleContext, presContext, bounds, + animSegment->startState().get_ArrayOfTransformFunction()); + + list = segment.mToValue.GetCSSValueSharedListValue(); + AddTransformFunctions(list->mHead, styleContext, presContext, bounds, + animSegment->endState().get_ArrayOfTransformFunction()); + } else if (aProperty.mProperty == eCSSProperty_opacity) { + animSegment->startState() = segment.mFromValue.GetFloatValue(); + animSegment->endState() = segment.mToValue.GetFloatValue(); } - for (uint32_t segIdx = 0; segIdx < property.mSegments.Length(); segIdx++) { - AnimationPropertySegment& segment = property.mSegments[segIdx]; - - AnimationSegment* animSegment = animation->segments().AppendElement(); - if (aProperty == eCSSProperty_transform) { - animSegment->startState() = InfallibleTArray(); - animSegment->endState() = InfallibleTArray(); - - nsCSSValueSharedList* list = - segment.mFromValue.GetCSSValueSharedListValue(); - AddTransformFunctions(list->mHead, styleContext, presContext, bounds, - animSegment->startState().get_ArrayOfTransformFunction()); - - list = segment.mToValue.GetCSSValueSharedListValue(); - AddTransformFunctions(list->mHead, styleContext, presContext, bounds, - animSegment->endState().get_ArrayOfTransformFunction()); - } else if (aProperty == eCSSProperty_opacity) { - animSegment->startState() = segment.mFromValue.GetFloatValue(); - animSegment->endState() = segment.mToValue.GetFloatValue(); - } - - animSegment->startPortion() = segment.mFromKey; - animSegment->endPortion() = segment.mToKey; - animSegment->sampleFn() = ToTimingFunction(segment.mTimingFunction); - } + animSegment->startPortion() = segment.mFromKey; + animSegment->endPortion() = segment.mToKey; + animSegment->sampleFn() = ToTimingFunction(segment.mTimingFunction); } } @@ -418,12 +407,32 @@ static void AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty, AnimationPlayerPtrArray& aPlayers, Layer* aLayer, AnimationData& aData, - bool aPending) { + bool aPending) +{ for (size_t playerIdx = 0; playerIdx < aPlayers.Length(); playerIdx++) { AnimationPlayer* player = aPlayers[playerIdx]; + if (!player->IsRunning()) { + continue; + } dom::Animation* anim = player->GetSource(); - if (!(anim && anim->HasAnimationOfProperty(aProperty) && - player->IsRunning())) { + if (!anim) { + continue; + } + const AnimationProperty* property = + anim->GetAnimationOfProperty(aProperty); + if (!property) { + continue; + } + + if (!property->mWinsInCascade) { + // We have an animation or transition, but it isn't actually + // winning in the CSS cascade, so we don't want to send it to the + // compositor. + // I believe that anything that changes mWinsInCascade should + // trigger this code again, either because of a restyle that + // changes the properties in question, or because of the + // main-thread style update that results when an animation stops + // filling. continue; } @@ -443,7 +452,7 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty, } } - AddAnimationForProperty(aFrame, aProperty, player, aLayer, aData, aPending); + AddAnimationForProperty(aFrame, *property, player, aLayer, aData, aPending); player->SetIsRunningOnCompositor(); } } @@ -522,9 +531,9 @@ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer, nscoord perspective = 0.0; nsStyleContext* parentStyleContext = aFrame->StyleContext()->GetParent(); if (parentStyleContext) { - const nsStylePosition* pos = parentStyleContext->StylePosition(); - if (pos && pos->mChildPerspective.GetUnit() == eStyleUnit_Coord) { - perspective = pos->mChildPerspective.GetCoordValue(); + const nsStyleDisplay* disp = parentStyleContext->StyleDisplay(); + if (disp && disp->mChildPerspective.GetUnit() == eStyleUnit_Coord) { + perspective = disp->mChildPerspective.GetCoordValue(); } } nsPoint origin; @@ -5009,8 +5018,8 @@ nsDisplayTransform::Init(nsDisplayListBuilder* aBuilder) mStoredList.SetVisibleRect(mChildrenVisibleRect); mMaybePrerender = ShouldPrerenderTransformedContent(aBuilder, mFrame); - const nsStylePosition* pos = mFrame->StylePosition(); - if ((pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) { + const nsStyleDisplay* disp = mFrame->StyleDisplay(); + if ((disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) { // We will only pre-render if this will-change is on budget. mMaybePrerender = true; } @@ -5064,8 +5073,7 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame, const nsRect* aBoundsOverride) { NS_PRECONDITION(aFrame, "Can't get delta for a null frame!"); - NS_PRECONDITION(aFrame->IsTransformed() || - aFrame->StylePosition()->BackfaceIsHidden(), + NS_PRECONDITION(aFrame->IsTransformed() || aFrame->StyleDisplay()->BackfaceIsHidden(), "Shouldn't get a delta for an untransformed frame!"); if (!aFrame->IsTransformed()) { @@ -5076,7 +5084,7 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame, * percentage, it's relative to the size of the frame. Otherwise, if it's * a distance, it's already computed for us! */ - const nsStylePosition* pos = aFrame->StylePosition(); + const nsStyleDisplay* display = aFrame->StyleDisplay(); nsRect boundingRect = (aBoundsOverride ? *aBoundsOverride : nsDisplayTransform::GetFrameBoundsForTransform(aFrame)); @@ -5089,7 +5097,7 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame, /* If the -moz-transform-origin specifies a percentage, take the percentage * of the size of the box. */ - const nsStyleCoord &coord = pos->mTransformOrigin[index]; + const nsStyleCoord &coord = display->mTransformOrigin[index]; if (coord.GetUnit() == eStyleUnit_Calc) { const nsStyleCoord::Calc *calc = coord.GetCalcValue(); coords[index] = @@ -5115,7 +5123,7 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame, } } - coords[2] = NSAppUnitsToFloatPixels(pos->mTransformOrigin[2].GetCoordValue(), + coords[2] = NSAppUnitsToFloatPixels(display->mTransformOrigin[2].GetCoordValue(), aAppUnitsPerPixel); /* Adjust based on the origin of the rectangle. */ coords[0] += NSAppUnitsToFloatPixels(boundingRect.x, aAppUnitsPerPixel); @@ -5134,8 +5142,7 @@ nsDisplayTransform::GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame, float aAppUnitsPerPixel) { NS_PRECONDITION(aFrame, "Can't get delta for a null frame!"); - NS_PRECONDITION(aFrame->IsTransformed() || - aFrame->StylePosition()->BackfaceIsHidden(), + NS_PRECONDITION(aFrame->IsTransformed() || aFrame->StyleDisplay()->BackfaceIsHidden(), "Shouldn't get a delta for an untransformed frame!"); if (!aFrame->IsTransformed()) { @@ -5160,7 +5167,7 @@ nsDisplayTransform::GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame, return Point3D(); } } - const nsStylePosition* pos = psc->StylePosition(); + const nsStyleDisplay* display = psc->StyleDisplay(); nsRect boundingRect = nsDisplayTransform::GetFrameBoundsForTransform(parent); /* Allows us to access named variables by index. */ @@ -5174,7 +5181,7 @@ nsDisplayTransform::GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame, /* If the -moz-transform-origin specifies a percentage, take the percentage * of the size of the box. */ - const nsStyleCoord &coord = pos->mPerspectiveOrigin[index]; + const nsStyleCoord &coord = display->mPerspectiveOrigin[index]; if (coord.GetUnit() == eStyleUnit_Calc) { const nsStyleCoord::Calc *calc = coord.GetCalcValue(); *coords[index] = @@ -5205,18 +5212,18 @@ nsDisplayTransform::FrameTransformProperties::FrameTransformProperties(const nsI float aAppUnitsPerPixel, const nsRect* aBoundsOverride) : mFrame(aFrame) - , mTransformList(aFrame->StylePosition()->mSpecifiedTransform) + , mTransformList(aFrame->StyleDisplay()->mSpecifiedTransform) , mToTransformOrigin(GetDeltaToTransformOrigin(aFrame, aAppUnitsPerPixel, aBoundsOverride)) , mToPerspectiveOrigin(GetDeltaToPerspectiveOrigin(aFrame, aAppUnitsPerPixel)) , mChildPerspective(0) { - const nsStylePosition* parentPos = nullptr; + const nsStyleDisplay* parentDisp = nullptr; nsStyleContext* parentStyleContext = aFrame->StyleContext()->GetParent(); if (parentStyleContext) { - parentPos = parentStyleContext->StylePosition(); + parentDisp = parentStyleContext->StyleDisplay(); } - if (parentPos && parentPos->mChildPerspective.GetUnit() == eStyleUnit_Coord) { - mChildPerspective = parentPos->mChildPerspective.GetCoordValue(); + if (parentDisp && parentDisp->mChildPerspective.GetUnit() == eStyleUnit_Coord) { + mChildPerspective = parentDisp->mChildPerspective.GetCoordValue(); } } @@ -5396,8 +5403,8 @@ nsDisplayTransform::ShouldPrerender(nsDisplayListBuilder* aBuilder) { return true; } - const nsStylePosition* pos = mFrame->StylePosition(); - if ((pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) && + const nsStyleDisplay* disp = mFrame->StyleDisplay(); + if ((disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) && aBuilder->IsInWillChangeBudget(mFrame)) { return true; } @@ -5486,8 +5493,7 @@ static bool IsFrameVisible(nsIFrame* aFrame, const Matrix4x4& aMatrix) if (aMatrix.IsSingular()) { return false; } - const nsStylePosition* pos = aFrame->StylePosition(); - if (pos->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN && + if (aFrame->StyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN && aMatrix.IsBackfaceVisible()) { return false; } @@ -5535,8 +5541,7 @@ already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu { const Matrix4x4& newTransformMatrix = GetTransform(); - const nsStylePosition* pos = mFrame->StylePosition(); - if (pos->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN && + if (mFrame->StyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN && newTransformMatrix.IsBackfaceVisible()) { return nullptr; } @@ -5595,8 +5600,8 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder, } } - const nsStylePosition* pos = mFrame->StylePosition(); - if ((pos->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) { + const nsStyleDisplay* disp = mFrame->StyleDisplay(); + if ((disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM)) { return LAYER_ACTIVE; } diff --git a/layout/base/nsLayoutDebugger.cpp b/layout/base/nsLayoutDebugger.cpp index c85ca8704f9..ced64b1df90 100644 --- a/layout/base/nsLayoutDebugger.cpp +++ b/layout/base/nsLayoutDebugger.cpp @@ -184,14 +184,13 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, aStream << " fixed"; } - const nsStylePosition* pos = aItem->Frame()->StylePosition(); - if (pos->mWillChange.Length() > 0) { + if (aItem->Frame()->StyleDisplay()->mWillChange.Length() > 0) { aStream << " (will-change="; - for (size_t i = 0; i < pos->mWillChange.Length(); i++) { + for (size_t i = 0; i < aItem->Frame()->StyleDisplay()->mWillChange.Length(); i++) { if (i > 0) { aStream << ","; } - aStream << NS_LossyConvertUTF16toASCII(pos->mWillChange[i]).get(); + aStream << NS_LossyConvertUTF16toASCII(aItem->Frame()->StyleDisplay()->mWillChange[i]).get(); } aStream << ")"; } diff --git a/layout/forms/nsHTMLButtonControlFrame.cpp b/layout/forms/nsHTMLButtonControlFrame.cpp index 62dbad37ad0..3d90c07f2ce 100644 --- a/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/layout/forms/nsHTMLButtonControlFrame.cpp @@ -268,9 +268,31 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext, // Buttons have some bonus renderer-determined border/padding, // which occupies part of the button's content-box area: - const LogicalMargin focusPadding = + LogicalMargin focusPadding = LogicalMargin(wm, mRenderer.GetAddedButtonBorderAndPadding()); + // See whether out availSize's inline-size is big enough. If it's + // smaller than our intrinsic min iSize, that means that the kid + // wouldn't really fit. In that case, we overflow into our internal + // focuspadding (which other browsers don't have) so that there's a + // little more space for it. + // Note that GetMinISize includes the focusPadding. + nscoord IOverflow = GetMinISize(aButtonReflowState.rendContext) - + aButtonReflowState.ComputedISize(); + nscoord IFocusPadding = focusPadding.IStartEnd(wm); + nscoord focusPaddingReduction = std::min(IFocusPadding, + std::max(IOverflow, 0)); + if (focusPaddingReduction > 0) { + nscoord startReduction = focusPadding.IStart(wm); + if (focusPaddingReduction != IFocusPadding) { + startReduction = NSToCoordRound(startReduction * + (float(focusPaddingReduction) / + float(IFocusPadding))); + } + focusPadding.IStart(wm) -= startReduction; + focusPadding.IEnd(wm) -= focusPaddingReduction - startReduction; + } + // shorthand for a value we need to use in a bunch of places const LogicalMargin& clbp = aButtonReflowState.ComputedLogicalBorderPadding(); @@ -278,26 +300,8 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext, // from the regular border. availSize.ISize(wm) -= focusPadding.IStartEnd(wm); - // See whether out availSize's inline-size is big enough. If it's smaller than - // our intrinsic min iSize, that means that the kid wouldn't really fit; for a - // better look in such cases we adjust the available iSize and our inline-start - // offset to allow the kid to spill start-wards into our padding. LogicalPoint childPos(wm); childPos.I(wm) = focusPadding.IStart(wm) + clbp.IStart(wm); - nscoord extraISize = GetMinISize(aButtonReflowState.rendContext) - - aButtonReflowState.ComputedISize(); - if (extraISize > 0) { - nscoord extraIStart = extraISize / 2; - nscoord extraIEnd = extraISize - extraIStart; - NS_ASSERTION(extraIEnd >=0, "How'd that happen?"); - - // Do not allow the extras to be bigger than the relevant padding - const LogicalMargin& padding = aButtonReflowState.ComputedLogicalPadding(); - extraIStart = std::min(extraIStart, padding.IStart(wm)); - extraIEnd = std::min(extraIEnd, padding.IEnd(wm)); - childPos.I(wm) -= extraIStart; - availSize.ISize(wm) = availSize.ISize(wm) + extraIStart + extraIEnd; - } availSize.ISize(wm) = std::max(availSize.ISize(wm), 0); // Give child a clone of the button's reflow state, with height/width reduced diff --git a/layout/generic/crashtests/769303-1.html b/layout/generic/crashtests/769303-1.html index 83c18bbb78a..91598029f4c 100644 --- a/layout/generic/crashtests/769303-1.html +++ b/layout/generic/crashtests/769303-1.html @@ -1,3 +1,4 @@ + + + +
+
+
text
+
+
+
+ + diff --git a/layout/reftests/bugs/1128354-1.html b/layout/reftests/bugs/1128354-1.html new file mode 100644 index 00000000000..c83bcf8b252 --- /dev/null +++ b/layout/reftests/bugs/1128354-1.html @@ -0,0 +1,37 @@ + + + + + + + +
+
+
text
+
+
+
+ + diff --git a/layout/reftests/bugs/491180-1-ref.html b/layout/reftests/bugs/491180-1-ref.html index f25b10a49f1..2cf61ad1655 100644 --- a/layout/reftests/bugs/491180-1-ref.html +++ b/layout/reftests/bugs/491180-1-ref.html @@ -1,5 +1,5 @@ -
+
Some text
diff --git a/layout/reftests/bugs/491180-2-ref.html b/layout/reftests/bugs/491180-2-ref.html index 615c709ddcc..2b7a85630dd 100644 --- a/layout/reftests/bugs/491180-2-ref.html +++ b/layout/reftests/bugs/491180-2-ref.html @@ -1,4 +1,4 @@ -
Some text
+
Some text
diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index bdd9756f6fa..fcaeea323bc 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -152,8 +152,8 @@ random == 99850-1b.html 99850-1-ref.html # bug 471629 == 179596-2.html 179596-2-ref.html == 179596-2.html 179596-2-ref2.html == 179596-2.html 179596-2-ref3.html -== 180085-1.html 180085-1-ref.html -== 180085-2.html 180085-2-ref.html +!= 180085-1.html 180085-1-ref.html # fix for 180085 reverted in bug 1010675 +!= 180085-2.html 180085-2-ref.html # fix for 180085 reverted in bug 1010675 == 185388-1.html 185388-1-ref.html == 186317-1.html 186317-1-ref.html == 192902-1.html 192902-ref.html @@ -527,8 +527,8 @@ random-if(cocoaWidget) == 350506-1.html 350506-1-ref.html == 356774-1.html 356774-1-ref.html == 356775-1.html 356775-1-ref.html == 359869-1.html 359869-1-ref.html -skip-if(B2G||Mulet) == 359903-1.html 359903-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop -== 359903-2.html 359903-2-ref.html +fails-if(OSX) != 359903-1.html 359903-1-ref.html # erosion of padding removed in bug 1010675 # failure is bug 1145589 +!= 359903-2.html 359903-2-ref.html # erosion of padding removed in bug 1010675 == 360065-1.html 360065-1-ref.html == 360746-1.html 360746-1-ref.html == 360757-1a.html 360757-1-ref.html @@ -1868,5 +1868,6 @@ skip-if(Mulet) == 1120431-2.html 1120431-2-ref.html # TC: Bug 1144079 - Re-enabl == 1127107-1b-pre.html 1127107-1-ref.html == 1127107-2-capitalize.html 1127107-2-capitalize-ref.html == 1127679-1a-inline-flex-relpos.html 1127679-1b-inline-flex-relpos.html +== 1128354-1.html 1128354-1-ref.html == 1130231-1-button-padding-rtl.html 1130231-1-button-padding-rtl-ref.html == 1130231-2-button-padding-rtl.html 1130231-2-button-padding-rtl-ref.html diff --git a/layout/reftests/css-animations/reftest.list b/layout/reftests/css-animations/reftest.list index 05a38ffc91c..51a66695242 100644 --- a/layout/reftests/css-animations/reftest.list +++ b/layout/reftests/css-animations/reftest.list @@ -1,4 +1,5 @@ == screen-animations.html screen-animations-ref.html != screen-animations.html screen-animations-notref.html -fails == print-no-animations.html print-no-animations-ref.html # reftest harness doesn't actually make pres context non-dynamic for reftest-print tests -fails != print-no-animations.html print-no-animations-notref.html # reftest harness doesn't actually make pres context non-dynamic for reftest-print tests +# random-if on osx, bug 1145327 +random-if(cocoaWidget) fails-if(!cocoaWidget) == print-no-animations.html print-no-animations-ref.html # reftest harness doesn't actually make pres context non-dynamic for reftest-print tests +random-if(cocoaWidget) fails-if(!cocoaWidget) != print-no-animations.html print-no-animations-notref.html # reftest harness doesn't actually make pres context non-dynamic for reftest-print tests diff --git a/layout/reftests/forms/button/reftest.list b/layout/reftests/forms/button/reftest.list index 6143c6a4d2b..181cfdf05ce 100644 --- a/layout/reftests/forms/button/reftest.list +++ b/layout/reftests/forms/button/reftest.list @@ -27,3 +27,18 @@ fails-if(Android||B2G||Mulet) == disabled-1.html disabled-1-ref.html # Initial m != disabled-4.html disabled-4-notref.html != disabled-5.html disabled-5-notref.html != disabled-6.html disabled-6-notref.html + +# The following 12 tests are skip-if(B2G) because they change the test +# chunking and thus trigger bug 1145803. +fails-if(B2G) skip-if(B2G) == width-auto-size-em-ltr.html width-auto-size-em-ltr-ref.html # Bug 1145672 +fails-if(B2G) skip-if(B2G) == width-auto-size-ltr.html width-auto-size-ltr-ref.html # Bug 1145672 +skip-if(B2G) == width-exact-fit-ltr.html width-auto-size-ltr-ref.html +skip-if(B2G) == width-erode-part-focuspadding-ltr.html width-erode-part-focuspadding-ltr-ref.html +skip-if(B2G) == width-erode-all-focuspadding-ltr.html width-erode-all-focuspadding-ltr-ref.html +skip-if(B2G) == width-erode-overflow-focuspadding-ltr.html width-erode-overflow-focuspadding-ltr-ref.html +fails-if(B2G) skip-if(B2G) == width-auto-size-em-rtl.html width-auto-size-em-rtl-ref.html # Bug 1145672 +fails-if(B2G) skip-if(B2G) == width-auto-size-rtl.html width-auto-size-rtl-ref.html # Bug 1145672 +skip-if(B2G) == width-exact-fit-rtl.html width-auto-size-rtl-ref.html +skip-if(B2G) == width-erode-part-focuspadding-rtl.html width-erode-part-focuspadding-rtl-ref.html +skip-if(B2G) == width-erode-all-focuspadding-rtl.html width-erode-all-focuspadding-rtl-ref.html +skip-if(B2G) == width-erode-overflow-focuspadding-rtl.html width-erode-overflow-focuspadding-rtl-ref.html diff --git a/layout/reftests/forms/button/width-auto-size-em-ltr-ref.html b/layout/reftests/forms/button/width-auto-size-em-ltr-ref.html new file mode 100644 index 00000000000..1e7ab40bba7 --- /dev/null +++ b/layout/reftests/forms/button/width-auto-size-em-ltr-ref.html @@ -0,0 +1,19 @@ + + + +
diff --git a/layout/reftests/forms/button/width-auto-size-em-ltr.html b/layout/reftests/forms/button/width-auto-size-em-ltr.html new file mode 100644 index 00000000000..3285c3e9551 --- /dev/null +++ b/layout/reftests/forms/button/width-auto-size-em-ltr.html @@ -0,0 +1,20 @@ + + + + diff --git a/layout/reftests/forms/button/width-auto-size-em-rtl-ref.html b/layout/reftests/forms/button/width-auto-size-em-rtl-ref.html new file mode 100644 index 00000000000..1214714744d --- /dev/null +++ b/layout/reftests/forms/button/width-auto-size-em-rtl-ref.html @@ -0,0 +1,20 @@ + + + + +
diff --git a/layout/reftests/forms/button/width-auto-size-em-rtl.html b/layout/reftests/forms/button/width-auto-size-em-rtl.html new file mode 100644 index 00000000000..fb72ef97e9a --- /dev/null +++ b/layout/reftests/forms/button/width-auto-size-em-rtl.html @@ -0,0 +1,21 @@ + + + + + diff --git a/layout/reftests/forms/button/width-auto-size-ltr-ref.html b/layout/reftests/forms/button/width-auto-size-ltr-ref.html new file mode 100644 index 00000000000..c1ba89860ef --- /dev/null +++ b/layout/reftests/forms/button/width-auto-size-ltr-ref.html @@ -0,0 +1,20 @@ + + + +
diff --git a/layout/reftests/forms/button/width-auto-size-ltr.html b/layout/reftests/forms/button/width-auto-size-ltr.html new file mode 100644 index 00000000000..c8f3f7d110c --- /dev/null +++ b/layout/reftests/forms/button/width-auto-size-ltr.html @@ -0,0 +1,20 @@ + + + + diff --git a/layout/reftests/forms/button/width-auto-size-rtl-ref.html b/layout/reftests/forms/button/width-auto-size-rtl-ref.html new file mode 100644 index 00000000000..3e09016dc33 --- /dev/null +++ b/layout/reftests/forms/button/width-auto-size-rtl-ref.html @@ -0,0 +1,21 @@ + + + + +
diff --git a/layout/reftests/forms/button/width-auto-size-rtl.html b/layout/reftests/forms/button/width-auto-size-rtl.html new file mode 100644 index 00000000000..7ae3092f94b --- /dev/null +++ b/layout/reftests/forms/button/width-auto-size-rtl.html @@ -0,0 +1,21 @@ + + + + + diff --git a/layout/reftests/forms/button/width-erode-all-focuspadding-ltr-ref.html b/layout/reftests/forms/button/width-erode-all-focuspadding-ltr-ref.html new file mode 100644 index 00000000000..c85da00e3ce --- /dev/null +++ b/layout/reftests/forms/button/width-erode-all-focuspadding-ltr-ref.html @@ -0,0 +1,20 @@ + + + +
diff --git a/layout/reftests/forms/button/width-erode-all-focuspadding-ltr.html b/layout/reftests/forms/button/width-erode-all-focuspadding-ltr.html new file mode 100644 index 00000000000..4978a57e4eb --- /dev/null +++ b/layout/reftests/forms/button/width-erode-all-focuspadding-ltr.html @@ -0,0 +1,21 @@ + + + + diff --git a/layout/reftests/forms/button/width-erode-all-focuspadding-rtl-ref.html b/layout/reftests/forms/button/width-erode-all-focuspadding-rtl-ref.html new file mode 100644 index 00000000000..762e443f81f --- /dev/null +++ b/layout/reftests/forms/button/width-erode-all-focuspadding-rtl-ref.html @@ -0,0 +1,21 @@ + + + + +
diff --git a/layout/reftests/forms/button/width-erode-all-focuspadding-rtl.html b/layout/reftests/forms/button/width-erode-all-focuspadding-rtl.html new file mode 100644 index 00000000000..d4b028b48e9 --- /dev/null +++ b/layout/reftests/forms/button/width-erode-all-focuspadding-rtl.html @@ -0,0 +1,22 @@ + + + + + diff --git a/layout/reftests/forms/button/width-erode-overflow-focuspadding-ltr-ref.html b/layout/reftests/forms/button/width-erode-overflow-focuspadding-ltr-ref.html new file mode 100644 index 00000000000..6f7047cce3c --- /dev/null +++ b/layout/reftests/forms/button/width-erode-overflow-focuspadding-ltr-ref.html @@ -0,0 +1,20 @@ + + + +
diff --git a/layout/reftests/forms/button/width-erode-overflow-focuspadding-ltr.html b/layout/reftests/forms/button/width-erode-overflow-focuspadding-ltr.html new file mode 100644 index 00000000000..daecef56e4c --- /dev/null +++ b/layout/reftests/forms/button/width-erode-overflow-focuspadding-ltr.html @@ -0,0 +1,21 @@ + + + + diff --git a/layout/reftests/forms/button/width-erode-overflow-focuspadding-rtl-ref.html b/layout/reftests/forms/button/width-erode-overflow-focuspadding-rtl-ref.html new file mode 100644 index 00000000000..1b36154cfca --- /dev/null +++ b/layout/reftests/forms/button/width-erode-overflow-focuspadding-rtl-ref.html @@ -0,0 +1,21 @@ + + + + +
diff --git a/layout/reftests/forms/button/width-erode-overflow-focuspadding-rtl.html b/layout/reftests/forms/button/width-erode-overflow-focuspadding-rtl.html new file mode 100644 index 00000000000..b76a3957a53 --- /dev/null +++ b/layout/reftests/forms/button/width-erode-overflow-focuspadding-rtl.html @@ -0,0 +1,22 @@ + + + + + diff --git a/layout/reftests/forms/button/width-erode-part-focuspadding-ltr-ref.html b/layout/reftests/forms/button/width-erode-part-focuspadding-ltr-ref.html new file mode 100644 index 00000000000..59cbd020864 --- /dev/null +++ b/layout/reftests/forms/button/width-erode-part-focuspadding-ltr-ref.html @@ -0,0 +1,20 @@ + + + +
diff --git a/layout/reftests/forms/button/width-erode-part-focuspadding-ltr.html b/layout/reftests/forms/button/width-erode-part-focuspadding-ltr.html new file mode 100644 index 00000000000..c0d64b27970 --- /dev/null +++ b/layout/reftests/forms/button/width-erode-part-focuspadding-ltr.html @@ -0,0 +1,21 @@ + + + + diff --git a/layout/reftests/forms/button/width-erode-part-focuspadding-rtl-ref.html b/layout/reftests/forms/button/width-erode-part-focuspadding-rtl-ref.html new file mode 100644 index 00000000000..0765a673dfb --- /dev/null +++ b/layout/reftests/forms/button/width-erode-part-focuspadding-rtl-ref.html @@ -0,0 +1,21 @@ + + + + +
diff --git a/layout/reftests/forms/button/width-erode-part-focuspadding-rtl.html b/layout/reftests/forms/button/width-erode-part-focuspadding-rtl.html new file mode 100644 index 00000000000..9b882693855 --- /dev/null +++ b/layout/reftests/forms/button/width-erode-part-focuspadding-rtl.html @@ -0,0 +1,22 @@ + + + + + diff --git a/layout/reftests/forms/button/width-exact-fit-ltr.html b/layout/reftests/forms/button/width-exact-fit-ltr.html new file mode 100644 index 00000000000..58db0aa70c9 --- /dev/null +++ b/layout/reftests/forms/button/width-exact-fit-ltr.html @@ -0,0 +1,21 @@ + + + + diff --git a/layout/reftests/forms/button/width-exact-fit-rtl.html b/layout/reftests/forms/button/width-exact-fit-rtl.html new file mode 100644 index 00000000000..996a69d8319 --- /dev/null +++ b/layout/reftests/forms/button/width-exact-fit-rtl.html @@ -0,0 +1,22 @@ + + + + + diff --git a/layout/reftests/writing-mode/1134849-orthogonal-inline-ref.html b/layout/reftests/writing-mode/1134849-orthogonal-inline-ref.html new file mode 100644 index 00000000000..c059c7f4088 --- /dev/null +++ b/layout/reftests/writing-mode/1134849-orthogonal-inline-ref.html @@ -0,0 +1,31 @@ + + + + + Test for bug 1134849 + + + +
+

The quick brown fox jumps over
the lazy dog.

+
+
+

The quick brown fox jumps over
the lazy dog.

+
+
+

The quick brown fox jumps over
the lazy dog.

+
+
+ inline-block + + diff --git a/layout/reftests/writing-mode/1134849-orthogonal-inline.html b/layout/reftests/writing-mode/1134849-orthogonal-inline.html new file mode 100644 index 00000000000..26dfc17cd9a --- /dev/null +++ b/layout/reftests/writing-mode/1134849-orthogonal-inline.html @@ -0,0 +1,33 @@ + + + + + Test for bug 1134849 + + + +
+

The quick brown fox jumps over
the lazy dog.

+
+
+

The quick brown fox jumps over
the lazy dog.

+
+
+

The quick brown fox jumps over
the lazy dog.

+
+
+ + + diff --git a/layout/reftests/writing-mode/reftest.list b/layout/reftests/writing-mode/reftest.list index 008e1fb8cff..74930c5f516 100644 --- a/layout/reftests/writing-mode/reftest.list +++ b/layout/reftests/writing-mode/reftest.list @@ -105,6 +105,7 @@ HTTP(..) == 1127488-align-left-vertical-lr-ltr.html 1127488-align-top-left-ref.h HTTP(..) == 1127488-align-right-vertical-lr-ltr.html 1127488-align-bottom-left-ref.html == 1131013-vertical-bidi.html 1131013-vertical-bidi-ref.html == 1134744-radio-checkbox-baseline-1.html 1134744-radio-checkbox-baseline-1-ref.html +== 1134849-orthogonal-inline.html 1134849-orthogonal-inline-ref.html fails-if(B2G||Mulet) == 1135361-ruby-justify-1.html 1135361-ruby-justify-1-ref.html # bug 1136067 # Initial mulet triage: parity with B2G/B2G Desktop skip-if(Mulet) == 1136557-1-nested-spans.html 1136557-1-nested-spans-ref.html # TC: Bug 1144079 - Re-enable Mulet mochitests and reftests taskcluster-specific disables. skip-if(Mulet) fuzzy-if(winWidget,255,69) == 1136557-2-nested-spans.html 1136557-2-nested-spans-ref.html # TC: Bug 1144079 - Re-enable Mulet mochitests and reftests taskcluster-specific disables. diff --git a/layout/style/AnimationCommon.cpp b/layout/style/AnimationCommon.cpp index 9a1dab1575a..fe9cf87c681 100644 --- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -741,6 +741,14 @@ AnimationPlayerCollection::EnsureStyleRuleFor(TimeStamp aRefreshTime, } mManager->CheckNeedsRefresh(); + + // If one of our animations just started or stopped filling, we need + // to notify the transition manager. This does the notification a bit + // more than necessary, but it's easier than doing it exactly. + if (mManager->IsAnimationManager()) { + mManager->mPresContext->TransitionManager()-> + UpdateCascadeResultsWithAnimations(this); + } } bool diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index 04ad10f5ee8..5cd1e9076e0 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -24,6 +24,7 @@ #include "mozilla/FloatingPoint.h" #include "nsCSSPseudoElements.h" #include "nsCycleCollectionParticipant.h" +#include "nsCSSPropertySet.h" class nsIFrame; class nsPresContext; @@ -191,6 +192,14 @@ public: mozilla::StyleAnimationValue mValue; }; + void AddPropertiesToSet(nsCSSPropertySet& aSet) const + { + for (size_t i = 0, i_end = mPropertyValuePairs.Length(); i < i_end; ++i) { + const PropertyValuePair &cv = mPropertyValuePairs[i]; + aSet.AddProperty(cv.mProperty); + } + } + private: ~AnimValuesStyleRule() {} @@ -324,6 +333,19 @@ struct AnimationPlayerCollection : public PRCList return NS_LITERAL_STRING("::after"); } + nsCSSPseudoElements::Type PseudoElementType() const + { + if (IsForElement()) { + return nsCSSPseudoElements::ePseudo_NotPseudoElement; + } + if (IsForBeforePseudo()) { + return nsCSSPseudoElements::ePseudo_before; + } + MOZ_ASSERT(IsForAfterPseudo(), + "::before & ::after should be the only pseudo-elements here"); + return nsCSSPseudoElements::ePseudo_after; + } + mozilla::dom::Element* GetElementToRestyle() const; void PostRestyleForAnimation(nsPresContext *aPresContext) { diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp index d57d85c296a..d5298deb0b9 100644 --- a/layout/style/StyleAnimationValue.cpp +++ b/layout/style/StyleAnimationValue.cpp @@ -3017,22 +3017,22 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty, const nsStyleTableBorder *styleTableBorder = static_cast(styleStruct); nsAutoPtr pair(new nsCSSValuePair); - nscoordToCSSValue(styleTableBorder->mBorderSpacingX, pair->mXValue); - nscoordToCSSValue(styleTableBorder->mBorderSpacingY, pair->mYValue); + nscoordToCSSValue(styleTableBorder->mBorderSpacingCol, pair->mXValue); + nscoordToCSSValue(styleTableBorder->mBorderSpacingRow, pair->mYValue); aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(), eUnit_CSSValuePair); break; } case eCSSProperty_transform_origin: { - const nsStylePosition *stylePosition = - static_cast(styleStruct); + const nsStyleDisplay *styleDisplay = + static_cast(styleStruct); nsAutoPtr triplet(new nsCSSValueTriplet); - if (!StyleCoordToCSSValue(stylePosition->mTransformOrigin[0], + if (!StyleCoordToCSSValue(styleDisplay->mTransformOrigin[0], triplet->mXValue) || - !StyleCoordToCSSValue(stylePosition->mTransformOrigin[1], + !StyleCoordToCSSValue(styleDisplay->mTransformOrigin[1], triplet->mYValue) || - !StyleCoordToCSSValue(stylePosition->mTransformOrigin[2], + !StyleCoordToCSSValue(styleDisplay->mTransformOrigin[2], triplet->mZValue)) { return false; } @@ -3042,12 +3042,12 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty, } case eCSSProperty_perspective_origin: { - const nsStylePosition *stylePosition = - static_cast(styleStruct); + const nsStyleDisplay *styleDisplay = + static_cast(styleStruct); nsAutoPtr pair(new nsCSSValuePair); - if (!StyleCoordToCSSValue(stylePosition->mPerspectiveOrigin[0], + if (!StyleCoordToCSSValue(styleDisplay->mPerspectiveOrigin[0], pair->mXValue) || - !StyleCoordToCSSValue(stylePosition->mPerspectiveOrigin[1], + !StyleCoordToCSSValue(styleDisplay->mPerspectiveOrigin[1], pair->mYValue)) { return false; } @@ -3147,29 +3147,29 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty, } case eCSSProperty_clip: { - const nsStylePosition* pos = - static_cast(styleStruct); - if (!(pos->mClipFlags & NS_STYLE_CLIP_RECT)) { + const nsStyleDisplay *display = + static_cast(styleStruct); + if (!(display->mClipFlags & NS_STYLE_CLIP_RECT)) { aComputedValue.SetAutoValue(); } else { nsCSSRect *vrect = new nsCSSRect; - const nsRect &srect = pos->mClip; - if (pos->mClipFlags & NS_STYLE_CLIP_TOP_AUTO) { + const nsRect &srect = display->mClip; + if (display->mClipFlags & NS_STYLE_CLIP_TOP_AUTO) { vrect->mTop.SetAutoValue(); } else { nscoordToCSSValue(srect.y, vrect->mTop); } - if (pos->mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO) { + if (display->mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO) { vrect->mRight.SetAutoValue(); } else { nscoordToCSSValue(srect.XMost(), vrect->mRight); } - if (pos->mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO) { + if (display->mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO) { vrect->mBottom.SetAutoValue(); } else { nscoordToCSSValue(srect.YMost(), vrect->mBottom); } - if (pos->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) { + if (display->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) { vrect->mLeft.SetAutoValue(); } else { nscoordToCSSValue(srect.x, vrect->mLeft); @@ -3339,13 +3339,13 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty, } case eCSSProperty_transform: { - const nsStylePosition* pos = - static_cast(styleStruct); + const nsStyleDisplay *display = + static_cast(styleStruct); nsAutoPtr result; - if (pos->mSpecifiedTransform) { + if (display->mSpecifiedTransform) { // Clone, and convert all lengths (not percents) to pixels. nsCSSValueList **resultTail = getter_Transfers(result); - for (const nsCSSValueList *l = pos->mSpecifiedTransform->mHead; + for (const nsCSSValueList *l = display->mSpecifiedTransform->mHead; l; l = l->mNext) { nsCSSValueList *clone = new nsCSSValueList; *resultTail = clone; diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index e98239fe28c..fc14eece201 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -272,6 +272,11 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext, if (newPlayers.IsEmpty()) { if (collection) { + // There might be transitions that run now that animations don't + // override them. + mPresContext->TransitionManager()-> + UpdateCascadeResultsWithAnimationsToBeDestroyed(collection); + collection->Destroy(); } return nullptr; @@ -594,6 +599,7 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext, AnimationProperty &propData = *destAnim->Properties().AppendElement(); propData.mProperty = prop; + propData.mWinsInCascade = true; KeyframeData *fromKeyframe = nullptr; nsRefPtr fromContext; diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 2d16ccbf824..61ac7aeeb1f 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -1373,7 +1373,7 @@ CSS_PROP_DISPLAY( kClearKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) -CSS_PROP_POSITION( +CSS_PROP_DISPLAY( clip, clip, Clip, @@ -1382,7 +1382,7 @@ CSS_PROP_POSITION( "", 0, nullptr, - offsetof(nsStylePosition, mClip), + offsetof(nsStyleDisplay, mClip), eStyleAnimType_Custom) CSS_PROP_COLOR( color, @@ -3305,7 +3305,7 @@ CSS_PROP_TEXT( kTextTransformKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) -CSS_PROP_POSITION( +CSS_PROP_DISPLAY( transform, transform, Transform, @@ -3315,9 +3315,9 @@ CSS_PROP_POSITION( "", 0, nullptr, - offsetof(nsStylePosition, mSpecifiedTransform), + offsetof(nsStyleDisplay, mSpecifiedTransform), eStyleAnimType_Custom) -CSS_PROP_POSITION( +CSS_PROP_DISPLAY( transform-origin, transform_origin, TransformOrigin, @@ -3329,7 +3329,7 @@ CSS_PROP_POSITION( kBackgroundPositionKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_Custom) -CSS_PROP_POSITION( +CSS_PROP_DISPLAY( perspective-origin, perspective_origin, PerspectiveOrigin, @@ -3341,7 +3341,7 @@ CSS_PROP_POSITION( kBackgroundPositionKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_Custom) -CSS_PROP_POSITION( +CSS_PROP_DISPLAY( perspective, perspective, Perspective, @@ -3350,9 +3350,9 @@ CSS_PROP_POSITION( "", VARIANT_NONE | VARIANT_INHERIT | VARIANT_LENGTH | VARIANT_POSITIVE_DIMENSION, nullptr, - offsetof(nsStylePosition, mChildPerspective), + offsetof(nsStyleDisplay, mChildPerspective), eStyleAnimType_Coord) -CSS_PROP_POSITION( +CSS_PROP_DISPLAY( transform-style, transform_style, TransformStyle, @@ -3363,7 +3363,7 @@ CSS_PROP_POSITION( kTransformStyleKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_None) -CSS_PROP_POSITION( +CSS_PROP_DISPLAY( backface-visibility, backface_visibility, BackfaceVisibility, @@ -3371,7 +3371,7 @@ CSS_PROP_POSITION( "", VARIANT_HK, kBackfaceVisibilityKTable, - offsetof(nsStylePosition, mBackfaceVisibility), + offsetof(nsStyleDisplay, mBackfaceVisibility), eStyleAnimType_None) CSS_PROP_POSITION( top, @@ -4122,7 +4122,7 @@ CSS_PROP_SVGRESET( offsetof(nsStyleSVGReset, mVectorEffect), eStyleAnimType_EnumU8) -CSS_PROP_POSITION( +CSS_PROP_DISPLAY( will-change, will_change, WillChange, diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index bc7c480baff..f3c06b6fe3c 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -1148,22 +1148,23 @@ nsComputedDOMStyle::DoGetTransformOrigin() nsDOMCSSValueList* valueList = GetROCSSValueList(false); /* Now, get the values. */ - const nsStylePosition* pos = StylePosition(); + const nsStyleDisplay* display = StyleDisplay(); nsROCSSPrimitiveValue* width = new nsROCSSPrimitiveValue; - SetValueToCoord(width, pos->mTransformOrigin[0], false, + SetValueToCoord(width, display->mTransformOrigin[0], false, &nsComputedDOMStyle::GetFrameBoundsWidthForTransform); valueList->AppendCSSValue(width); nsROCSSPrimitiveValue* height = new nsROCSSPrimitiveValue; - SetValueToCoord(height, pos->mTransformOrigin[1], false, + SetValueToCoord(height, display->mTransformOrigin[1], false, &nsComputedDOMStyle::GetFrameBoundsHeightForTransform); valueList->AppendCSSValue(height); - if (pos->mTransformOrigin[2].GetUnit() != eStyleUnit_Coord || - pos->mTransformOrigin[2].GetCoordValue() != 0) { + if (display->mTransformOrigin[2].GetUnit() != eStyleUnit_Coord || + display->mTransformOrigin[2].GetCoordValue() != 0) { nsROCSSPrimitiveValue* depth = new nsROCSSPrimitiveValue; - SetValueToCoord(depth, pos->mTransformOrigin[2], false, nullptr); + SetValueToCoord(depth, display->mTransformOrigin[2], false, + nullptr); valueList->AppendCSSValue(depth); } @@ -1184,15 +1185,15 @@ nsComputedDOMStyle::DoGetPerspectiveOrigin() nsDOMCSSValueList* valueList = GetROCSSValueList(false); /* Now, get the values. */ - const nsStylePosition* pos = StylePosition(); + const nsStyleDisplay* display = StyleDisplay(); nsROCSSPrimitiveValue* width = new nsROCSSPrimitiveValue; - SetValueToCoord(width, pos->mPerspectiveOrigin[0], false, + SetValueToCoord(width, display->mPerspectiveOrigin[0], false, &nsComputedDOMStyle::GetFrameBoundsWidthForTransform); valueList->AppendCSSValue(width); nsROCSSPrimitiveValue* height = new nsROCSSPrimitiveValue; - SetValueToCoord(height, pos->mPerspectiveOrigin[1], false, + SetValueToCoord(height, display->mPerspectiveOrigin[1], false, &nsComputedDOMStyle::GetFrameBoundsHeightForTransform); valueList->AppendCSSValue(height); @@ -1203,7 +1204,7 @@ CSSValue* nsComputedDOMStyle::DoGetPerspective() { nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; - SetValueToCoord(val, StylePosition()->mChildPerspective, false); + SetValueToCoord(val, StyleDisplay()->mChildPerspective, false); return val; } @@ -1212,7 +1213,7 @@ nsComputedDOMStyle::DoGetBackfaceVisibility() { nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; val->SetIdent( - nsCSSProps::ValueToKeywordEnum(StylePosition()->mBackfaceVisibility, + nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBackfaceVisibility, nsCSSProps::kBackfaceVisibilityKTable)); return val; } @@ -1222,7 +1223,7 @@ nsComputedDOMStyle::DoGetTransformStyle() { nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; val->SetIdent( - nsCSSProps::ValueToKeywordEnum(StylePosition()->mTransformStyle, + nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mTransformStyle, nsCSSProps::kTransformStyleKTable)); return val; } @@ -1234,13 +1235,13 @@ nsComputedDOMStyle::DoGetTransformStyle() CSSValue* nsComputedDOMStyle::DoGetTransform() { - /* First, get the position data. We'll need it. */ - const nsStylePosition* pos = StylePosition(); + /* First, get the display data. We'll need it. */ + const nsStyleDisplay* display = StyleDisplay(); /* If there are no transforms, then we should construct a single-element * entry and hand it back. */ - if (!pos->mSpecifiedTransform) { + if (!display->mSpecifiedTransform) { nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; /* Set it to "none." */ @@ -1267,7 +1268,7 @@ nsComputedDOMStyle::DoGetTransform() bool dummy; gfx3DMatrix matrix = - nsStyleTransformMatrix::ReadTransforms(pos->mSpecifiedTransform->mHead, + nsStyleTransformMatrix::ReadTransforms(display->mSpecifiedTransform->mHead, mStyleContextHolder, mStyleContextHolder->PresContext(), dummy, @@ -2516,8 +2517,8 @@ nsComputedDOMStyle::DoGetBorderSpacing() valueList->AppendCSSValue(ySpacing); const nsStyleTableBorder *border = StyleTableBorder(); - xSpacing->SetAppUnits(border->mBorderSpacingX); - ySpacing->SetAppUnits(border->mBorderSpacingY); + xSpacing->SetAppUnits(border->mBorderSpacingCol); + ySpacing->SetAppUnits(border->mBorderSpacingRow); return valueList; } @@ -4005,9 +4006,9 @@ nsComputedDOMStyle::DoGetClip() { nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; - const nsStylePosition* pos = StylePosition(); + const nsStyleDisplay* display = StyleDisplay(); - if (pos->mClipFlags == NS_STYLE_CLIP_AUTO) { + if (display->mClipFlags == NS_STYLE_CLIP_AUTO) { val->SetIdent(eCSSKeyword_auto); } else { // create the cssvalues for the sides, stick them in the rect object @@ -4017,28 +4018,28 @@ nsComputedDOMStyle::DoGetClip() nsROCSSPrimitiveValue *leftVal = new nsROCSSPrimitiveValue; nsDOMCSSRect * domRect = new nsDOMCSSRect(topVal, rightVal, bottomVal, leftVal); - if (pos->mClipFlags & NS_STYLE_CLIP_TOP_AUTO) { + if (display->mClipFlags & NS_STYLE_CLIP_TOP_AUTO) { topVal->SetIdent(eCSSKeyword_auto); } else { - topVal->SetAppUnits(pos->mClip.y); + topVal->SetAppUnits(display->mClip.y); } - if (pos->mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO) { + if (display->mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO) { rightVal->SetIdent(eCSSKeyword_auto); } else { - rightVal->SetAppUnits(pos->mClip.width + pos->mClip.x); + rightVal->SetAppUnits(display->mClip.width + display->mClip.x); } - if (pos->mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO) { + if (display->mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO) { bottomVal->SetIdent(eCSSKeyword_auto); } else { - bottomVal->SetAppUnits(pos->mClip.height + pos->mClip.y); + bottomVal->SetAppUnits(display->mClip.height + display->mClip.y); } - if (pos->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) { + if (display->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) { leftVal->SetIdent(eCSSKeyword_auto); } else { - leftVal->SetAppUnits(pos->mClip.x); + leftVal->SetAppUnits(display->mClip.x); } val->SetRect(domRect); } @@ -4049,7 +4050,7 @@ nsComputedDOMStyle::DoGetClip() CSSValue* nsComputedDOMStyle::DoGetWillChange() { - const nsTArray& willChange = StylePosition()->mWillChange; + const nsTArray& willChange = StyleDisplay()->mWillChange; if (willChange.IsEmpty()) { nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 0dfa0a6ba8c..1c4523da8f2 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -5568,6 +5568,80 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct, parentDisplay->mResize, NS_STYLE_RESIZE_NONE, 0, 0, 0, 0); + // clip property: length, auto, inherit + const nsCSSValue* clipValue = aRuleData->ValueForClip(); + switch (clipValue->GetUnit()) { + case eCSSUnit_Inherit: + canStoreInRuleTree = false; + display->mClipFlags = parentDisplay->mClipFlags; + display->mClip = parentDisplay->mClip; + break; + + case eCSSUnit_Initial: + case eCSSUnit_Unset: + case eCSSUnit_Auto: + display->mClipFlags = NS_STYLE_CLIP_AUTO; + display->mClip.SetRect(0,0,0,0); + break; + + case eCSSUnit_Null: + break; + + case eCSSUnit_Rect: { + const nsCSSRect& clipRect = clipValue->GetRectValue(); + + display->mClipFlags = NS_STYLE_CLIP_RECT; + + if (clipRect.mTop.GetUnit() == eCSSUnit_Auto) { + display->mClip.y = 0; + display->mClipFlags |= NS_STYLE_CLIP_TOP_AUTO; + } + else if (clipRect.mTop.IsLengthUnit()) { + display->mClip.y = CalcLength(clipRect.mTop, aContext, + mPresContext, canStoreInRuleTree); + } + + if (clipRect.mBottom.GetUnit() == eCSSUnit_Auto) { + // Setting to NS_MAXSIZE for the 'auto' case ensures that + // the clip rect is nonempty. It is important that mClip be + // nonempty if the actual clip rect could be nonempty. + display->mClip.height = NS_MAXSIZE; + display->mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO; + } + else if (clipRect.mBottom.IsLengthUnit()) { + display->mClip.height = CalcLength(clipRect.mBottom, aContext, + mPresContext, canStoreInRuleTree) - + display->mClip.y; + } + + if (clipRect.mLeft.GetUnit() == eCSSUnit_Auto) { + display->mClip.x = 0; + display->mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO; + } + else if (clipRect.mLeft.IsLengthUnit()) { + display->mClip.x = CalcLength(clipRect.mLeft, aContext, + mPresContext, canStoreInRuleTree); + } + + if (clipRect.mRight.GetUnit() == eCSSUnit_Auto) { + // Setting to NS_MAXSIZE for the 'auto' case ensures that + // the clip rect is nonempty. It is important that mClip be + // nonempty if the actual clip rect could be nonempty. + display->mClip.width = NS_MAXSIZE; + display->mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO; + } + else if (clipRect.mRight.IsLengthUnit()) { + display->mClip.width = CalcLength(clipRect.mRight, aContext, + mPresContext, canStoreInRuleTree) - + display->mClip.x; + } + break; + } + + default: + MOZ_ASSERT(false, "unrecognized clip unit"); + } + if (display->mDisplay != NS_STYLE_DISPLAY_NONE) { // CSS2 9.7 specifies display type corrections dealing with 'float' // and 'position'. Since generated content can't be floated or @@ -5626,6 +5700,183 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct, } + /* Convert the nsCSSValueList into an nsTArray. */ + const nsCSSValue* transformValue = aRuleData->ValueForTransform(); + switch (transformValue->GetUnit()) { + case eCSSUnit_Null: + break; + + case eCSSUnit_Initial: + case eCSSUnit_Unset: + case eCSSUnit_None: + display->mSpecifiedTransform = nullptr; + break; + + case eCSSUnit_Inherit: + display->mSpecifiedTransform = parentDisplay->mSpecifiedTransform; + canStoreInRuleTree = false; + break; + + case eCSSUnit_SharedList: { + nsCSSValueSharedList* list = transformValue->GetSharedListValue(); + nsCSSValueList* head = list->mHead; + MOZ_ASSERT(head, "transform list must have at least one item"); + // can get a _None in here from transform animation + if (head->mValue.GetUnit() == eCSSUnit_None) { + MOZ_ASSERT(head->mNext == nullptr, "none must be alone"); + display->mSpecifiedTransform = nullptr; + } else { + display->mSpecifiedTransform = list; + } + break; + } + + default: + MOZ_ASSERT(false, "unrecognized transform unit"); + } + + /* Convert the nsCSSValueList into a will-change bitfield for fast lookup */ + const nsCSSValue* willChangeValue = aRuleData->ValueForWillChange(); + switch (willChangeValue->GetUnit()) { + case eCSSUnit_Null: + break; + + case eCSSUnit_List: + case eCSSUnit_ListDep: { + display->mWillChange.Clear(); + display->mWillChangeBitField = 0; + for (const nsCSSValueList* item = willChangeValue->GetListValue(); + item; item = item->mNext) + { + if (item->mValue.UnitHasStringValue()) { + nsAutoString buffer; + item->mValue.GetStringValue(buffer); + display->mWillChange.AppendElement(buffer); + + if (buffer.EqualsLiteral("transform")) { + display->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_TRANSFORM; + } + if (buffer.EqualsLiteral("opacity")) { + display->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_OPACITY; + } + if (buffer.EqualsLiteral("scroll-position")) { + display->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_SCROLL; + } + + nsCSSProperty prop = + nsCSSProps::LookupProperty(buffer, + nsCSSProps::eEnabledForAllContent); + if (prop != eCSSProperty_UNKNOWN && + nsCSSProps::PropHasFlags(prop, + CSS_PROPERTY_CREATES_STACKING_CONTEXT)) + { + display->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_STACKING_CONTEXT; + } + } + } + break; + } + + case eCSSUnit_Inherit: + display->mWillChange = parentDisplay->mWillChange; + display->mWillChangeBitField = parentDisplay->mWillChangeBitField; + canStoreInRuleTree = false; + break; + + case eCSSUnit_Initial: + case eCSSUnit_Unset: + case eCSSUnit_Auto: + display->mWillChange.Clear(); + display->mWillChangeBitField = 0; + break; + + default: + MOZ_ASSERT(false, "unrecognized will-change unit"); + } + + /* Convert -moz-transform-origin. */ + const nsCSSValue* transformOriginValue = + aRuleData->ValueForTransformOrigin(); + if (transformOriginValue->GetUnit() != eCSSUnit_Null) { + const nsCSSValue& valX = + transformOriginValue->GetUnit() == eCSSUnit_Triplet ? + transformOriginValue->GetTripletValue().mXValue : *transformOriginValue; + const nsCSSValue& valY = + transformOriginValue->GetUnit() == eCSSUnit_Triplet ? + transformOriginValue->GetTripletValue().mYValue : *transformOriginValue; + const nsCSSValue& valZ = + transformOriginValue->GetUnit() == eCSSUnit_Triplet ? + transformOriginValue->GetTripletValue().mZValue : *transformOriginValue; + + mozilla::DebugOnly cX = + SetCoord(valX, display->mTransformOrigin[0], + parentDisplay->mTransformOrigin[0], + SETCOORD_LPH | SETCOORD_INITIAL_HALF | + SETCOORD_BOX_POSITION | SETCOORD_STORE_CALC | + SETCOORD_UNSET_INITIAL, + aContext, mPresContext, canStoreInRuleTree); + + mozilla::DebugOnly cY = + SetCoord(valY, display->mTransformOrigin[1], + parentDisplay->mTransformOrigin[1], + SETCOORD_LPH | SETCOORD_INITIAL_HALF | + SETCOORD_BOX_POSITION | SETCOORD_STORE_CALC | + SETCOORD_UNSET_INITIAL, + aContext, mPresContext, canStoreInRuleTree); + + if (valZ.GetUnit() == eCSSUnit_Null) { + // Null for the z component means a 0 translation, not + // unspecified, as we have already checked the triplet + // value for Null. + display->mTransformOrigin[2].SetCoordValue(0); + } else { + mozilla::DebugOnly cZ = + SetCoord(valZ, display->mTransformOrigin[2], + parentDisplay->mTransformOrigin[2], + SETCOORD_LH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC | + SETCOORD_UNSET_INITIAL, + aContext, mPresContext, canStoreInRuleTree); + MOZ_ASSERT(cY == cZ, "changed one but not the other"); + } + MOZ_ASSERT(cX == cY, "changed one but not the other"); + NS_ASSERTION(cX, "Malformed -moz-transform-origin parse!"); + } + + const nsCSSValue* perspectiveOriginValue = + aRuleData->ValueForPerspectiveOrigin(); + if (perspectiveOriginValue->GetUnit() != eCSSUnit_Null) { + mozilla::DebugOnly result = + SetPairCoords(*perspectiveOriginValue, + display->mPerspectiveOrigin[0], + display->mPerspectiveOrigin[1], + parentDisplay->mPerspectiveOrigin[0], + parentDisplay->mPerspectiveOrigin[1], + SETCOORD_LPH | SETCOORD_INITIAL_HALF | + SETCOORD_BOX_POSITION | SETCOORD_STORE_CALC | + SETCOORD_UNSET_INITIAL, + aContext, mPresContext, canStoreInRuleTree); + NS_ASSERTION(result, "Malformed -moz-perspective-origin parse!"); + } + + SetCoord(*aRuleData->ValueForPerspective(), + display->mChildPerspective, parentDisplay->mChildPerspective, + SETCOORD_LAH | SETCOORD_INITIAL_NONE | SETCOORD_NONE | + SETCOORD_UNSET_INITIAL, + aContext, mPresContext, canStoreInRuleTree); + + SetDiscrete(*aRuleData->ValueForBackfaceVisibility(), + display->mBackfaceVisibility, canStoreInRuleTree, + SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL, + parentDisplay->mBackfaceVisibility, + NS_STYLE_BACKFACE_VISIBILITY_VISIBLE, 0, 0, 0, 0); + + // transform-style: enum, inherit, initial + SetDiscrete(*aRuleData->ValueForTransformStyle(), + display->mTransformStyle, canStoreInRuleTree, + SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL, + parentDisplay->mTransformStyle, + NS_STYLE_TRANSFORM_STYLE_FLAT, 0, 0, 0, 0); + // orient: enum, inherit, initial SetDiscrete(*aRuleData->ValueForOrient(), display->mOrient, canStoreInRuleTree, @@ -7449,80 +7700,6 @@ nsRuleNode::ComputePositionData(void* aStartStruct, 0, 0, 0, 0); } - // clip property: length, auto, inherit - const nsCSSValue* clipValue = aRuleData->ValueForClip(); - switch (clipValue->GetUnit()) { - case eCSSUnit_Inherit: - canStoreInRuleTree = false; - pos->mClipFlags = parentPos->mClipFlags; - pos->mClip = parentPos->mClip; - break; - - case eCSSUnit_Initial: - case eCSSUnit_Unset: - case eCSSUnit_Auto: - pos->mClipFlags = NS_STYLE_CLIP_AUTO; - pos->mClip.SetRect(0,0,0,0); - break; - - case eCSSUnit_Null: - break; - - case eCSSUnit_Rect: { - const nsCSSRect& clipRect = clipValue->GetRectValue(); - - pos->mClipFlags = NS_STYLE_CLIP_RECT; - - if (clipRect.mTop.GetUnit() == eCSSUnit_Auto) { - pos->mClip.y = 0; - pos->mClipFlags |= NS_STYLE_CLIP_TOP_AUTO; - } - else if (clipRect.mTop.IsLengthUnit()) { - pos->mClip.y = CalcLength(clipRect.mTop, aContext, - mPresContext, canStoreInRuleTree); - } - - if (clipRect.mBottom.GetUnit() == eCSSUnit_Auto) { - // Setting to NS_MAXSIZE for the 'auto' case ensures that - // the clip rect is nonempty. It is important that mClip be - // nonempty if the actual clip rect could be nonempty. - pos->mClip.height = NS_MAXSIZE; - pos->mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO; - } - else if (clipRect.mBottom.IsLengthUnit()) { - pos->mClip.height = CalcLength(clipRect.mBottom, aContext, - mPresContext, canStoreInRuleTree) - - pos->mClip.y; - } - - if (clipRect.mLeft.GetUnit() == eCSSUnit_Auto) { - pos->mClip.x = 0; - pos->mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO; - } - else if (clipRect.mLeft.IsLengthUnit()) { - pos->mClip.x = CalcLength(clipRect.mLeft, aContext, - mPresContext, canStoreInRuleTree); - } - - if (clipRect.mRight.GetUnit() == eCSSUnit_Auto) { - // Setting to NS_MAXSIZE for the 'auto' case ensures that - // the clip rect is nonempty. It is important that mClip be - // nonempty if the actual clip rect could be nonempty. - pos->mClip.width = NS_MAXSIZE; - pos->mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO; - } - else if (clipRect.mRight.IsLengthUnit()) { - pos->mClip.width = CalcLength(clipRect.mRight, aContext, - mPresContext, canStoreInRuleTree) - - pos->mClip.x; - } - break; - } - - default: - MOZ_ASSERT(false, "unrecognized clip unit"); - } - // flex-basis: auto, length, percent, enum, calc, inherit, initial // (Note: The flags here should match those used for 'width' property above.) SetCoord(*aRuleData->ValueForFlexBasis(), pos->mFlexBasis, parentPos->mFlexBasis, @@ -7670,183 +7847,6 @@ nsRuleNode::ComputePositionData(void* aStartStruct, parentPos->mGridRowEnd, canStoreInRuleTree); - /* Convert the nsCSSValueList into an nsTArray. */ - const nsCSSValue* transformValue = aRuleData->ValueForTransform(); - switch (transformValue->GetUnit()) { - case eCSSUnit_Null: - break; - - case eCSSUnit_Initial: - case eCSSUnit_Unset: - case eCSSUnit_None: - pos->mSpecifiedTransform = nullptr; - break; - - case eCSSUnit_Inherit: - pos->mSpecifiedTransform = parentPos->mSpecifiedTransform; - canStoreInRuleTree = false; - break; - - case eCSSUnit_SharedList: { - nsCSSValueSharedList* list = transformValue->GetSharedListValue(); - nsCSSValueList* head = list->mHead; - MOZ_ASSERT(head, "transform list must have at least one item"); - // can get a _None in here from transform animation - if (head->mValue.GetUnit() == eCSSUnit_None) { - MOZ_ASSERT(head->mNext == nullptr, "none must be alone"); - pos->mSpecifiedTransform = nullptr; - } else { - pos->mSpecifiedTransform = list; - } - break; - } - - default: - MOZ_ASSERT(false, "unrecognized transform unit"); - } - - /* Convert -moz-transform-origin. */ - const nsCSSValue* transformOriginValue = - aRuleData->ValueForTransformOrigin(); - if (transformOriginValue->GetUnit() != eCSSUnit_Null) { - const nsCSSValue& valX = - transformOriginValue->GetUnit() == eCSSUnit_Triplet ? - transformOriginValue->GetTripletValue().mXValue : *transformOriginValue; - const nsCSSValue& valY = - transformOriginValue->GetUnit() == eCSSUnit_Triplet ? - transformOriginValue->GetTripletValue().mYValue : *transformOriginValue; - const nsCSSValue& valZ = - transformOriginValue->GetUnit() == eCSSUnit_Triplet ? - transformOriginValue->GetTripletValue().mZValue : *transformOriginValue; - - mozilla::DebugOnly cX = - SetCoord(valX, pos->mTransformOrigin[0], - parentPos->mTransformOrigin[0], - SETCOORD_LPH | SETCOORD_INITIAL_HALF | - SETCOORD_BOX_POSITION | SETCOORD_STORE_CALC | - SETCOORD_UNSET_INITIAL, - aContext, mPresContext, canStoreInRuleTree); - - mozilla::DebugOnly cY = - SetCoord(valY, pos->mTransformOrigin[1], - parentPos->mTransformOrigin[1], - SETCOORD_LPH | SETCOORD_INITIAL_HALF | - SETCOORD_BOX_POSITION | SETCOORD_STORE_CALC | - SETCOORD_UNSET_INITIAL, - aContext, mPresContext, canStoreInRuleTree); - - if (valZ.GetUnit() == eCSSUnit_Null) { - // Null for the z component means a 0 translation, not - // unspecified, as we have already checked the triplet - // value for Null. - pos->mTransformOrigin[2].SetCoordValue(0); - } else { - mozilla::DebugOnly cZ = - SetCoord(valZ, pos->mTransformOrigin[2], - parentPos->mTransformOrigin[2], - SETCOORD_LH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC | - SETCOORD_UNSET_INITIAL, - aContext, mPresContext, canStoreInRuleTree); - MOZ_ASSERT(cY == cZ, "changed one but not the other"); - } - MOZ_ASSERT(cX == cY, "changed one but not the other"); - NS_ASSERTION(cX, "Malformed -moz-transform-origin parse!"); - } - - const nsCSSValue* perspectiveOriginValue = - aRuleData->ValueForPerspectiveOrigin(); - if (perspectiveOriginValue->GetUnit() != eCSSUnit_Null) { - mozilla::DebugOnly result = - SetPairCoords(*perspectiveOriginValue, - pos->mPerspectiveOrigin[0], - pos->mPerspectiveOrigin[1], - parentPos->mPerspectiveOrigin[0], - parentPos->mPerspectiveOrigin[1], - SETCOORD_LPH | SETCOORD_INITIAL_HALF | - SETCOORD_BOX_POSITION | SETCOORD_STORE_CALC | - SETCOORD_UNSET_INITIAL, - aContext, mPresContext, canStoreInRuleTree); - NS_ASSERTION(result, "Malformed -moz-perspective-origin parse!"); - } - - SetCoord(*aRuleData->ValueForPerspective(), - pos->mChildPerspective, parentPos->mChildPerspective, - SETCOORD_LAH | SETCOORD_INITIAL_NONE | SETCOORD_NONE | - SETCOORD_UNSET_INITIAL, - aContext, mPresContext, canStoreInRuleTree); - - SetDiscrete(*aRuleData->ValueForBackfaceVisibility(), - pos->mBackfaceVisibility, canStoreInRuleTree, - SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL, - parentPos->mBackfaceVisibility, - NS_STYLE_BACKFACE_VISIBILITY_VISIBLE, 0, 0, 0, 0); - - // transform-style: enum, inherit, initial - SetDiscrete(*aRuleData->ValueForTransformStyle(), - pos->mTransformStyle, canStoreInRuleTree, - SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL, - parentPos->mTransformStyle, - NS_STYLE_TRANSFORM_STYLE_FLAT, 0, 0, 0, 0); - - /* Convert the nsCSSValueList into a will-change bitfield for fast lookup */ - const nsCSSValue* willChangeValue = aRuleData->ValueForWillChange(); - switch (willChangeValue->GetUnit()) { - case eCSSUnit_Null: - break; - - case eCSSUnit_List: - case eCSSUnit_ListDep: { - pos->mWillChange.Clear(); - pos->mWillChangeBitField = 0; - for (const nsCSSValueList* item = willChangeValue->GetListValue(); - item; item = item->mNext) - { - if (item->mValue.UnitHasStringValue()) { - nsAutoString buffer; - item->mValue.GetStringValue(buffer); - pos->mWillChange.AppendElement(buffer); - - if (buffer.EqualsLiteral("transform")) { - pos->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_TRANSFORM; - } - if (buffer.EqualsLiteral("opacity")) { - pos->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_OPACITY; - } - if (buffer.EqualsLiteral("scroll-position")) { - pos->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_SCROLL; - } - - nsCSSProperty prop = - nsCSSProps::LookupProperty(buffer, - nsCSSProps::eEnabledForAllContent); - if (prop != eCSSProperty_UNKNOWN && - nsCSSProps::PropHasFlags(prop, - CSS_PROPERTY_CREATES_STACKING_CONTEXT)) - { - pos->mWillChangeBitField |= NS_STYLE_WILL_CHANGE_STACKING_CONTEXT; - } - } - } - break; - } - - case eCSSUnit_Inherit: - pos->mWillChange = parentPos->mWillChange; - pos->mWillChangeBitField = parentPos->mWillChangeBitField; - canStoreInRuleTree = false; - break; - - case eCSSUnit_Initial: - case eCSSUnit_Unset: - case eCSSUnit_Auto: - pos->mWillChange.Clear(); - pos->mWillChangeBitField = 0; - break; - - default: - MOZ_ASSERT(false, "unrecognized will-change unit"); - } - // z-index const nsCSSValue* zIndexValue = aRuleData->ValueForZIndex(); if (! SetCoord(*zIndexValue, pos->mZIndex, parentPos->mZIndex, @@ -7906,26 +7906,26 @@ nsRuleNode::ComputeTableBorderData(void* aStartStruct, NS_STYLE_BORDER_SEPARATE, 0, 0, 0, 0); const nsCSSValue* borderSpacingValue = aRuleData->ValueForBorderSpacing(); + // border-spacing: pair(length), inherit if (borderSpacingValue->GetUnit() != eCSSUnit_Null) { - // border-spacing-x/y: length, inherit - nsStyleCoord parentX(parentTable->mBorderSpacingX, - nsStyleCoord::CoordConstructor); - nsStyleCoord parentY(parentTable->mBorderSpacingY, - nsStyleCoord::CoordConstructor); - nsStyleCoord coordX, coordY; + nsStyleCoord parentCol(parentTable->mBorderSpacingCol, + nsStyleCoord::CoordConstructor); + nsStyleCoord parentRow(parentTable->mBorderSpacingRow, + nsStyleCoord::CoordConstructor); + nsStyleCoord coordCol, coordRow; #ifdef DEBUG bool result = #endif SetPairCoords(*borderSpacingValue, - coordX, coordY, parentX, parentY, + coordCol, coordRow, parentCol, parentRow, SETCOORD_LH | SETCOORD_INITIAL_ZERO | SETCOORD_CALC_LENGTH_ONLY | SETCOORD_CALC_CLAMP_NONNEGATIVE | SETCOORD_UNSET_INHERIT, aContext, mPresContext, canStoreInRuleTree); NS_ASSERTION(result, "malformed table border value"); - table->mBorderSpacingX = coordX.GetCoordValue(); - table->mBorderSpacingY = coordY.GetCoordValue(); + table->mBorderSpacingCol = coordCol.GetCoordValue(); + table->mBorderSpacingRow = coordRow.GetCoordValue(); } // caption-side: enum, inherit, initial diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h index 763893f1242..460e76d427f 100644 --- a/layout/style/nsStyleConsts.h +++ b/layout/style/nsStyleConsts.h @@ -1020,12 +1020,10 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) { #define NS_STYLE_VECTOR_EFFECT_NONE 0 #define NS_STYLE_VECTOR_EFFECT_NON_SCALING_STROKE 1 -// backface-visibility // 3d Transforms - Backface visibility #define NS_STYLE_BACKFACE_VISIBILITY_VISIBLE 1 #define NS_STYLE_BACKFACE_VISIBILITY_HIDDEN 0 -// transform-style #define NS_STYLE_TRANSFORM_STYLE_FLAT 0 #define NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D 1 diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index 38464ac8991..c87ffe6059b 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -707,6 +707,23 @@ nsStyleContext::ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup) CreateEmptyStyleData(eStyleStruct_Padding); } + // Elements with display:inline whose writing-mode is orthogonal to their + // parent's mode will be converted to display:inline-block. + if (disp->mDisplay == NS_STYLE_DISPLAY_INLINE && mParent) { + // We don't need the full mozilla::WritingMode value (incorporating dir and + // text-orientation) here, all we care about is vertical vs horizontal. + bool thisHorizontal = + StyleVisibility()->mWritingMode == NS_STYLE_WRITING_MODE_HORIZONTAL_TB; + bool parentHorizontal = mParent->StyleVisibility()->mWritingMode == + NS_STYLE_WRITING_MODE_HORIZONTAL_TB; + if (thisHorizontal != parentHorizontal) { + nsStyleDisplay *mutable_display = + static_cast(GetUniqueStyleData(eStyleStruct_Display)); + mutable_display->mOriginalDisplay = mutable_display->mDisplay = + NS_STYLE_DISPLAY_INLINE_BLOCK; + } + } + // Compute User Interface style, to trigger loads of cursors StyleUserInterface(); } diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index e24e5e2ea02..bc38c8ee9c8 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -1379,14 +1379,12 @@ bool nsStyleSVGPaint::operator==(const nsStyleSVGPaint& aOther) const // nsStylePosition // nsStylePosition::nsStylePosition(void) - : mWillChangeBitField(0) { MOZ_COUNT_CTOR(nsStylePosition); // positioning values not inherited mObjectPosition.SetInitialPercentValues(0.5f); - mClip.SetRect(0,0,0,0); nsStyleCoord autoCoord(eStyleUnit_Auto); mOffset.SetLeft(autoCoord); @@ -1412,13 +1410,6 @@ nsStylePosition::nsStylePosition(void) mGridAutoRowsMax.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MAX_CONTENT, eStyleUnit_Enumerated); - mTransformOrigin[0].SetPercentValue(0.5f); // Transform is centered on origin - mTransformOrigin[1].SetPercentValue(0.5f); - mTransformOrigin[2].SetCoordValue(0); - mChildPerspective.SetNoneValue(); - mPerspectiveOrigin[0].SetPercentValue(0.5f); - mPerspectiveOrigin[1].SetPercentValue(0.5f); - mGridAutoFlow = NS_STYLE_GRID_AUTO_FLOW_ROW; mBoxSizing = NS_STYLE_BOX_SIZING_CONTENT; mAlignContent = NS_STYLE_ALIGN_CONTENT_STRETCH; @@ -1428,14 +1419,10 @@ nsStylePosition::nsStylePosition(void) mFlexWrap = NS_STYLE_FLEX_WRAP_NOWRAP; mJustifyContent = NS_STYLE_JUSTIFY_CONTENT_FLEX_START; mObjectFit = NS_STYLE_OBJECT_FIT_FILL; - mClipFlags = NS_STYLE_CLIP_AUTO; - mBackfaceVisibility = NS_STYLE_BACKFACE_VISIBILITY_VISIBLE; - mTransformStyle = NS_STYLE_TRANSFORM_STYLE_FLAT; mOrder = NS_STYLE_ORDER_INITIAL; mFlexGrow = 0.0f; mFlexShrink = 1.0f; mZIndex.SetAutoValue(); - mSpecifiedTransform = nullptr; // Other members get their default constructors // which initialize them to representations of their respective initial value. // mGridTemplateAreas: nullptr for 'none' @@ -1450,7 +1437,6 @@ nsStylePosition::~nsStylePosition(void) nsStylePosition::nsStylePosition(const nsStylePosition& aSource) : mObjectPosition(aSource.mObjectPosition) - , mClip(aSource.mClip) , mOffset(aSource.mOffset) , mWidth(aSource.mWidth) , mMinWidth(aSource.mMinWidth) @@ -1463,7 +1449,6 @@ nsStylePosition::nsStylePosition(const nsStylePosition& aSource) , mGridAutoColumnsMax(aSource.mGridAutoColumnsMax) , mGridAutoRowsMin(aSource.mGridAutoRowsMin) , mGridAutoRowsMax(aSource.mGridAutoRowsMax) - , mChildPerspective(aSource.mChildPerspective) , mGridAutoFlow(aSource.mGridAutoFlow) , mBoxSizing(aSource.mBoxSizing) , mAlignContent(aSource.mAlignContent) @@ -1473,10 +1458,6 @@ nsStylePosition::nsStylePosition(const nsStylePosition& aSource) , mFlexWrap(aSource.mFlexWrap) , mJustifyContent(aSource.mJustifyContent) , mObjectFit(aSource.mObjectFit) - , mClipFlags(aSource.mClipFlags) - , mBackfaceVisibility(aSource.mBackfaceVisibility) - , mTransformStyle(aSource.mTransformStyle) - , mWillChangeBitField(aSource.mWillChangeBitField) , mOrder(aSource.mOrder) , mFlexGrow(aSource.mFlexGrow) , mFlexShrink(aSource.mFlexShrink) @@ -1488,17 +1469,8 @@ nsStylePosition::nsStylePosition(const nsStylePosition& aSource) , mGridColumnEnd(aSource.mGridColumnEnd) , mGridRowStart(aSource.mGridRowStart) , mGridRowEnd(aSource.mGridRowEnd) - , mSpecifiedTransform(aSource.mSpecifiedTransform) - , mWillChange(aSource.mWillChange) { MOZ_COUNT_CTOR(nsStylePosition); - - /* Copy over transform origin. */ - mTransformOrigin[0] = aSource.mTransformOrigin[0]; - mTransformOrigin[1] = aSource.mTransformOrigin[1]; - mTransformOrigin[2] = aSource.mTransformOrigin[2]; - mPerspectiveOrigin[0] = aSource.mPerspectiveOrigin[0]; - mPerspectiveOrigin[1] = aSource.mPerspectiveOrigin[1]; } static bool @@ -1531,96 +1503,6 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons nsChangeHint_NeedReflow)); } - if (mClipFlags != aOther.mClipFlags) { - NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_AllReflowHints, - nsChangeHint_RepaintFrame)); - } - - if (!mClip.IsEqualInterior(aOther.mClip)) { - // If the clip has changed, we just need to update overflow areas. DLBI - // will handle the invalidation. - NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_UpdateOverflow, - nsChangeHint_SchedulePaint)); - } - - /* If we've added or removed the transform property, we need to reconstruct the frame to add - * or remove the view object, and also to handle abs-pos and fixed-pos containers. - */ - if (HasTransformStyle() != aOther.HasTransformStyle()) { - // We do not need to apply nsChangeHint_UpdateTransformLayer since - // nsChangeHint_RepaintFrame will forcibly invalidate the frame area and - // ensure layers are rebuilt (or removed). - NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_AddOrRemoveTransform, - NS_CombineHint(nsChangeHint_UpdateOverflow, - nsChangeHint_RepaintFrame))); - } else { - /* Otherwise, if we've kept the property lying around and we already had a - * transform, we need to see whether or not we've changed the transform. - * If so, we need to recompute its overflow rect (which probably changed - * if the transform changed) and to redraw within the bounds of that new - * overflow rect. - * - * If the property isn't present in either style struct, we still do the - * comparisons but turn all the resulting change hints into - * nsChangeHint_NeutralChange. - */ - nsChangeHint transformHint = nsChangeHint(0); - - if (!mSpecifiedTransform != !aOther.mSpecifiedTransform || - (mSpecifiedTransform && - *mSpecifiedTransform != *aOther.mSpecifiedTransform)) { - NS_UpdateHint(transformHint, nsChangeHint_UpdateTransformLayer); - - if (mSpecifiedTransform && - aOther.mSpecifiedTransform) { - NS_UpdateHint(transformHint, nsChangeHint_UpdatePostTransformOverflow); - } else { - NS_UpdateHint(transformHint, nsChangeHint_UpdateOverflow); - } - } - - const nsChangeHint kUpdateOverflowAndRepaintHint = - NS_CombineHint(nsChangeHint_UpdateOverflow, nsChangeHint_RepaintFrame); - for (uint8_t index = 0; index < 3; ++index) - if (mTransformOrigin[index] != aOther.mTransformOrigin[index]) { - NS_UpdateHint(transformHint, kUpdateOverflowAndRepaintHint); - break; - } - - for (uint8_t index = 0; index < 2; ++index) - if (mPerspectiveOrigin[index] != aOther.mPerspectiveOrigin[index]) { - NS_UpdateHint(transformHint, kUpdateOverflowAndRepaintHint); - break; - } - - if (mChildPerspective != aOther.mChildPerspective || - mTransformStyle != aOther.mTransformStyle) - NS_UpdateHint(transformHint, kUpdateOverflowAndRepaintHint); - - if (mBackfaceVisibility != aOther.mBackfaceVisibility) - NS_UpdateHint(transformHint, nsChangeHint_RepaintFrame); - - if (transformHint) { - if (HasTransformStyle()) { - NS_UpdateHint(hint, transformHint); - } else { - NS_UpdateHint(hint, nsChangeHint_NeutralChange); - } - } - } - - // Note that the HasTransformStyle() != aOther.HasTransformStyle() - // test above handles relevant changes in the - // NS_STYLE_WILL_CHANGE_TRANSFORM bit, which in turn handles frame - // reconstruction for changes in the containing block of - // fixed-positioned elements. Other than that, all changes to - // 'will-change' can be handled by a repaint. - uint8_t willChangeBitsChanged = - mWillChangeBitField ^ aOther.mWillChangeBitField; - if (willChangeBitsChanged) { - NS_UpdateHint(hint, nsChangeHint_RepaintFrame); - } - if (mOrder != aOther.mOrder) { // "order" impacts both layout order and stacking order, so we need both a // reflow and a repaint when it changes. (Technically, we only need a @@ -1741,10 +1623,6 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons return NS_CombineHint(hint, nsChangeHint_AllReflowHints); } } - - if (!hint && !mClip.IsEqualEdges(aOther.mClip)) { - return nsChangeHint_NeutralChange; - } return hint; } @@ -1799,8 +1677,8 @@ nsStyleTableBorder::nsStyleTableBorder() mEmptyCells = NS_STYLE_TABLE_EMPTY_CELLS_SHOW; mCaptionSide = NS_STYLE_CAPTION_SIDE_TOP; - mBorderSpacingX = 0; - mBorderSpacingY = 0; + mBorderSpacingCol = 0; + mBorderSpacingRow = 0; } nsStyleTableBorder::~nsStyleTableBorder(void) @@ -1809,8 +1687,8 @@ nsStyleTableBorder::~nsStyleTableBorder(void) } nsStyleTableBorder::nsStyleTableBorder(const nsStyleTableBorder& aSource) - : mBorderSpacingX(aSource.mBorderSpacingX) - , mBorderSpacingY(aSource.mBorderSpacingY) + : mBorderSpacingCol(aSource.mBorderSpacingCol) + , mBorderSpacingRow(aSource.mBorderSpacingRow) , mBorderCollapse(aSource.mBorderCollapse) , mCaptionSide(aSource.mCaptionSide) , mEmptyCells(aSource.mEmptyCells) @@ -1829,8 +1707,8 @@ nsChangeHint nsStyleTableBorder::CalcDifference(const nsStyleTableBorder& aOther } if ((mCaptionSide == aOther.mCaptionSide) && - (mBorderSpacingX == aOther.mBorderSpacingX) && - (mBorderSpacingY == aOther.mBorderSpacingY)) { + (mBorderSpacingCol == aOther.mBorderSpacingCol) && + (mBorderSpacingRow == aOther.mBorderSpacingRow)) { if (mEmptyCells == aOther.mEmptyCells) return NS_STYLE_HINT_NONE; return NS_STYLE_HINT_VISUAL; @@ -2689,6 +2567,7 @@ mozilla::StyleAnimation::operator==(const mozilla::StyleAnimation& aOther) const } nsStyleDisplay::nsStyleDisplay() + : mWillChangeBitField(0) { MOZ_COUNT_CTOR(nsStyleDisplay); mAppearance = NS_THEME_NONE; @@ -2705,7 +2584,18 @@ nsStyleDisplay::nsStyleDisplay() mOverflowY = NS_STYLE_OVERFLOW_VISIBLE; mOverflowClipBox = NS_STYLE_OVERFLOW_CLIP_BOX_PADDING_BOX; mResize = NS_STYLE_RESIZE_NONE; + mClipFlags = NS_STYLE_CLIP_AUTO; + mClip.SetRect(0,0,0,0); mOpacity = 1.0f; + mSpecifiedTransform = nullptr; + mTransformOrigin[0].SetPercentValue(0.5f); // Transform is centered on origin + mTransformOrigin[1].SetPercentValue(0.5f); + mTransformOrigin[2].SetCoordValue(0); + mPerspectiveOrigin[0].SetPercentValue(0.5f); + mPerspectiveOrigin[1].SetPercentValue(0.5f); + mChildPerspective.SetNoneValue(); + mBackfaceVisibility = NS_STYLE_BACKFACE_VISIBILITY_VISIBLE; + mTransformStyle = NS_STYLE_TRANSFORM_STYLE_FLAT; mOrient = NS_STYLE_ORIENT_AUTO; mMixBlendMode = NS_STYLE_BLEND_NORMAL; mIsolation = NS_STYLE_ISOLATION_AUTO; @@ -2743,6 +2633,7 @@ nsStyleDisplay::nsStyleDisplay() nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource) : mBinding(aSource.mBinding) + , mClip(aSource.mClip) , mOpacity(aSource.mOpacity) , mDisplay(aSource.mDisplay) , mOriginalDisplay(aSource.mOriginalDisplay) @@ -2758,9 +2649,12 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource) , mOverflowY(aSource.mOverflowY) , mOverflowClipBox(aSource.mOverflowClipBox) , mResize(aSource.mResize) + , mClipFlags(aSource.mClipFlags) , mOrient(aSource.mOrient) , mMixBlendMode(aSource.mMixBlendMode) , mIsolation(aSource.mIsolation) + , mWillChangeBitField(aSource.mWillChangeBitField) + , mWillChange(aSource.mWillChange) , mTouchAction(aSource.mTouchAction) , mScrollBehavior(aSource.mScrollBehavior) , mScrollSnapTypeX(aSource.mScrollSnapTypeX) @@ -2769,6 +2663,10 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource) , mScrollSnapPointsY(aSource.mScrollSnapPointsY) , mScrollSnapDestination(aSource.mScrollSnapDestination) , mScrollSnapCoordinate(aSource.mScrollSnapCoordinate) + , mBackfaceVisibility(aSource.mBackfaceVisibility) + , mTransformStyle(aSource.mTransformStyle) + , mSpecifiedTransform(aSource.mSpecifiedTransform) + , mChildPerspective(aSource.mChildPerspective) , mTransitions(aSource.mTransitions) , mTransitionTimingFunctionCount(aSource.mTransitionTimingFunctionCount) , mTransitionDurationCount(aSource.mTransitionDurationCount) @@ -2785,6 +2683,13 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource) , mAnimationIterationCountCount(aSource.mAnimationIterationCountCount) { MOZ_COUNT_CTOR(nsStyleDisplay); + + /* Copy over transform origin. */ + mTransformOrigin[0] = aSource.mTransformOrigin[0]; + mTransformOrigin[1] = aSource.mTransformOrigin[1]; + mTransformOrigin[2] = aSource.mTransformOrigin[2]; + mPerspectiveOrigin[0] = aSource.mPerspectiveOrigin[0]; + mPerspectiveOrigin[1] = aSource.mPerspectiveOrigin[1]; } nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const @@ -2847,10 +2752,18 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const || mBreakAfter != aOther.mBreakAfter || mAppearance != aOther.mAppearance || mOrient != aOther.mOrient - || mOverflowClipBox != aOther.mOverflowClipBox) + || mOverflowClipBox != aOther.mOverflowClipBox + || mClipFlags != aOther.mClipFlags) NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_AllReflowHints, nsChangeHint_RepaintFrame)); + if (!mClip.IsEqualInterior(aOther.mClip)) { + // If the clip has changed, we just need to update overflow areas. DLBI + // will handle the invalidation. + NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_UpdateOverflow, + nsChangeHint_SchedulePaint)); + } + if (mOpacity != aOther.mOpacity) { // If we're going from the optimized >=0.99 opacity value to 1.0 or back, then // repaint the frame because DLBI will not catch the invalidation. Otherwise, @@ -2868,6 +2781,84 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const NS_UpdateHint(hint, nsChangeHint_RepaintFrame); } + /* If we've added or removed the transform property, we need to reconstruct the frame to add + * or remove the view object, and also to handle abs-pos and fixed-pos containers. + */ + if (HasTransformStyle() != aOther.HasTransformStyle()) { + // We do not need to apply nsChangeHint_UpdateTransformLayer since + // nsChangeHint_RepaintFrame will forcibly invalidate the frame area and + // ensure layers are rebuilt (or removed). + NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_AddOrRemoveTransform, + NS_CombineHint(nsChangeHint_UpdateOverflow, + nsChangeHint_RepaintFrame))); + } else { + /* Otherwise, if we've kept the property lying around and we already had a + * transform, we need to see whether or not we've changed the transform. + * If so, we need to recompute its overflow rect (which probably changed + * if the transform changed) and to redraw within the bounds of that new + * overflow rect. + * + * If the property isn't present in either style struct, we still do the + * comparisons but turn all the resulting change hints into + * nsChangeHint_NeutralChange. + */ + nsChangeHint transformHint = nsChangeHint(0); + + if (!mSpecifiedTransform != !aOther.mSpecifiedTransform || + (mSpecifiedTransform && + *mSpecifiedTransform != *aOther.mSpecifiedTransform)) { + NS_UpdateHint(transformHint, nsChangeHint_UpdateTransformLayer); + + if (mSpecifiedTransform && + aOther.mSpecifiedTransform) { + NS_UpdateHint(transformHint, nsChangeHint_UpdatePostTransformOverflow); + } else { + NS_UpdateHint(transformHint, nsChangeHint_UpdateOverflow); + } + } + + const nsChangeHint kUpdateOverflowAndRepaintHint = + NS_CombineHint(nsChangeHint_UpdateOverflow, nsChangeHint_RepaintFrame); + for (uint8_t index = 0; index < 3; ++index) + if (mTransformOrigin[index] != aOther.mTransformOrigin[index]) { + NS_UpdateHint(transformHint, kUpdateOverflowAndRepaintHint); + break; + } + + for (uint8_t index = 0; index < 2; ++index) + if (mPerspectiveOrigin[index] != aOther.mPerspectiveOrigin[index]) { + NS_UpdateHint(transformHint, kUpdateOverflowAndRepaintHint); + break; + } + + if (mChildPerspective != aOther.mChildPerspective || + mTransformStyle != aOther.mTransformStyle) + NS_UpdateHint(transformHint, kUpdateOverflowAndRepaintHint); + + if (mBackfaceVisibility != aOther.mBackfaceVisibility) + NS_UpdateHint(transformHint, nsChangeHint_RepaintFrame); + + if (transformHint) { + if (HasTransformStyle()) { + NS_UpdateHint(hint, transformHint); + } else { + NS_UpdateHint(hint, nsChangeHint_NeutralChange); + } + } + } + + // Note that the HasTransformStyle() != aOther.HasTransformStyle() + // test above handles relevant changes in the + // NS_STYLE_WILL_CHANGE_TRANSFORM bit, which in turn handles frame + // reconstruction for changes in the containing block of + // fixed-positioned elements. Other than that, all changes to + // 'will-change' can be handled by a repaint. + uint8_t willChangeBitsChanged = + mWillChangeBitField ^ aOther.mWillChangeBitField; + if (willChangeBitsChanged) { + NS_UpdateHint(hint, nsChangeHint_RepaintFrame); + } + // Note: Our current behavior for handling changes to the // transition-duration, transition-delay, and transition-timing-function // properties is to do nothing. In other words, the transition @@ -2886,7 +2877,8 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const // properties, since some data did change in the style struct. if (!hint && - (mOriginalDisplay != aOther.mOriginalDisplay || + (!mClip.IsEqualEdges(aOther.mClip) || + mOriginalDisplay != aOther.mOriginalDisplay || mOriginalFloats != aOther.mOriginalFloats || mTransitions != aOther.mTransitions || mTransitionTimingFunctionCount != diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index a55ffb02b92..bfa4cdfc2b2 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1335,14 +1335,9 @@ struct nsStylePosition { nsChangeHint CalcDifference(const nsStylePosition& aOther) const; static nsChangeHint MaxDifference() { - return nsChangeHint(NS_STYLE_HINT_REFLOW | - nsChangeHint_RecomputePosition | - nsChangeHint_UpdateTransformLayer | - nsChangeHint_UpdateOverflow | - nsChangeHint_UpdateParentOverflow | - nsChangeHint_UpdatePostTransformOverflow | - nsChangeHint_AddOrRemoveTransform | - nsChangeHint_NeutralChange); + return NS_CombineHint(NS_STYLE_HINT_REFLOW, + nsChangeHint(nsChangeHint_RecomputePosition | + nsChangeHint_UpdateParentOverflow)); } static nsChangeHint MaxDifferenceNeverInherited() { // CalcDifference can return both nsChangeHint_ClearAncestorIntrinsics and @@ -1355,7 +1350,6 @@ struct nsStylePosition { typedef nsStyleBackground::Position Position; Position mObjectPosition; // [reset] - nsRect mClip; // [reset] offsets from upper-left border edge nsStyleSides mOffset; // [reset] coord, percent, calc, auto nsStyleCoord mWidth; // [reset] coord, percent, enum, calc, auto nsStyleCoord mMinWidth; // [reset] coord, percent, enum, calc @@ -1368,9 +1362,6 @@ struct nsStylePosition { nsStyleCoord mGridAutoColumnsMax; // [reset] coord, percent, enum, calc, flex nsStyleCoord mGridAutoRowsMin; // [reset] coord, percent, enum, calc, flex nsStyleCoord mGridAutoRowsMax; // [reset] coord, percent, enum, calc, flex - nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only - nsStyleCoord mChildPerspective; // [reset] coord - nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc uint8_t mGridAutoFlow; // [reset] enumerated. See nsStyleConsts.h uint8_t mBoxSizing; // [reset] see nsStyleConsts.h uint8_t mAlignContent; // [reset] see nsStyleConsts.h @@ -1380,15 +1371,6 @@ struct nsStylePosition { uint8_t mFlexWrap; // [reset] see nsStyleConsts.h uint8_t mJustifyContent; // [reset] see nsStyleConsts.h uint8_t mObjectFit; // [reset] see nsStyleConsts.h - uint8_t mClipFlags; // [reset] see nsStyleConsts.h - uint8_t mBackfaceVisibility; // [reset] see nsStyleConsts.h - uint8_t mTransformStyle; // [reset] see nsStyleConsts.h - uint8_t mWillChangeBitField; // [reset] see nsStyleConsts.h. Stores a - // bitfield representation of the properties - // that are frequently queried. This should - // match mWillChange. Also tracks if any of the - // properties in the will-change list require - // a stacking context. int32_t mOrder; // [reset] integer float mFlexGrow; // [reset] float float mFlexShrink; // [reset] float @@ -1404,14 +1386,6 @@ struct nsStylePosition { nsStyleGridLine mGridRowStart; nsStyleGridLine mGridRowEnd; - // mSpecifiedTransform is the list of transform functions as - // specified, or null to indicate there is no transform. (inherit or - // initial are replaced by an actual list of transform functions, or - // null, as appropriate.) - nsRefPtr mSpecifiedTransform; // [reset] - - nsAutoTArray mWillChange; // see mWillChangeBitField - bool WidthDependsOnContainer() const { return mWidth.GetUnit() == eStyleUnit_Auto || @@ -1455,38 +1429,6 @@ struct nsStylePosition { return mOffset.Get(aSide).HasPercent(); } - /* Returns whether the element has the -moz-transform property - * or a related property. */ - bool HasTransformStyle() const { - return mSpecifiedTransform != nullptr || - mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D || - (mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM); - } - - bool HasPerspectiveStyle() const { - return mChildPerspective.GetUnit() == eStyleUnit_Coord; - } - - bool BackfaceIsHidden() const { - return mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN; - } - - // These methods are defined in nsStyleStructInlines.h. - - /** - * Returns true when the element has the transform property - * or a related property, and supports CSS transforms. - * aContextFrame is the frame for which this is the nsStylePosition. - */ - inline bool HasTransform(const nsIFrame* aContextFrame) const; - - /** - * Returns true when the element is a containing block for its fixed-pos - * descendants. - * aContextFrame is the frame for which this is the nsStylePosition. - */ - inline bool IsFixedPosContainingBlock(const nsIFrame* aContextFrame) const; - private: static bool WidthCoordDependsOnContainer(const nsStyleCoord &aCoord); static bool HeightCoordDependsOnContainer(const nsStyleCoord &aCoord) @@ -2064,6 +2006,10 @@ struct nsStyleDisplay { // All the parts of FRAMECHANGE are present in CalcDifference. return nsChangeHint(NS_STYLE_HINT_FRAMECHANGE | nsChangeHint_UpdateOpacityLayer | + nsChangeHint_UpdateTransformLayer | + nsChangeHint_UpdateOverflow | + nsChangeHint_UpdatePostTransformOverflow | + nsChangeHint_AddOrRemoveTransform | nsChangeHint_NeutralChange); } static nsChangeHint MaxDifferenceNeverInherited() { @@ -2080,6 +2026,7 @@ struct nsStyleDisplay { // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and // mBinding->mOriginPrincipal. nsRefPtr mBinding; // [reset] + nsRect mClip; // [reset] offsets from upper-left border edge float mOpacity; // [reset] uint8_t mDisplay; // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_* uint8_t mOriginalDisplay; // [reset] saved mDisplay for position:absolute/fixed @@ -2098,9 +2045,17 @@ struct nsStyleDisplay { uint8_t mOverflowY; // [reset] see nsStyleConsts.h uint8_t mOverflowClipBox; // [reset] see nsStyleConsts.h uint8_t mResize; // [reset] see nsStyleConsts.h + uint8_t mClipFlags; // [reset] see nsStyleConsts.h uint8_t mOrient; // [reset] see nsStyleConsts.h uint8_t mMixBlendMode; // [reset] see nsStyleConsts.h uint8_t mIsolation; // [reset] see nsStyleConsts.h + uint8_t mWillChangeBitField; // [reset] see nsStyleConsts.h. Stores a + // bitfield representation of the properties + // that are frequently queried. This should + // match mWillChange. Also tracks if any of the + // properties in the will-change list require + // a stacking context. + nsAutoTArray mWillChange; uint8_t mTouchAction; // [reset] see nsStyleConsts.h uint8_t mScrollBehavior; // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_BEHAVIOR_* @@ -2111,6 +2066,17 @@ struct nsStyleDisplay { Position mScrollSnapDestination; // [reset] nsTArray mScrollSnapCoordinate; // [reset] + // mSpecifiedTransform is the list of transform functions as + // specified, or null to indicate there is no transform. (inherit or + // initial are replaced by an actual list of transform functions, or + // null, as appropriate.) + uint8_t mBackfaceVisibility; + uint8_t mTransformStyle; + nsRefPtr mSpecifiedTransform; // [reset] + nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only + nsStyleCoord mChildPerspective; // [reset] coord + nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc + nsAutoTArray mTransitions; // [reset] // The number of elements in mTransitions that are not from repeating // a list due to another property being longer. @@ -2229,6 +2195,22 @@ struct nsStyleDisplay { mOverflowX != NS_STYLE_OVERFLOW_CLIP; } + /* Returns whether the element has the -moz-transform property + * or a related property. */ + bool HasTransformStyle() const { + return mSpecifiedTransform != nullptr || + mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D || + (mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM); + } + + bool HasPerspectiveStyle() const { + return mChildPerspective.GetUnit() == eStyleUnit_Coord; + } + + bool BackfaceIsHidden() const { + return mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN; + } + // These are defined in nsStyleStructInlines.h. // The aContextFrame argument on each of these is the frame this @@ -2244,6 +2226,22 @@ struct nsStyleDisplay { inline bool IsAbsPosContainingBlock(const nsIFrame* aContextFrame) const; inline bool IsRelativelyPositioned(const nsIFrame* aContextFrame) const; inline bool IsAbsolutelyPositioned(const nsIFrame* aContextFrame) const; + + // These methods are defined in nsStyleStructInlines.h. + + /** + * Returns true when the element has the transform property + * or a related property, and supports CSS transforms. + * aContextFrame is the frame for which this is the nsStylePosition. + */ + inline bool HasTransform(const nsIFrame* aContextFrame) const; + + /** + * Returns true when the element is a containing block for its fixed-pos + * descendants. + * aContextFrame is the frame for which this is the nsStylePosition. + */ + inline bool IsFixedPosContainingBlock(const nsIFrame* aContextFrame) const; }; struct nsStyleTable { @@ -2302,8 +2300,8 @@ struct nsStyleTableBorder { nsChangeHint_ClearAncestorIntrinsics); } - nscoord mBorderSpacingX;// [inherited] - nscoord mBorderSpacingY;// [inherited] + nscoord mBorderSpacingCol;// [inherited] + nscoord mBorderSpacingRow;// [inherited] uint8_t mBorderCollapse;// [inherited] uint8_t mCaptionSide; // [inherited] uint8_t mEmptyCells; // [inherited] diff --git a/layout/style/nsStyleStructInlines.h b/layout/style/nsStyleStructInlines.h index b3c35fe4781..8a52f9934ec 100644 --- a/layout/style/nsStyleStructInlines.h +++ b/layout/style/nsStyleStructInlines.h @@ -30,21 +30,6 @@ nsStyleImage::GetSubImage(uint8_t aIndex) const return subImage; } -bool -nsStylePosition::HasTransform(const nsIFrame* aContextFrame) const -{ - NS_ASSERTION(aContextFrame->StylePosition() == this, "unexpected aContextFrame"); - return HasTransformStyle() && aContextFrame->IsFrameOfType(nsIFrame::eSupportsCSSTransforms); -} - -bool -nsStylePosition::IsFixedPosContainingBlock(const nsIFrame* aContextFrame) const -{ - return (HasTransform(aContextFrame) || HasPerspectiveStyle() || - !aContextFrame->StyleSVGReset()->mFilters.IsEmpty()) && - !aContextFrame->IsSVGText(); -} - bool nsStyleText::HasTextShadow() const { @@ -142,15 +127,28 @@ nsStyleDisplay::IsFloating(const nsIFrame* aContextFrame) const // If you change this function, also change the corresponding block in // nsCSSFrameConstructor::ConstructFrameFromItemInternal that references // this function in comments. +bool +nsStyleDisplay::HasTransform(const nsIFrame* aContextFrame) const +{ + NS_ASSERTION(aContextFrame->StyleDisplay() == this, "unexpected aContextFrame"); + return HasTransformStyle() && aContextFrame->IsFrameOfType(nsIFrame::eSupportsCSSTransforms); +} + +bool +nsStyleDisplay::IsFixedPosContainingBlock(const nsIFrame* aContextFrame) const +{ + return (HasTransform(aContextFrame) || HasPerspectiveStyle() || + !aContextFrame->StyleSVGReset()->mFilters.IsEmpty()) && + !aContextFrame->IsSVGText(); +} + bool nsStyleDisplay::IsAbsPosContainingBlock(const nsIFrame* aContextFrame) const { NS_ASSERTION(aContextFrame->StyleDisplay() == this, "unexpected aContextFrame"); return ((IsAbsolutelyPositionedStyle() || IsRelativelyPositionedStyle()) && - !aContextFrame->IsSVGText()) || - aContextFrame->StylePosition()-> - IsFixedPosContainingBlock(aContextFrame); + !aContextFrame->IsSVGText()) || IsFixedPosContainingBlock(aContextFrame); } bool diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp index 54fa80f28f6..1ef66bb7524 100644 --- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -347,6 +347,8 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement, "must have element transitions if we started any transitions"); if (collection) { + UpdateCascadeResultsWithTransitions(collection); + // Set the style rule refresh time to null so that EnsureStyleRuleFor // creates a new style rule if we started *or* stopped transitions. collection->mStyleRuleRefreshTime = TimeStamp(); @@ -545,6 +547,7 @@ nsTransitionManager::ConsiderStartingTransition( AnimationProperty& prop = *pt->Properties().AppendElement(); prop.mProperty = aProperty; + prop.mWinsInCascade = true; AnimationPropertySegment& segment = *prop.mSegments.AppendElement(); segment.mFromValue = startValue; @@ -599,6 +602,97 @@ nsTransitionManager::ConsiderStartingTransition( aWhichStarted->AddProperty(aProperty); } +void +nsTransitionManager::UpdateCascadeResultsWithTransitions( + AnimationPlayerCollection* aTransitions) +{ + AnimationPlayerCollection* animations = + mPresContext->AnimationManager()-> + GetAnimationPlayers(aTransitions->mElement, + aTransitions->PseudoElementType(), false); + UpdateCascadeResults(aTransitions, animations); +} + +void +nsTransitionManager::UpdateCascadeResultsWithAnimations( + const AnimationPlayerCollection* aAnimations) +{ + AnimationPlayerCollection* transitions = + mPresContext->TransitionManager()-> + GetAnimationPlayers(aAnimations->mElement, + aAnimations->PseudoElementType(), false); + UpdateCascadeResults(transitions, aAnimations); +} + +void +nsTransitionManager::UpdateCascadeResultsWithAnimationsToBeDestroyed( + const AnimationPlayerCollection* aAnimations) +{ + // aAnimations is about to be destroyed. So get transitions from it, + // but then don't pass it to UpdateCascadeResults, since it has + // information that may now be incorrect. + AnimationPlayerCollection* transitions = + mPresContext->TransitionManager()-> + GetAnimationPlayers(aAnimations->mElement, + aAnimations->PseudoElementType(), false); + UpdateCascadeResults(transitions, nullptr); +} + +void +nsTransitionManager::UpdateCascadeResults( + AnimationPlayerCollection* aTransitions, + const AnimationPlayerCollection* aAnimations) +{ + if (!aTransitions) { + // Nothing to do. + return; + } + + nsCSSPropertySet propertiesUsed; +#ifdef DEBUG + nsCSSPropertySet propertiesWithTransitions; +#endif + + // http://dev.w3.org/csswg/css-transitions/#application says that + // transitions do not apply when the same property has a CSS Animation + // on that element (even though animations are lower in the cascade). + if (aAnimations && aAnimations->mStyleRule) { + aAnimations->mStyleRule->AddPropertiesToSet(propertiesUsed); + } + + // Since we should never have more than one transition for the same + // property, it doesn't matter what order we iterate the transitions. + // But let's go the same way as animations. + bool changed = false; + AnimationPlayerPtrArray& players = aTransitions->mPlayers; + for (size_t playerIdx = players.Length(); playerIdx-- != 0; ) { + MOZ_ASSERT(players[playerIdx]->GetSource() && + players[playerIdx]->GetSource()->Properties().Length() == 1, + "Should have one animation property for a transition"); + AnimationProperty& prop = players[playerIdx]->GetSource()->Properties()[0]; + bool newWinsInCascade = !propertiesUsed.HasProperty(prop.mProperty); + if (prop.mWinsInCascade != newWinsInCascade) { + changed = true; + } + prop.mWinsInCascade = newWinsInCascade; + // assert that we don't need to bother adding the transitioned + // properties into propertiesUsed +#ifdef DEBUG + MOZ_ASSERT(!propertiesWithTransitions.HasProperty(prop.mProperty), + "we're assuming we have only one transition per property"); + propertiesWithTransitions.AddProperty(prop.mProperty); +#endif + } + + if (changed) { + aTransitions->UpdateAnimationGeneration(mPresContext); + + // Invalidate our style rule. + aTransitions->mStyleRuleRefreshTime = TimeStamp(); + aTransitions->mNeedsRefreshes = true; + } +} + /* * nsIStyleRuleProcessor implementation */ diff --git a/layout/style/nsTransitionManager.h b/layout/style/nsTransitionManager.h index 83490f002d1..93c69d9d989 100644 --- a/layout/style/nsTransitionManager.h +++ b/layout/style/nsTransitionManager.h @@ -128,6 +128,15 @@ public: nsStyleContext *aOldStyleContext, nsRefPtr* aNewStyleContext /* inout */); + void UpdateCascadeResultsWithTransitions( + AnimationPlayerCollection* aTransitions); + void UpdateCascadeResultsWithAnimations( + const AnimationPlayerCollection* aAnimations); + void UpdateCascadeResultsWithAnimationsToBeDestroyed( + const AnimationPlayerCollection* aAnimations); + void UpdateCascadeResults(AnimationPlayerCollection* aTransitions, + const AnimationPlayerCollection* aAnimations); + void SetInAnimationOnlyStyleUpdate(bool aInAnimationOnlyUpdate) { mInAnimationOnlyStyleUpdate = aInAnimationOnlyUpdate; } diff --git a/layout/style/test/test_animations.html b/layout/style/test/test_animations.html index 2310464f175..a5f58fc603f 100644 --- a/layout/style/test/test_animations.html +++ b/layout/style/test/test_animations.html @@ -158,6 +158,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=435442 @keyframes overridetop { 0%, 100% { top: 0px } } + + @keyframes opacitymid { + 0% { opacity: 0.2 } + 100% { opacity: 0.8 } + } @@ -2011,6 +2016,22 @@ ancestor.parentNode.removeChild(ancestor); done_div(); +/* + * Bug 1125455 - Transitions should not run when animations are running. + */ +new_div("transition: opacity 2s linear; opacity: 0.8"); +advance_clock(0); +is(cs.getPropertyValue("opacity"), "0.8", "initial opacity"); +div.style.opacity = "0.2"; +is(cs.getPropertyValue("opacity"), "0.8", "opacity transition at 0s"); +advance_clock(500); +is(cs.getPropertyValue("opacity"), "0.65", "opacity transition at 0.5s"); +div.style.animation = "opacitymid 2s linear"; +is(cs.getPropertyValue("opacity"), "0.2", "opacity animation overriding transition at 0s"); +advance_clock(500); +is(cs.getPropertyValue("opacity"), "0.35", "opacity animation overriding transition at 0.5s"); +done_div(); + SpecialPowers.DOMWindowUtils.restoreNormalRefresh(); diff --git a/layout/style/test/test_animations_omta.html b/layout/style/test/test_animations_omta.html index 9dd19d4e8f2..b56aed0e642 100644 --- a/layout/style/test/test_animations_omta.html +++ b/layout/style/test/test_animations_omta.html @@ -154,6 +154,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=964646 #visitedLink:link { background-color: yellow } #visitedLink:visited { background-color: blue } + + @keyframes opacitymid { + 0% { opacity: 0.2 } + 100% { opacity: 0.8 } + } @@ -2129,5 +2134,28 @@ addAsyncAnimTest(function *() { done_div(); }); +// Bug 1125455 - Transitions should not run when animations are running. +addAsyncAnimTest(function *() { + new_div("transition: opacity 2s linear; opacity: 0.8"); + yield waitForPaintsFlushed(); + omta_is("opacity", 0.8, RunningOn.MainThread, + "initial opacity"); + gDiv.style.opacity = "0.2"; + yield waitForPaintsFlushed(); + omta_is("opacity", 0.8, RunningOn.Compositor, + "opacity transition at 0s"); + advance_clock(500); + omta_is("opacity", 0.65, RunningOn.Compositor, + "opacity transition at 0.5s"); + gDiv.style.animation = "opacitymid 2s linear"; + yield waitForPaintsFlushed(); + omta_is("opacity", 0.2, RunningOn.Compositor, + "opacity animation overriding transition at 0s"); + advance_clock(500); + omta_is("opacity", 0.35, RunningOn.Compositor, + "opacity animation overriding transition at 0.5s"); + done_div(); +}); + diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index 4b93cc726ec..5b0b6b0e272 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -827,10 +827,9 @@ nsSVGUtils::GetClipRectForFrame(nsIFrame *aFrame, float aX, float aY, float aWidth, float aHeight) { const nsStyleDisplay* disp = aFrame->StyleDisplay(); - const nsStylePosition* pos = aFrame->StylePosition(); - if (!(pos->mClipFlags & NS_STYLE_CLIP_RECT)) { - NS_ASSERTION(pos->mClipFlags == NS_STYLE_CLIP_AUTO, + if (!(disp->mClipFlags & NS_STYLE_CLIP_RECT)) { + NS_ASSERTION(disp->mClipFlags == NS_STYLE_CLIP_AUTO, "We don't know about this type of clip."); return gfxRect(aX, aY, aWidth, aHeight); } @@ -839,14 +838,14 @@ nsSVGUtils::GetClipRectForFrame(nsIFrame *aFrame, disp->mOverflowY == NS_STYLE_OVERFLOW_HIDDEN) { nsIntRect clipPxRect = - pos->mClip.ToOutsidePixels(aFrame->PresContext()->AppUnitsPerDevPixel()); + disp->mClip.ToOutsidePixels(aFrame->PresContext()->AppUnitsPerDevPixel()); gfxRect clipRect = gfxRect(clipPxRect.x, clipPxRect.y, clipPxRect.width, clipPxRect.height); - if (NS_STYLE_CLIP_RIGHT_AUTO & pos->mClipFlags) { + if (NS_STYLE_CLIP_RIGHT_AUTO & disp->mClipFlags) { clipRect.width = aWidth - clipRect.X(); } - if (NS_STYLE_CLIP_BOTTOM_AUTO & pos->mClipFlags) { + if (NS_STYLE_CLIP_BOTTOM_AUTO & disp->mClipFlags) { clipRect.height = aHeight - clipRect.Y(); } diff --git a/layout/tables/BasicTableLayoutStrategy.cpp b/layout/tables/BasicTableLayoutStrategy.cpp index 021e1b52e83..e5e822ffb57 100644 --- a/layout/tables/BasicTableLayoutStrategy.cpp +++ b/layout/tables/BasicTableLayoutStrategy.cpp @@ -440,7 +440,7 @@ BasicTableLayoutStrategy::ComputeIntrinsicISizes(nsRenderingContext* aRenderingC int32_t colCount = cellMap->GetColCount(); // add a total of (colcount + 1) lots of cellSpacingX for columns where a // cell originates - nscoord add = mTableFrame->GetCellSpacingX(colCount); + nscoord add = mTableFrame->GetColSpacing(colCount); for (int32_t col = 0; col < colCount; ++col) { nsTableColFrame *colFrame = mTableFrame->GetColFrame(col); @@ -449,7 +449,7 @@ BasicTableLayoutStrategy::ComputeIntrinsicISizes(nsRenderingContext* aRenderingC continue; } if (mTableFrame->ColumnHasCellSpacingBefore(col)) { - add += mTableFrame->GetCellSpacingX(col - 1); + add += mTableFrame->GetColSpacing(col - 1); } min += colFrame->GetMinCoord(); pref = NSCoordSaturatingAdd(pref, colFrame->GetPrefCoord()); @@ -665,15 +665,15 @@ BasicTableLayoutStrategy::DistributeWidthToColumns(nscoord aWidth, for (int32_t col = aFirstCol + 1; col < aFirstCol + aColCount; ++col) { if (mTableFrame->ColumnHasCellSpacingBefore(col)) { // border-spacing isn't part of the basis for percentages. - subtract += mTableFrame->GetCellSpacingX(col - 1); + subtract += mTableFrame->GetColSpacing(col - 1); } } if (aWidthType == BTLS_FINAL_WIDTH) { // If we're computing final col-width, then aWidth initially includes // border spacing on the table's far left + far right edge, too. Need // to subtract those out, too. - subtract += (mTableFrame->GetCellSpacingX(-1) + - mTableFrame->GetCellSpacingX(aColCount)); + subtract += (mTableFrame->GetColSpacing(-1) + + mTableFrame->GetColSpacing(aColCount)); } aWidth = NSCoordSaturatingSubtract(aWidth, subtract, nscoord_MAX); diff --git a/layout/tables/FixedTableLayoutStrategy.cpp b/layout/tables/FixedTableLayoutStrategy.cpp index 9ed8c282a78..1f883766705 100644 --- a/layout/tables/FixedTableLayoutStrategy.cpp +++ b/layout/tables/FixedTableLayoutStrategy.cpp @@ -55,7 +55,7 @@ FixedTableLayoutStrategy::GetMinISize(nsRenderingContext* aRenderingContext) nscoord result = 0; if (colCount > 0) { - result += mTableFrame->GetCellSpacingX(-1, colCount); + result += mTableFrame->GetColSpacing(-1, colCount); } for (int32_t col = 0; col < colCount; ++col) { @@ -64,7 +64,7 @@ FixedTableLayoutStrategy::GetMinISize(nsRenderingContext* aRenderingContext) NS_ERROR("column frames out of sync with cell map"); continue; } - nscoord spacing = mTableFrame->GetCellSpacingX(col); + nscoord spacing = mTableFrame->GetColSpacing(col); const nsStyleCoord *styleWidth = &colFrame->StylePosition()->mWidth; if (styleWidth->ConvertsToLength()) { @@ -168,7 +168,7 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt } // border-spacing isn't part of the basis for percentages. - tableWidth -= mTableFrame->GetCellSpacingX(-1, colCount); + tableWidth -= mTableFrame->GetColSpacing(-1, colCount); // store the old column widths. We might call multiple times SetFinalWidth // on the columns, due to this we can't compare at the last call that the @@ -280,7 +280,7 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt // row, split up the space evenly. (XXX This // isn't quite right if some of the columns it's // in have specified widths. Should we care?) - nscoord spacing = mTableFrame->GetCellSpacingX(col); + nscoord spacing = mTableFrame->GetColSpacing(col); colWidth = ((colWidth + spacing) / colSpan) - spacing; if (colWidth < 0) colWidth = 0; diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index f3ede239221..2c17c347b8b 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -840,8 +840,8 @@ CalcUnpaginagedHeight(nsPresContext* aPresContext, firstCellInFlow->GetRowIndex(rowIndex); int32_t rowSpan = aTableFrame.GetEffectiveRowSpan(*firstCellInFlow); - nscoord computedHeight = firstTableInFlow->GetCellSpacingY(rowIndex, - rowIndex + rowSpan - 1); + nscoord computedHeight = firstTableInFlow->GetRowSpacing(rowIndex, + rowIndex + rowSpan - 1); computedHeight -= aVerticalBorderPadding; int32_t rowX; for (row = firstRGInFlow->GetFirstRow(), rowX = 0; row; row = row->GetNextRow(), rowX++) { diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 4c81a701f30..8e5dad3818d 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -86,23 +86,23 @@ struct nsTableReflowState { nsTableFrame* table = static_cast(aTableFrame.FirstInFlow()); nsMargin borderPadding = table->GetChildAreaOffset(&reflowState); - x = borderPadding.left + table->GetCellSpacingX(-1); + x = borderPadding.left + table->GetColSpacing(-1); y = borderPadding.top; //cellspacing added during reflow availSize.width = aAvailWidth; if (NS_UNCONSTRAINEDSIZE != availSize.width) { int32_t colCount = table->GetColCount(); availSize.width -= borderPadding.left + borderPadding.right - + table->GetCellSpacingX(-1) - + table->GetCellSpacingX(colCount); + + table->GetColSpacing(-1) + + table->GetColSpacing(colCount); availSize.width = std::max(0, availSize.width); } availSize.height = aAvailHeight; if (NS_UNCONSTRAINEDSIZE != availSize.height) { availSize.height -= borderPadding.top + borderPadding.bottom - + table->GetCellSpacingY(-1) - + table->GetCellSpacingY(table->GetRowCount()); + + table->GetRowSpacing(-1) + + table->GetRowSpacing(table->GetRowCount()); availSize.height = std::max(0, availSize.height); } } @@ -1423,17 +1423,17 @@ nsTableFrame::SetColumnDimensions(nscoord aHeight, const nsMargin& aBorderPadding) { nscoord colHeight = aHeight -= aBorderPadding.top + aBorderPadding.bottom + - GetCellSpacingY(-1) + - GetCellSpacingY(GetRowCount()); + GetRowSpacing(-1) + + GetRowSpacing(GetRowCount()); nsTableIterator iter(mColGroups); nsIFrame* colGroupFrame = iter.First(); bool tableIsLTR = StyleVisibility()->mDirection == NS_STYLE_DIRECTION_LTR; int32_t colX =tableIsLTR ? 0 : std::max(0, GetColCount() - 1); - nscoord cellSpacingX = GetCellSpacingX(colX); + nscoord cellSpacingX = GetColSpacing(colX); int32_t tableColIncr = tableIsLTR ? 1 : -1; - nsPoint colGroupOrigin(aBorderPadding.left + GetCellSpacingX(-1), - aBorderPadding.top + GetCellSpacingY(-1)); + nsPoint colGroupOrigin(aBorderPadding.left + GetColSpacing(-1), + aBorderPadding.top + GetRowSpacing(-1)); while (colGroupFrame) { MOZ_ASSERT(colGroupFrame->GetType() == nsGkAtoms::tableColGroupFrame); nscoord colGroupWidth = 0; @@ -1447,7 +1447,7 @@ nsTableFrame::SetColumnDimensions(nscoord aHeight, nscoord colWidth = GetColumnWidth(colX); nsRect colRect(colOrigin.x, colOrigin.y, colWidth, colHeight); colFrame->SetRect(colRect); - cellSpacingX = GetCellSpacingX(colX); + cellSpacingX = GetColSpacing(colX); colOrigin.x += colWidth + cellSpacingX; colGroupWidth += colWidth + cellSpacingX; colX += tableColIncr; @@ -1878,7 +1878,7 @@ nsTableFrame::Reflow(nsPresContext* aPresContext, if (lastChildReflowed && NS_FRAME_IS_NOT_COMPLETE(aStatus)) { // if there is an incomplete child, then set the desired height to include it but not the next one nsMargin borderPadding = GetChildAreaOffset(&aReflowState); - aDesiredSize.Height() = borderPadding.bottom + GetCellSpacingY(GetRowCount()) + + aDesiredSize.Height() = borderPadding.bottom + GetRowSpacing(GetRowCount()) + lastChildReflowed->GetNormalRect().YMost(); } haveDesiredHeight = true; @@ -2141,8 +2141,8 @@ nsTableFrame::AdjustForCollapsingRowsCols(nsHTMLReflowMetrics& aDesiredSize, nsTableFrame* firstInFlow = static_cast(FirstInFlow()); nscoord width = firstInFlow->GetCollapsedWidth(aBorderPadding); - nscoord rgWidth = width - GetCellSpacingX(-1) - - GetCellSpacingX(GetColCount()); + nscoord rgWidth = width - GetColSpacing(-1) - + GetColSpacing(GetColCount()); nsOverflowAreas overflow; // Walk the list of children for (uint32_t childX = 0; childX < rowGroups.Length(); childX++) { @@ -2164,7 +2164,7 @@ nscoord nsTableFrame::GetCollapsedWidth(nsMargin aBorderPadding) { NS_ASSERTION(!GetPrevInFlow(), "GetCollapsedWidth called on next in flow"); - nscoord width = GetCellSpacingX(GetColCount()); + nscoord width = GetColSpacing(GetColCount()); width += aBorderPadding.left + aBorderPadding.right; for (nsIFrame* groupFrame = mColGroups.FirstChild(); groupFrame; groupFrame = groupFrame->GetNextSibling()) { @@ -2182,7 +2182,7 @@ nsTableFrame::GetCollapsedWidth(nsMargin aBorderPadding) if (!collapseGroup && !collapseCol) { width += colWidth; if (ColumnHasCellSpacingBefore(colX)) - width += GetCellSpacingX(colX-1); + width += GetColSpacing(colX-1); } else { SetNeedToCollapse(true); @@ -2867,7 +2867,7 @@ nsTableFrame::PlaceRepeatedFooter(nsTableReflowState& aReflowState, -1, -1, nsHTMLReflowState::CALLER_WILL_INIT); InitChildReflowState(footerReflowState); - aReflowState.y += GetCellSpacingY(GetRowCount()); + aReflowState.y += GetRowSpacing(GetRowCount()); nsRect origTfootRect = aTfoot->GetRect(); nsRect origTfootVisualOverflow = aTfoot->GetVisualOverflowRect(); @@ -2944,8 +2944,8 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState, for (size_t childX = 0; childX < rowGroups.Length(); childX++) { nsIFrame* kidFrame = rowGroups[childX]; nsTableRowGroupFrame* rowGroupFrame = rowGroups[childX]; - nscoord cellSpacingY = GetCellSpacingY(rowGroupFrame->GetStartRowIndex()+ - rowGroupFrame->GetRowCount()); + nscoord cellSpacingY = GetRowSpacing(rowGroupFrame->GetStartRowIndex()+ + rowGroupFrame->GetRowCount()); // Get the frame state bits // See if we should only reflow the dirty child frames if (reflowAllKids || @@ -3228,11 +3228,11 @@ nsTableFrame::CalcDesiredHeight(const nsHTMLReflowState& aReflowState, nsHTMLRef int32_t colCount = cellMap->GetColCount(); nscoord desiredHeight = borderPadding.top + borderPadding.bottom; if (rowCount > 0 && colCount > 0) { - desiredHeight += GetCellSpacingY(-1); + desiredHeight += GetRowSpacing(-1); for (uint32_t rgX = 0; rgX < rowGroups.Length(); rgX++) { desiredHeight += rowGroups[rgX]->GetSize().height + - GetCellSpacingY(rowGroups[rgX]->GetRowCount() + - rowGroups[rgX]->GetStartRowIndex()); + GetRowSpacing(rowGroups[rgX]->GetRowCount() + + rowGroups[rgX]->GetStartRowIndex()); } } @@ -3298,8 +3298,8 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState, // distribute space to each pct height row whose row group doesn't have a computed // height, and base the pct on the table height. If the row group had a computed // height, then this was already done in nsTableRowGroupFrame::CalculateRowHeights - nscoord pctBasis = aReflowState.ComputedHeight() - GetCellSpacingY(-1, GetRowCount()); - nscoord yOriginRG = borderPadding.top + GetCellSpacingY(0); + nscoord pctBasis = aReflowState.ComputedHeight() - GetRowSpacing(-1, GetRowCount()); + nscoord yOriginRG = borderPadding.top + GetRowSpacing(0); nscoord yEndRG = yOriginRG; uint32_t rgX; for (rgX = 0; rgX < rowGroups.Length(); rgX++) { @@ -3311,7 +3311,7 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState, nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); while (rowFrame) { nsRect rowNormalRect = rowFrame->GetNormalRect(); - nscoord cellSpacingY = GetCellSpacingY(rowFrame->GetRowIndex()); + nscoord cellSpacingY = GetRowSpacing(rowFrame->GetRowIndex()); if ((amountUsed < aAmount) && rowFrame->HasPctHeight()) { nscoord pctHeight = rowFrame->GetHeight(pctBasis); nscoord amountForRow = std::min(aAmount - amountUsed, @@ -3437,7 +3437,7 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState, } // allocate the extra height to the unstyled row groups and rows nscoord heightToDistribute = aAmount - amountUsed; - yOriginRG = borderPadding.top + GetCellSpacingY(-1); + yOriginRG = borderPadding.top + GetRowSpacing(-1); yEndRG = yOriginRG; for (rgX = 0; rgX < rowGroups.Length(); rgX++) { nsTableRowGroupFrame* rgFrame = rowGroups[rgX]; @@ -3449,7 +3449,7 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState, if (!firstUnStyledRG || !rgFrame->HasStyleHeight() || !eligibleRows) { nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); while (rowFrame) { - nscoord cellSpacingY = GetCellSpacingY(rowFrame->GetRowIndex()); + nscoord cellSpacingY = GetRowSpacing(rowFrame->GetRowIndex()); nsRect rowNormalRect = rowFrame->GetNormalRect(); nsRect rowVisualOverflow = rowFrame->GetVisualOverflowRect(); // see if there is an eligible row or we distribute to all rows @@ -3547,26 +3547,26 @@ int32_t nsTableFrame::GetColumnWidth(int32_t aColIndex) return firstInFlow->GetColumnWidth(aColIndex); } -nscoord nsTableFrame::GetCellSpacingX() +nscoord nsTableFrame::GetColSpacing() { if (IsBorderCollapse()) return 0; - return StyleTableBorder()->mBorderSpacingX; + return StyleTableBorder()->mBorderSpacingCol; } // XXX: could cache this. But be sure to check style changes if you do! -nscoord nsTableFrame::GetCellSpacingX(int32_t aColIndex) +nscoord nsTableFrame::GetColSpacing(int32_t aColIndex) { NS_ASSERTION(aColIndex >= -1 && aColIndex <= GetColCount(), "Column index exceeds the bounds of the table"); // Index is irrelevant for ordinary tables. We check that it falls within // appropriate bounds to increase confidence of correctness in situations // where it does matter. - return GetCellSpacingX(); + return GetColSpacing(); } -nscoord nsTableFrame::GetCellSpacingX(int32_t aStartColIndex, +nscoord nsTableFrame::GetColSpacing(int32_t aStartColIndex, int32_t aEndColIndex) { NS_ASSERTION(aStartColIndex >= -1 && aStartColIndex <= GetColCount(), @@ -3577,29 +3577,29 @@ nscoord nsTableFrame::GetCellSpacingX(int32_t aStartColIndex, "End index must not be less than start index"); // Only one possible value so just multiply it out. Tables where index // matters will override this function - return GetCellSpacingX() * (aEndColIndex - aStartColIndex); + return GetColSpacing() * (aEndColIndex - aStartColIndex); } -nscoord nsTableFrame::GetCellSpacingY() +nscoord nsTableFrame::GetRowSpacing() { if (IsBorderCollapse()) return 0; - return StyleTableBorder()->mBorderSpacingY; + return StyleTableBorder()->mBorderSpacingRow; } // XXX: could cache this. But be sure to check style changes if you do! -nscoord nsTableFrame::GetCellSpacingY(int32_t aRowIndex) +nscoord nsTableFrame::GetRowSpacing(int32_t aRowIndex) { NS_ASSERTION(aRowIndex >= -1 && aRowIndex <= GetRowCount(), "Row index exceeds the bounds of the table"); // Index is irrelevant for ordinary tables. We check that it falls within // appropriate bounds to increase confidence of correctness in situations // where it does matter. - return GetCellSpacingY(); + return GetRowSpacing(); } -nscoord nsTableFrame::GetCellSpacingY(int32_t aStartRowIndex, +nscoord nsTableFrame::GetRowSpacing(int32_t aStartRowIndex, int32_t aEndRowIndex) { NS_ASSERTION(aStartRowIndex >= -1 && aStartRowIndex <= GetRowCount(), @@ -3610,7 +3610,7 @@ nscoord nsTableFrame::GetCellSpacingY(int32_t aStartRowIndex, "End index must not be less than start index"); // Only one possible value so just multiply it out. Tables where index // matters will override this function - return GetCellSpacingY() * (aEndRowIndex - aStartRowIndex); + return GetRowSpacing() * (aEndRowIndex - aStartRowIndex); } /* virtual */ nscoord diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index 185380592a7..ee20f9893b5 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -386,7 +386,7 @@ public: /** return the width of the column at aColIndex */ int32_t GetColumnWidth(int32_t aColIndex); - /** Helper to get the cell spacing X style value. + /** Helper to get the column spacing style value. * The argument refers to the space between column aColIndex and column * aColIndex + 1. An index of -1 indicates the padding between the table * and the left border, an index equal to the number of columns indicates @@ -395,7 +395,7 @@ public: * Although in this class cell spacing does not depend on the index, it * may be important for overriding classes. */ - virtual nscoord GetCellSpacingX(int32_t aColIndex); + virtual nscoord GetColSpacing(int32_t aColIndex); /** Helper to find the sum of the cell spacing between arbitrary columns. * The argument refers to the space between column aColIndex and column @@ -406,14 +406,14 @@ public: * This method is equivalent to * nscoord result = 0; * for (i = aStartColIndex; i < aEndColIndex; i++) { - * result += GetCellSpacingX(i); + * result += GetColSpacing(i); * } * return result; */ - virtual nscoord GetCellSpacingX(int32_t aStartColIndex, - int32_t aEndColIndex); + virtual nscoord GetColSpacing(int32_t aStartColIndex, + int32_t aEndColIndex); - /** Helper to get the cell spacing Y style value. + /** Helper to get the row spacing style value. * The argument refers to the space between row aRowIndex and row * aRowIndex + 1. An index of -1 indicates the padding between the table * and the top border, an index equal to the number of rows indicates @@ -422,7 +422,7 @@ public: * Although in this class cell spacing does not depend on the index, it * may be important for overriding classes. */ - virtual nscoord GetCellSpacingY(int32_t aRowIndex); + virtual nscoord GetRowSpacing(int32_t aRowIndex); /** Helper to find the sum of the cell spacing between arbitrary rows. * The argument refers to the space between row aRowIndex and row @@ -433,19 +433,19 @@ public: * This method is equivalent to * nscoord result = 0; * for (i = aStartRowIndex; i < aEndRowIndex; i++) { - * result += GetCellSpacingY(i); + * result += GetRowSpacing(i); * } * return result; */ - virtual nscoord GetCellSpacingY(int32_t aStartRowIndex, + virtual nscoord GetRowSpacing(int32_t aStartRowIndex, int32_t aEndRowIndex); private: /* For the base implementation of nsTableFrame, cell spacing does not depend * on row/column indexing. */ - nscoord GetCellSpacingX(); - nscoord GetCellSpacingY(); + nscoord GetColSpacing(); + nscoord GetRowSpacing(); public: virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE; diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index de12a15c6fc..d9f1ca5d32e 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -287,7 +287,7 @@ GetHeightOfRowsSpannedBelowFirst(nsTableCellFrame& aTableCellFrame, height += nextRow->GetSize().height; rowX++; } - height += aTableFrame.GetCellSpacingY(rowX); + height += aTableFrame.GetRowSpacing(rowX); nextRow = nextRow->GetNextSibling(); } return height; @@ -683,7 +683,7 @@ CalcAvailWidth(nsTableFrame& aTableFrame, cellAvailWidth += aTableFrame.GetColumnWidth(colIndex + spanX); if (spanX > 0 && aTableFrame.ColumnHasCellSpacingBefore(colIndex + spanX)) { - cellAvailWidth += aTableFrame.GetCellSpacingX(colIndex + spanX - 1); + cellAvailWidth += aTableFrame.GetColSpacing(colIndex + spanX - 1); } } return cellAvailWidth; @@ -718,7 +718,7 @@ GetSpaceBetween(int32_t aPrevColIndex, space += aTableFrame.GetColumnWidth(colX); } if (!isCollapsed && aTableFrame.ColumnHasCellSpacingBefore(colX)) { - space += aTableFrame.GetCellSpacingX(colX - 1); + space += aTableFrame.GetColSpacing(colX - 1); } } } @@ -742,7 +742,7 @@ GetSpaceBetween(int32_t aPrevColIndex, space += aTableFrame.GetColumnWidth(colX); } if (!isCollapsed && aTableFrame.ColumnHasCellSpacingBefore(colX)) { - space += aTableFrame.GetCellSpacingX(colX - 1); + space += aTableFrame.GetColSpacing(colX - 1); } } } @@ -988,7 +988,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext, } } ConsiderChildOverflow(aDesiredSize.mOverflowAreas, kidFrame); - x += aTableFrame.GetCellSpacingX(cellColIndex); + x += aTableFrame.GetColSpacing(cellColIndex); } // just set our width to what was available. The table will calculate the width and not use our value. @@ -1168,7 +1168,7 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset, if (cellFrame) { int32_t rowIndex; cellFrame->GetRowIndex(rowIndex); - shift += tableFrame->GetCellSpacingY(rowIndex); + shift += tableFrame->GetRowSpacing(rowIndex); while (cellFrame) { nsRect cRect = cellFrame->GetRect(); // If aRowOffset != 0, there's no point in invalidating the cells, since @@ -1183,7 +1183,7 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset, cellFrame = cellFrame->GetNextCell(); } } else { - shift += tableFrame->GetCellSpacingY(GetRowIndex()); + shift += tableFrame->GetRowSpacing(GetRowIndex()); } rowRect.height = 0; } @@ -1247,14 +1247,14 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset, nextColFrame->StyleVisibility(); if ( (NS_STYLE_VISIBILITY_COLLAPSE != nextColVis->mVisible) && tableFrame->ColumnHasCellSpacingBefore(colX + colIncrement)) { - cRect.width += tableFrame->GetCellSpacingX(cellColIndex); + cRect.width += tableFrame->GetColSpacing(cellColIndex); } } } } x += cRect.width; if (isVisible) - x += tableFrame->GetCellSpacingX(cellColIndex); + x += tableFrame->GetColSpacing(cellColIndex); int32_t actualRowSpan = tableFrame->GetEffectiveRowSpan(*cellFrame); nsTableRowFrame* rowFrame = GetNextRow(); for (actualRowSpan--; actualRowSpan > 0 && rowFrame; actualRowSpan--) { @@ -1264,7 +1264,7 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset, if (!collapseNextRow) { nsRect nextRect = rowFrame->GetRect(); cRect.height += nextRect.height + - tableFrame->GetCellSpacingY(rowFrame->GetRowIndex()); + tableFrame->GetRowSpacing(rowFrame->GetRowIndex()); } rowFrame = rowFrame->GetNextRow(); } diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 95b57928cec..0004b38e990 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -349,7 +349,7 @@ nsTableRowGroupFrame::ReflowChildren(nsPresContext* aPresContext, NS_NOTREACHED("yikes, a non-row child"); continue; } - nscoord cellSpacingY = tableFrame->GetCellSpacingY(rowFrame->GetRowIndex()); + nscoord cellSpacingY = tableFrame->GetRowSpacing(rowFrame->GetRowIndex()); haveRow = true; // Reflow the row frame @@ -443,8 +443,8 @@ nsTableRowGroupFrame::ReflowChildren(nsPresContext* aPresContext, } if (haveRow) - aReflowState.y -= tableFrame->GetCellSpacingY(GetStartRowIndex() + - GetRowCount()); + aReflowState.y -= tableFrame->GetRowSpacing(GetStartRowIndex() + + GetRowCount()); // Return our desired rect aDesiredSize.Width() = aReflowState.reflowState.AvailableWidth(); @@ -607,7 +607,7 @@ nsTableRowGroupFrame::CalculateRowHeights(nsPresContext* aPresContext, nsTableCellFrame* cellFrame = rowFrame->GetFirstCell(); // iteratate the row's cell frames while (cellFrame) { - nscoord cellSpacingY = tableFrame->GetCellSpacingY(startRowIndex + rowIndex); + nscoord cellSpacingY = tableFrame->GetRowSpacing(startRowIndex + rowIndex); int32_t rowSpan = tableFrame->GetEffectiveRowSpan(rowIndex + startRowIndex, *cellFrame); if ((rowIndex + rowSpan) > numRows) { // there might be rows pushed already to the nextInFlow @@ -727,7 +727,7 @@ nsTableRowGroupFrame::CalculateRowHeights(nsPresContext* aPresContext, bool styleHeightAllocation = false; nscoord rowGroupHeight = startRowGroupHeight + heightOfRows + - tableFrame->GetCellSpacingY(0, numRows-1); + tableFrame->GetRowSpacing(0, numRows-1); // if we have a style height, allocate the extra height to unconstrained rows if ((aReflowState.ComputedHeight() > rowGroupHeight) && (NS_UNCONSTRAINEDSIZE != aReflowState.ComputedHeight())) { @@ -787,7 +787,7 @@ nsTableRowGroupFrame::CalculateRowHeights(nsPresContext* aPresContext, // XXXbz we don't need to update our overflow area? } } - yOrigin += rowHeight + tableFrame->GetCellSpacingY(startRowIndex + rowIndex); + yOrigin += rowHeight + tableFrame->GetRowSpacing(startRowIndex + rowIndex); } if (isPaginated && styleHeightAllocation) { @@ -831,8 +831,8 @@ nsTableRowGroupFrame::CollapseRowGroupIfNecessary(nscoord aYTotalOffset, groupRect.height -= yGroupOffset; if (didCollapse) { // add back the cellspacing between rowgroups - groupRect.height += tableFrame->GetCellSpacingY(GetStartRowIndex() + - GetRowCount()); + groupRect.height += tableFrame->GetRowSpacing(GetStartRowIndex() + + GetRowCount()); } groupRect.y -= aYTotalOffset; @@ -1062,7 +1062,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, // in the available space for (nsTableRowFrame* rowFrame = firstRowThisPage; rowFrame; rowFrame = rowFrame->GetNextRow()) { bool rowIsOnPage = true; - nscoord cellSpacingY = aTableFrame->GetCellSpacingY(rowFrame->GetRowIndex()); + nscoord cellSpacingY = aTableFrame->GetRowSpacing(rowFrame->GetRowIndex()); nsRect rowRect = rowFrame->GetNormalRect(); // See if the row fits on this page if (rowRect.YMost() > availHeight) { @@ -1516,9 +1516,9 @@ nsTableRowGroupFrame::GetHeightBasis(const nsHTMLReflowState& aReflowState) nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); int32_t startRowIndex = GetStartRowIndex(); if ((aReflowState.ComputedHeight() > 0) && (aReflowState.ComputedHeight() < NS_UNCONSTRAINEDSIZE)) { - nscoord cellSpacing = tableFrame->GetCellSpacingY(startRowIndex, - std::max(startRowIndex, - startRowIndex + GetRowCount() - 1)); + nscoord cellSpacing = tableFrame->GetRowSpacing(startRowIndex, + std::max(startRowIndex, + startRowIndex + GetRowCount() - 1)); result = aReflowState.ComputedHeight() - cellSpacing; } else { @@ -1528,7 +1528,7 @@ nsTableRowGroupFrame::GetHeightBasis(const nsHTMLReflowState& aReflowState) } if (parentRS && (tableFrame == parentRS->frame) && (parentRS->ComputedHeight() > 0) && (parentRS->ComputedHeight() < NS_UNCONSTRAINEDSIZE)) { - nscoord cellSpacing = tableFrame->GetCellSpacingY(-1, tableFrame->GetRowCount()); + nscoord cellSpacing = tableFrame->GetRowSpacing(-1, tableFrame->GetRowCount()); result = parentRS->ComputedHeight() - cellSpacing; } } diff --git a/layout/tools/reftest/runreftest.py b/layout/tools/reftest/runreftest.py index 705551d4625..86dacee71a6 100644 --- a/layout/tools/reftest/runreftest.py +++ b/layout/tools/reftest/runreftest.py @@ -289,22 +289,22 @@ class RefTest(object): def _psInfo(line): if pname in line: log.info(line) - process = mozprocess.ProcessHandler(['ps', '-f', '--no-headers'], + process = mozprocess.ProcessHandler(['ps', '-f'], processOutputLine=_psInfo) process.run() process.wait() def _psKill(line): parts = line.split() - pid = int(parts[0]) - if len(parts) == 3 and parts[2] == pname and parts[1] == '1': - log.info("killing %s orphan with pid %d" % (pname, pid)) - try: - os.kill(pid, getattr(signal, "SIGKILL", signal.SIGTERM)) - except Exception as e: - log.info("Failed to kill process %d: %s" % (pid, str(e))) - - process = mozprocess.ProcessHandler(['ps', '-o', 'pid,ppid,comm', '--no-headers'], + if len(parts) == 3 and parts[0].isdigit(): + pid = int(parts[0]) + if parts[2] == pname and parts[1] == '1': + log.info("killing %s orphan with pid %d" % (pname, pid)) + try: + os.kill(pid, getattr(signal, "SIGKILL", signal.SIGTERM)) + except Exception as e: + log.info("Failed to kill process %d: %s" % (pid, str(e))) + process = mozprocess.ProcessHandler(['ps', '-o', 'pid,ppid,comm'], processOutputLine=_psKill) process.run() process.wait() diff --git a/layout/xul/nsMenuPopupFrame.cpp b/layout/xul/nsMenuPopupFrame.cpp index adc8c84850f..f2be7f808e3 100644 --- a/layout/xul/nsMenuPopupFrame.cpp +++ b/layout/xul/nsMenuPopupFrame.cpp @@ -458,8 +458,11 @@ nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu, mPrefSize = prefSize; } + bool needCallback = false; + if (shouldPosition) { SetPopupPosition(aAnchor, false, aSizedToPopup); + needCallback = true; } nsRect bounds(GetRect()); @@ -477,6 +480,7 @@ nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu, mPrefSize = newsize; if (isOpen) { SetPopupPosition(aAnchor, false, aSizedToPopup); + needCallback = true; } } } @@ -528,6 +532,27 @@ nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu, nsCOMPtr event = new nsXULPopupShownEvent(GetContent(), pc); NS_DispatchToCurrentThread(event); } + + if (needCallback && !mReflowCallbackData.mPosted) { + pc->PresShell()->PostReflowCallback(this); + mReflowCallbackData.MarkPosted(aAnchor, aSizedToPopup); + } +} + +bool +nsMenuPopupFrame::ReflowFinished() +{ + SetPopupPosition(mReflowCallbackData.mAnchor, false, mReflowCallbackData.mSizedToPopup); + + mReflowCallbackData.Clear(); + + return false; +} + +void +nsMenuPopupFrame::ReflowCallbackCanceled() +{ + mReflowCallbackData.Clear(); } nsIContent* @@ -1943,6 +1968,11 @@ nsMenuPopupFrame::MoveToAttributePosition() void nsMenuPopupFrame::DestroyFrom(nsIFrame* aDestructRoot) { + if (mReflowCallbackData.mPosted) { + PresContext()->PresShell()->CancelReflowCallback(this); + mReflowCallbackData.Clear(); + } + nsMenuFrame* menu = do_QueryFrame(GetParent()); if (menu) { // clear the open attribute on the parent menu diff --git a/layout/xul/nsMenuPopupFrame.h b/layout/xul/nsMenuPopupFrame.h index 64acca6ab0a..979bbc38fbc 100644 --- a/layout/xul/nsMenuPopupFrame.h +++ b/layout/xul/nsMenuPopupFrame.h @@ -152,7 +152,8 @@ private: nsRefPtr mPresContext; }; -class nsMenuPopupFrame MOZ_FINAL : public nsBoxFrame, public nsMenuParent +class nsMenuPopupFrame MOZ_FINAL : public nsBoxFrame, public nsMenuParent, + public nsIReflowCallback { public: NS_DECL_QUERYFRAME_TARGET(nsMenuPopupFrame) @@ -399,6 +400,10 @@ public: return false; } + // nsIReflowCallback + virtual bool ReflowFinished() MOZ_OVERRIDE; + virtual void ReflowCallbackCanceled() MOZ_OVERRIDE; + protected: // returns the popup's level. @@ -526,6 +531,28 @@ protected: uint8_t mConsumeRollupEvent; FlipType mFlip; // Whether to flip + struct ReflowCallbackData { + ReflowCallbackData() : + mPosted(false), + mAnchor(nullptr), + mSizedToPopup(false) + {} + void MarkPosted(nsIFrame* aAnchor, bool aSizedToPopup) { + mPosted = true; + mAnchor = aAnchor; + mSizedToPopup = aSizedToPopup; + } + void Clear() { + mPosted = false; + mAnchor = nullptr; + mSizedToPopup = false; + } + bool mPosted; + nsIFrame* mAnchor; + bool mSizedToPopup; + }; + ReflowCallbackData mReflowCallbackData; + bool mIsOpenChanged; // true if the open state changed since the last layout bool mIsContextMenu; // true for context menus // true if we need to offset the popup to ensure it's not under the mouse diff --git a/layout/xul/nsSprocketLayout.cpp b/layout/xul/nsSprocketLayout.cpp index 8fd67b2ad81..a54a9995bd9 100644 --- a/layout/xul/nsSprocketLayout.cpp +++ b/layout/xul/nsSprocketLayout.cpp @@ -293,9 +293,6 @@ nsSprocketLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState) origX = x; origY = y; - nscoord nextX = x; - nscoord nextY = y; - // Now we iterate over our box children and our box size lists in // parallel. For each child, we look at its sizes and figure out // where to place it. @@ -354,9 +351,6 @@ nsSprocketLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState) y -= (childBoxSize->right); } - nextX = x; - nextY = y; - // Now we build a child rect. nscoord rectX = x; nscoord rectY = y; @@ -383,6 +377,9 @@ nsSprocketLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState) // Either |nextX| or |nextY| is updated by this function call, according // to our axis. + nscoord nextX = x; + nscoord nextY = y; + ComputeChildsNextPosition(aBox, x, y, nextX, nextY, childRect); // Now we further update our nextX/Y along our axis. diff --git a/layout/xul/test/chrome.ini b/layout/xul/test/chrome.ini index a52e18218ca..ac658238dbf 100644 --- a/layout/xul/test/chrome.ini +++ b/layout/xul/test/chrome.ini @@ -18,6 +18,7 @@ skip-if = buildapp == 'mulet' [test_bug987230.xul] skip-if = os == 'linux' # No native mousedown event [test_popupSizeTo.xul] +[test_popupZoom.xul] [test_resizer.xul] [test_stack.xul] [test_windowminmaxsize.xul] diff --git a/layout/xul/test/test_popupZoom.xul b/layout/xul/test/test_popupZoom.xul new file mode 100644 index 00000000000..b8e15ba1d26 --- /dev/null +++ b/layout/xul/test/test_popupZoom.xul @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + diff --git a/media/libcubeb/src/cubeb_wasapi.cpp b/media/libcubeb/src/cubeb_wasapi.cpp index 50806381db3..46140b9c89c 100644 --- a/media/libcubeb/src/cubeb_wasapi.cpp +++ b/media/libcubeb/src/cubeb_wasapi.cpp @@ -1241,10 +1241,7 @@ int wasapi_stream_stop(cubeb_stream * stm) { auto_lock lock(stm->stream_reset_lock); - if (!stm->client) { - XASSERT(!stm->thread); - LOG("stream already stopped\n"); - } else { + if (stm->client) { HRESULT hr = stm->client->Stop(); if (FAILED(hr)) { LOG("could not stop AudioClient\n"); diff --git a/media/libstagefright/binding/H264.cpp b/media/libstagefright/binding/H264.cpp index 450356c1b33..e006e389ae2 100644 --- a/media/libstagefright/binding/H264.cpp +++ b/media/libstagefright/binding/H264.cpp @@ -113,17 +113,16 @@ H264::DecodeNALUnit(const ByteBuffer* aNAL) if (!reader.Read(nalUnitHeaderBytes - 1)) { return nullptr; } - uint32_t zeros = 0; + uint32_t lastbytes = 0xffff; while (reader.Remaining()) { uint8_t byte = reader.ReadU8(); - if (zeros < 2 || byte == 0x03) { + if ((lastbytes & 0xffff) == 0 && byte == 0x03) { + // reset last two bytes, to detect the 0x000003 sequence again. + lastbytes = 0xffff; + } else { rbsp->AppendElement(byte); } - if (byte == 0) { - zeros++; - } else { - zeros = 0; - } + lastbytes = (lastbytes << 8) | byte; } return rbsp.forget(); } diff --git a/media/libstagefright/binding/include/mp4_demuxer/H264.h b/media/libstagefright/binding/include/mp4_demuxer/H264.h index 9122bfa82a3..b7fb47b3160 100644 --- a/media/libstagefright/binding/include/mp4_demuxer/H264.h +++ b/media/libstagefright/binding/include/mp4_demuxer/H264.h @@ -321,7 +321,9 @@ class H264 public: static bool DecodeSPSFromExtraData(const ByteBuffer* aExtraData, SPSData& aDest); /* Extract RAW BYTE SEQUENCE PAYLOAD from NAL content. - Returns nullptr if invalid content. */ + Returns nullptr if invalid content. + This is compliant to ITU H.264 7.3.1 Syntax in tabular form NAL unit syntax + */ static already_AddRefed DecodeNALUnit(const ByteBuffer* aNAL); /* Decode SPS NAL RBSP and fill SPSData structure */ static bool DecodeSPS(const ByteBuffer* aSPS, SPSData& aDest); diff --git a/media/mtransport/test/ice_unittest.cpp b/media/mtransport/test/ice_unittest.cpp index a470c2eca23..b54e9613312 100644 --- a/media/mtransport/test/ice_unittest.cpp +++ b/media/mtransport/test/ice_unittest.cpp @@ -411,8 +411,7 @@ class IceTestPeer : public sigslot::has_slots<> { expected_remote_type_ = remote; } - void SetExpectedCandidateAddr(const std::string& addr) { - expected_local_addr_ = addr; + void SetExpectedRemoteCandidateAddr(const std::string& addr) { expected_remote_addr_ = addr; } @@ -593,9 +592,6 @@ class IceTestPeer : public sigslot::has_slots<> { ASSERT_EQ(expected_local_transport_, local->local_addr.transport); DumpCandidate("Remote ", *remote); ASSERT_EQ(expected_remote_type_, remote->type); - if (!expected_local_addr_.empty()) { - ASSERT_EQ(expected_local_addr_, local->cand_addr.host); - } if (!expected_remote_addr_.empty()) { ASSERT_EQ(expected_remote_addr_, remote->cand_addr.host); } @@ -961,7 +957,6 @@ class IceTestPeer : public sigslot::has_slots<> { NrIceCandidate::Type expected_local_type_; std::string expected_local_transport_; NrIceCandidate::Type expected_remote_type_; - std::string expected_local_addr_; std::string expected_remote_addr_; TrickleMode trickle_mode_; int trickled_; @@ -1145,9 +1140,9 @@ class IceConnectTest : public ::testing::Test { p2_->SetExpectedTypes(local2, remote2); } - void SetExpectedCandidateAddr(const std::string& addr) { - p1_->SetExpectedCandidateAddr(addr); - p2_->SetExpectedCandidateAddr(addr); + void SetExpectedRemoteCandidateAddr(const std::string& addr) { + p1_->SetExpectedRemoteCandidateAddr(addr); + p2_->SetExpectedRemoteCandidateAddr(addr); } void ConnectP1(TrickleMode mode = TRICKLE_NONE) { @@ -1523,9 +1518,9 @@ TEST_F(IceConnectTest, TestConnect) { TEST_F(IceConnectTest, TestLoopbackOnlySortOf) { Init(false, true); AddStream("first", 1); - ASSERT_TRUE(Gather()); SetCandidateFilter(IsLoopbackCandidate); - SetExpectedCandidateAddr("127.0.0.1"); + ASSERT_TRUE(Gather()); + SetExpectedRemoteCandidateAddr("127.0.0.1"); Connect(); } diff --git a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp index b3dbfe0e3b7..89cad965b67 100644 --- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp +++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp @@ -1184,6 +1184,11 @@ JsepSessionImpl::CreateAnswerMSection(const JsepAnswerOptions& options, // Add extmap attributes. AddCommonExtmaps(remoteMsection, msection); + if (!msection->IsReceiving() && !msection->IsSending()) { + DisableMsection(sdp, msection); + return NS_OK; + } + if (msection->GetFormats().empty()) { // Could not negotiate anything. Disable m-section. DisableMsection(sdp, msection); @@ -1870,7 +1875,7 @@ JsepSessionImpl::CopyStickyParams(const SdpMediaSection& source, new SdpFlagAttribute(SdpAttribute::kRtcpMuxAttribute)); } - // mid must stay the same + // mid should stay the same if (sourceAttrs.HasAttribute(SdpAttribute::kMidAttribute)) { destAttrs.SetAttribute( new SdpStringAttribute(SdpAttribute::kMidAttribute, @@ -2154,7 +2159,8 @@ JsepSessionImpl::ValidateRemoteDescription(const Sdp& description) for (size_t i = 0; i < mCurrentRemoteDescription->GetMediaSectionCount(); ++i) { - if (MsectionIsDisabled(description.GetMediaSection(i))) { + if (MsectionIsDisabled(description.GetMediaSection(i)) || + MsectionIsDisabled(mCurrentRemoteDescription->GetMediaSection(i))) { continue; } @@ -2163,15 +2169,7 @@ JsepSessionImpl::ValidateRemoteDescription(const Sdp& description) const SdpAttributeList& oldAttrs( mCurrentRemoteDescription->GetMediaSection(i).GetAttributeList()); - // We have already verified the presence of these attributes in ParseSdp. - if (newAttrs.GetMid() != oldAttrs.GetMid()) { - JSEP_SET_ERROR("New remote description changes mid for level " << i - << ", was \'" << oldAttrs.GetMid() - << "\" now \'" << newAttrs.GetMid() << "\'"); - return NS_ERROR_INVALID_ARG; - } - - if (oldBundleMids.count(newAttrs.GetMid()) && + if (oldBundleMids.count(oldAttrs.GetMid()) && !newBundleMids.count(newAttrs.GetMid())) { JSEP_SET_ERROR("Removing m-sections from a bundle group is unsupported " "at this time."); @@ -2223,6 +2221,17 @@ JsepSessionImpl::ValidateAnswer(const Sdp& offer, const Sdp& answer) JSEP_SET_ERROR("Answer tried to set send when offer did not set recv"); return NS_ERROR_INVALID_ARG; } + + if (!MsectionIsDisabled(answerMsection)) { + if (offerMsection.GetAttributeList().GetMid() != + answerMsection.GetAttributeList().GetMid()) { + JSEP_SET_ERROR("Answer changes mid for level, was \'" + << offerMsection.GetAttributeList().GetMid() + << "\', now \'" + << answerMsection.GetAttributeList().GetMid() << "\'"); + return NS_ERROR_INVALID_ARG; + } + } } return NS_OK; @@ -2688,7 +2697,7 @@ JsepSessionImpl::GetBundleInfo(const Sdp& sdp, } if (!bundleMids->empty()) { - if (!bundleMsection) { + if (!*bundleMsection) { JSEP_SET_ERROR("mid specified for bundle transport in group attribute" " does not exist in the SDP. (mid=" << group->tags[0] << ")"); diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp index 09d71205089..d49d21a87ab 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp @@ -210,13 +210,18 @@ PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent) mMainThread(mParent->GetMainThread()), mSTSThread(mParent->GetSTSThread()), mProxyResolveCompleted(false) { +} + +nsresult PeerConnectionMedia::Init(const std::vector& stun_servers, + const std::vector& turn_servers) +{ nsresult rv; nsCOMPtr pps = do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to get proxy service: %d", __FUNCTION__, (int)rv); - return; + return NS_ERROR_FAILURE; } // We use the following URL to find the "default" proxy address for all HTTPS @@ -226,21 +231,42 @@ PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent) rv = NS_NewURI(getter_AddRefs(fakeHttpsLocation), "https://example.com"); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to set URI: %d", __FUNCTION__, (int)rv); - return; + return NS_ERROR_FAILURE; } nsCOMPtr channel; - nsCOMPtr doc = mParent->GetWindow()->GetExtantDoc(); + +#ifdef MOZILLA_INTERNAL_API + nsCOMPtr principal = mParent->GetWindow()->GetExtantDoc(); +#else + // For unit-tests + nsCOMPtr secMan( + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv)); + if (NS_FAILED(rv)) { + CSFLogError(logTag, "%s: Failed to get IOService: %d", + __FUNCTION__, (int)rv); + CSFLogError(logTag, "%s: Failed to get securityManager: %d", __FUNCTION__, (int)rv); + return NS_ERROR_FAILURE; + } + + nsCOMPtr principal; + rv = secMan->GetSystemPrincipal(getter_AddRefs(principal)); + if (NS_FAILED(rv)) { + CSFLogError(logTag, "%s: Failed to get systemPrincipal: %d", __FUNCTION__, (int)rv); + return NS_ERROR_FAILURE; + } +#endif + rv = NS_NewChannel(getter_AddRefs(channel), fakeHttpsLocation, - doc, + principal, nsILoadInfo::SEC_NORMAL, nsIContentPolicy::TYPE_OTHER); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to get channel from URI: %d", __FUNCTION__, (int)rv); - return; + return NS_ERROR_FAILURE; } nsRefPtr handler = new ProtocolProxyQueryHandler(this); @@ -250,13 +276,9 @@ PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent) handler, getter_AddRefs(mProxyRequest)); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to resolve protocol proxy: %d", __FUNCTION__, (int)rv); - return; + return NS_ERROR_FAILURE; } -} -nsresult PeerConnectionMedia::Init(const std::vector& stun_servers, - const std::vector& turn_servers) -{ // TODO(ekr@rtfm.com): need some way to set not offerer later // Looks like a bug in the NrIceCtx API. mIceCtx = NrIceCtx::Create("PC:" + mParentName, @@ -267,7 +289,7 @@ nsresult PeerConnectionMedia::Init(const std::vector& stun_serv CSFLogError(logTag, "%s: Failed to create Ice Context", __FUNCTION__); return NS_ERROR_FAILURE; } - nsresult rv; + if (NS_FAILED(rv = mIceCtx->SetStunServers(stun_servers))) { CSFLogError(logTag, "%s: Failed to set stun servers", __FUNCTION__); return rv; diff --git a/media/webrtc/signaling/test/jsep_session_unittest.cpp b/media/webrtc/signaling/test/jsep_session_unittest.cpp index 8ac2298ec8f..51935777a1d 100644 --- a/media/webrtc/signaling/test/jsep_session_unittest.cpp +++ b/media/webrtc/signaling/test/jsep_session_unittest.cpp @@ -1334,12 +1334,13 @@ TEST_P(JsepSessionTest, RenegotiationBothRemoveTrack) ASSERT_TRUE(msection->IsReceiving()); ASSERT_FALSE(msection->IsSending()); - // First m-section should be inactive + // First m-section should be inactive, and rejected auto answer = GetParsedLocalDescription(mSessionAns); msection = GetMsection(*answer, types.front(), 0); ASSERT_TRUE(msection); ASSERT_FALSE(msection->IsReceiving()); ASSERT_FALSE(msection->IsSending()); + ASSERT_FALSE(msection->GetPort()); auto newOffererPairs = GetTrackPairsByLevel(mSessionOff); auto newAnswererPairs = GetTrackPairsByLevel(mSessionAns); @@ -1347,13 +1348,91 @@ TEST_P(JsepSessionTest, RenegotiationBothRemoveTrack) ASSERT_EQ(offererPairs.size(), newOffererPairs.size() + 1); for (size_t i = 0; i < newOffererPairs.size(); ++i) { - ASSERT_TRUE(Equals(offererPairs[i + 1], newOffererPairs[i])); + JsepTrackPair oldPair(offererPairs[i + 1]); + JsepTrackPair newPair(newOffererPairs[i]); + ASSERT_EQ(oldPair.mLevel, newPair.mLevel); + ASSERT_EQ(oldPair.mSending.get(), newPair.mSending.get()); + ASSERT_EQ(oldPair.mReceiving.get(), newPair.mReceiving.get()); + ASSERT_TRUE(oldPair.mBundleLevel.isSome()); + ASSERT_TRUE(newPair.mBundleLevel.isSome()); + ASSERT_EQ(0U, *oldPair.mBundleLevel); + ASSERT_EQ(1U, *newPair.mBundleLevel); } ASSERT_EQ(answererPairs.size(), newAnswererPairs.size() + 1); for (size_t i = 0; i < newAnswererPairs.size(); ++i) { - ASSERT_TRUE(Equals(answererPairs[i + 1], newAnswererPairs[i])); + JsepTrackPair oldPair(answererPairs[i + 1]); + JsepTrackPair newPair(newAnswererPairs[i]); + ASSERT_EQ(oldPair.mLevel, newPair.mLevel); + ASSERT_EQ(oldPair.mSending.get(), newPair.mSending.get()); + ASSERT_EQ(oldPair.mReceiving.get(), newPair.mReceiving.get()); + ASSERT_TRUE(oldPair.mBundleLevel.isSome()); + ASSERT_TRUE(newPair.mBundleLevel.isSome()); + ASSERT_EQ(0U, *oldPair.mBundleLevel); + ASSERT_EQ(1U, *newPair.mBundleLevel); + } +} + +TEST_P(JsepSessionTest, RenegotiationBothRemoveThenAddTrack) +{ + AddTracks(mSessionOff); + AddTracks(mSessionAns); + if (types.front() == SdpMediaSection::kApplication) { + return; + } + + SdpMediaSection::MediaType removedType = types.front(); + + OfferAnswer(); + + RefPtr removedTrackAnswer = GetTrackAns(0, removedType); + ASSERT_TRUE(removedTrackAnswer); + ASSERT_EQ(NS_OK, mSessionAns.RemoveTrack(removedTrackAnswer->GetStreamId(), + removedTrackAnswer->GetTrackId())); + + RefPtr removedTrackOffer = GetTrackOff(0, removedType); + ASSERT_TRUE(removedTrackOffer); + ASSERT_EQ(NS_OK, mSessionOff.RemoveTrack(removedTrackOffer->GetStreamId(), + removedTrackOffer->GetTrackId())); + + OfferAnswer(CHECK_SUCCESS); + + auto offererPairs = GetTrackPairsByLevel(mSessionOff); + auto answererPairs = GetTrackPairsByLevel(mSessionAns); + + std::vector extraTypes; + extraTypes.push_back(removedType); + AddTracks(mSessionAns, extraTypes); + AddTracks(mSessionOff, extraTypes); + types.insert(types.end(), extraTypes.begin(), extraTypes.end()); + + OfferAnswer(CHECK_SUCCESS); + + auto added = mSessionAns.GetRemoteTracksAdded(); + auto removed = mSessionAns.GetRemoteTracksRemoved(); + ASSERT_EQ(1U, added.size()); + ASSERT_EQ(0U, removed.size()); + ASSERT_EQ(removedType, added[0]->GetMediaType()); + + added = mSessionOff.GetRemoteTracksAdded(); + removed = mSessionOff.GetRemoteTracksRemoved(); + ASSERT_EQ(1U, added.size()); + ASSERT_EQ(0U, removed.size()); + ASSERT_EQ(removedType, added[0]->GetMediaType()); + + auto newOffererPairs = GetTrackPairsByLevel(mSessionOff); + auto newAnswererPairs = GetTrackPairsByLevel(mSessionAns); + + ASSERT_EQ(offererPairs.size() + 1, newOffererPairs.size()); + ASSERT_EQ(answererPairs.size() + 1, newAnswererPairs.size()); + + // Ensure that the m-section was re-used; no gaps + for (size_t i = 0; i < newOffererPairs.size(); ++i) { + ASSERT_EQ(i, newOffererPairs[i].mLevel); + } + for (size_t i = 0; i < newAnswererPairs.size(); ++i) { + ASSERT_EQ(i, newAnswererPairs[i].mLevel); } } diff --git a/media/webrtc/signaling/test/signaling_unittests.cpp b/media/webrtc/signaling/test/signaling_unittests.cpp index a228538ac4e..d549fe6c5e8 100644 --- a/media/webrtc/signaling/test/signaling_unittests.cpp +++ b/media/webrtc/signaling/test/signaling_unittests.cpp @@ -2313,14 +2313,6 @@ TEST_P(SignalingTest, OfferAnswerVideoInactive) CloseStreams(); } -TEST_P(SignalingTest, OfferAnswerBothInactive) -{ - OfferOptions options; - options.setInt32Option("OfferToReceiveAudio", 1); - options.setInt32Option("OfferToReceiveVideo", 1); - OfferAnswer(options, OFFER_NONE); -} - TEST_P(SignalingTest, CreateOfferAddCandidate) { OfferOptions options; diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index 805da449996..9763100d9aa 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -566,7 +566,6 @@ pref("media.fragmented-mp4.android-media-codec.enabled", true); pref("media.fragmented-mp4.android-media-codec.preferred", true); // optimize images memory usage -pref("image.downscale-during-decode.enabled", true); pref("image.mem.decodeondraw", true); #ifdef NIGHTLY_BUILD diff --git a/mobile/android/base/MemoryMonitor.java b/mobile/android/base/MemoryMonitor.java index 20f5a5a72d9..f186faec016 100644 --- a/mobile/android/base/MemoryMonitor.java +++ b/mobile/android/base/MemoryMonitor.java @@ -94,18 +94,33 @@ class MemoryMonitor extends BroadcastReceiver { return; } - if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { - increaseMemoryPressure(MEMORY_PRESSURE_HIGH); - } else if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) { - increaseMemoryPressure(MEMORY_PRESSURE_MEDIUM); - } else if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { - // includes TRIM_MEMORY_BACKGROUND - increaseMemoryPressure(MEMORY_PRESSURE_CLEANUP); - } else { - // levels down here mean gecko is the foreground process so we - // should be less aggressive with wiping memory as it may impact - // user experience. - increaseMemoryPressure(MEMORY_PRESSURE_LOW); + if (level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { + // We seem to get this just by entering the task switcher or hitting the home button. + // Seems bogus, because we are the foreground app, or at least not at the end of the LRU list. + // Just ignore it, and if there is a real memory pressure event (CRITICAL, MODERATE, etc), + // we'll respond appropriately. + return; + } + + switch (level) { + case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL: + case ComponentCallbacks2.TRIM_MEMORY_MODERATE: + // TRIM_MEMORY_MODERATE is the highest level we'll respond to while backgrounded + increaseMemoryPressure(MEMORY_PRESSURE_HIGH); + break; + case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE: + increaseMemoryPressure(MEMORY_PRESSURE_MEDIUM); + break; + case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW: + increaseMemoryPressure(MEMORY_PRESSURE_LOW); + break; + case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN: + case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND: + increaseMemoryPressure(MEMORY_PRESSURE_CLEANUP); + break; + default: + Log.d(LOGTAG, "Unhandled onTrimMemory() level " + level); + break; } } @@ -140,6 +155,8 @@ class MemoryMonitor extends BroadcastReceiver { mMemoryPressure = level; } + Log.d(LOGTAG, "increasing memory pressure to " + level); + // since we don't get notifications for when memory pressure is off, // we schedule our own timer to slowly back off the memory pressure level. // note that this will reset the time to next decrement if the decrementer diff --git a/mobile/android/config/proguard/strip-libs.cfg b/mobile/android/config/proguard/strip-libs.cfg index b9706b61d1b..80a1f151c94 100644 --- a/mobile/android/config/proguard/strip-libs.cfg +++ b/mobile/android/config/proguard/strip-libs.cfg @@ -38,3 +38,4 @@ # Don't print spurious warnings from the support library. # See: http://stackoverflow.com/questions/22441366/note-android-support-v4-text-icucompatics-cant-find-dynamically-referenced-cl -dontnote android.support.** +-dontwarn android.support.** diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 062c5f04dd1..67517c15de5 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -3819,7 +3819,7 @@ pref("image.cache.size", 5242880); pref("image.cache.timeweight", 500); // Whether we attempt to downscale images during decoding. -pref("image.downscale-during-decode.enabled", true); +pref("image.downscale-during-decode.enabled", false); // The default Accept header sent for images loaded over HTTP(S) pref("image.http.accept", "image/png,image/*;q=0.8,*/*;q=0.5"); @@ -4628,6 +4628,11 @@ pref("media.gmp.insecure.allow", false); #if defined(XP_MACOSX) || defined(XP_WIN) pref("gfx.vsync.hw-vsync.enabled", true); pref("gfx.vsync.compositor", true); +#endif + +#if defined(XP_MACOSX) +pref("gfx.vsync.refreshdriver", true); +#else pref("gfx.vsync.refreshdriver", false); #endif diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp index 00391263a32..3fdf9b5f18d 100644 --- a/netwerk/base/nsIOService.cpp +++ b/netwerk/base/nsIOService.cpp @@ -1561,14 +1561,31 @@ nsIOService::SpeculativeConnect(nsIURI *aURI, nsresult rv; nsCOMPtr pps = do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv); - if (NS_FAILED(rv)) - return rv; + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr secMan( + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr systemPrincipal; + rv = secMan->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); + NS_ENSURE_SUCCESS(rv, rv); + + // dummy channel used to create a TCP connection. + // we perform security checks on the *real* channel, responsible + // for any network loads. this real channel just checks the TCP + // pool if there is an available connection created by the + // channel we create underneath - hence it's safe to use + // the systemPrincipal as the loadingPrincipal for this channel. nsCOMPtr channel; - rv = NewChannelFromURI(aURI, getter_AddRefs(channel)); - if (NS_FAILED(rv)) { - return rv; - } + rv = NewChannelFromURI2(aURI, + nullptr, // aLoadingNode, + systemPrincipal, + nullptr, //aTriggeringPrincipal, + nsILoadInfo::SEC_NORMAL, + nsIContentPolicy::TYPE_OTHER, + getter_AddRefs(channel)); + + NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr cancelable; nsRefPtr callback = diff --git a/netwerk/base/nsProtocolProxyService.cpp b/netwerk/base/nsProtocolProxyService.cpp index 164bf4da8a5..7c3a1600085 100644 --- a/netwerk/base/nsProtocolProxyService.cpp +++ b/netwerk/base/nsProtocolProxyService.cpp @@ -18,6 +18,7 @@ #include "nsICancelable.h" #include "nsIDNSService.h" #include "nsPIDNSService.h" +#include "nsIScriptSecurityManager.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" #include "nsThreadUtils.h" @@ -1285,11 +1286,22 @@ nsProtocolProxyService::AsyncResolve(nsISupports *channelOrURI, uint32_t flags, return NS_ERROR_NO_INTERFACE; } - // make a temporary channel from the URI - nsCOMPtr ios(do_GetIOService(&rv)); - if (NS_FAILED(rv)) return rv; - rv = ios->NewChannelFromURI(uri, getter_AddRefs(channel)); - if (NS_FAILED(rv)) return rv; + nsCOMPtr secMan( + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr systemPrincipal; + rv = secMan->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); + NS_ENSURE_SUCCESS(rv, rv); + + // creating a temporary channel from the URI which is not + // used to perform any network loads, hence its safe to + // use systemPrincipal as the loadingPrincipal. + rv = NS_NewChannel(getter_AddRefs(channel), + uri, + systemPrincipal, + nsILoadInfo::SEC_NORMAL, + nsIContentPolicy::TYPE_OTHER); + NS_ENSURE_SUCCESS(rv, rv); } return AsyncResolveInternal(channel, flags, callback, result, false); diff --git a/netwerk/mime/nsMimeTypes.h b/netwerk/mime/nsMimeTypes.h index 447148c5999..4c49a9d87a9 100644 --- a/netwerk/mime/nsMimeTypes.h +++ b/netwerk/mime/nsMimeTypes.h @@ -79,6 +79,7 @@ #define AUDIO_MP3 "audio/mpeg" #define AUDIO_MP4 "audio/mp4" #define AUDIO_AMR "audio/amr" +#define AUDIO_FLAC "audio/flac" #define AUDIO_3GPP "audio/3gpp" #define AUDIO_MIDI "audio/x-midi" #define AUDIO_MATROSKA "audio/x-matroska" diff --git a/netwerk/protocol/http/Http2Session.cpp b/netwerk/protocol/http/Http2Session.cpp index 1337b05db98..7b550a7c9be 100644 --- a/netwerk/protocol/http/Http2Session.cpp +++ b/netwerk/protocol/http/Http2Session.cpp @@ -75,13 +75,20 @@ Http2Session::Http2Session(nsISocketTransport *aSocketTransport, uint32_t versio , mDownstreamState(BUFFERING_OPENING_SETTINGS) , mInputFrameBufferSize(kDefaultBufferSize) , mInputFrameBufferUsed(0) + , mInputFrameDataSize(0) + , mInputFrameDataRead(0) , mInputFrameFinal(false) + , mInputFrameType(0) + , mInputFrameFlags(0) + , mInputFrameID(0) + , mPaddingLength(0) , mInputFrameDataStream(nullptr) , mNeedsCleanup(nullptr) , mDownstreamRstReason(NO_HTTP_ERROR) , mExpectedHeaderID(0) , mExpectedPushPromiseID(0) , mContinuedPromiseStream(0) + , mFlatHTTPResponseHeadersOut(0) , mShouldGoAway(false) , mClosed(false) , mCleanShutdown(false) @@ -125,6 +132,7 @@ Http2Session::Http2Session(nsISocketTransport *aSocketTransport, uint32_t versio mLastDataReadEpoch = mLastReadEpoch; mPingThreshold = gHttpHandler->SpdyPingThreshold(); + mPreviousPingThreshold = mPingThreshold; mNegotiatedToken.AssignLiteral(HTTP2_DRAFT_LATEST_TOKEN); } diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index ed91f49584d..9b7e9cfa2ca 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -1562,22 +1562,47 @@ nsHttpHandler::TimerCallback(nsITimer * aTimer, void * aClosure) thisObject->mCapabilities &= ~NS_HTTP_ALLOW_PIPELINING; } +/** + * Currently, only regularizes the case of subtags. + */ static void -NormalizeLanguageTag(char *code) +CanonicalizeLanguageTag(char *languageTag) { - bool is_region = false; - while (*code != '\0') - { - if (*code == '-') { - is_region = true; + char *s = languageTag; + while (*s != '\0') { + *s = nsCRT::ToLower(*s); + s++; + } + + s = languageTag; + bool isFirst = true; + bool seenSingleton = false; + while (*s != '\0') { + char *subTagEnd = strchr(s, '-'); + if (subTagEnd == nullptr) { + subTagEnd = strchr(s, '\0'); + } + + if (isFirst) { + isFirst = false; + } else if (seenSingleton) { + // Do nothing } else { - if (is_region) { - *code = nsCRT::ToUpper(*code); - } else { - *code = nsCRT::ToLower(*code); + size_t subTagLength = subTagEnd - s; + if (subTagLength == 1) { + seenSingleton = true; + } else if (subTagLength == 2) { + *s = nsCRT::ToUpper(*s); + *(s + 1) = nsCRT::ToUpper(*(s + 1)); + } else if (subTagLength == 4) { + *s = nsCRT::ToUpper(*s); } } - code++; + + s = subTagEnd; + if (*s != '\0') { + s++; + } } } @@ -1636,7 +1661,7 @@ PrepareAcceptLanguages(const char *i_AcceptLanguages, nsACString &o_AcceptLangua *trim = '\0'; if (*token != '\0') { - NormalizeLanguageTag(token); + CanonicalizeLanguageTag(token); comma = count_n++ != 0 ? "," : ""; // delimiter if not first item uint32_t u = QVAL_TO_UINT(q); diff --git a/netwerk/test/unit/test_header_Accept-Language_case.js b/netwerk/test/unit/test_header_Accept-Language_case.js index f64e5cffaff..2374ff1f8b7 100644 --- a/netwerk/test/unit/test_header_Accept-Language_case.js +++ b/netwerk/test/unit/test_header_Accept-Language_case.js @@ -8,6 +8,16 @@ function run_test() { let oldAcceptLangPref = intlPrefs.getCharPref("accept_languages"); let testData = [ + ["en", "en"], + ["ast", "ast"], + ["fr-ca", "fr-CA"], + ["zh-yue", "zh-yue"], + ["az-latn", "az-Latn"], + ["sl-nedis", "sl-nedis"], + ["zh-hant-hk", "zh-Hant-HK"], + ["ZH-HANT-HK", "zh-Hant-HK"], + ["en-us-x-priv", "en-US-x-priv"], + ["en-us-x-twain", "en-US-x-twain"], ["de, en-US, en", "de,en-US;q=0.7,en;q=0.3"], ["de,en-us,en", "de,en-US;q=0.7,en;q=0.3"], ["en-US, en", "en-US,en;q=0.5"], diff --git a/security/manager/boot/src/StaticHPKPins.h b/security/manager/boot/src/StaticHPKPins.h index 3002a318762..07ebc96cf20 100644 --- a/security/manager/boot/src/StaticHPKPins.h +++ b/security/manager/boot/src/StaticHPKPins.h @@ -1081,4 +1081,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = { static const int32_t kUnknownId = -1; -static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1434795456425000); +static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1435400245288000); diff --git a/security/manager/boot/src/nsSTSPreloadList.errors b/security/manager/boot/src/nsSTSPreloadList.errors index ca8f1ef733e..c030f4982d1 100644 --- a/security/manager/boot/src/nsSTSPreloadList.errors +++ b/security/manager/boot/src/nsSTSPreloadList.errors @@ -1,3 +1,5 @@ +0x0a.net: could not connect to host +301.website: did not receive HSTS header 56ct.com: could not connect to host 9point6.com: could not connect to host admin.google.com: did not receive HSTS header (error ignored - included regardless) @@ -12,15 +14,18 @@ apis.google.com: did not receive HSTS header (error ignored - included regardles app.manilla.com: could not connect to host appengine.google.com: did not receive HSTS header (error ignored - included regardless) appseccalifornia.org: did not receive HSTS header +astaxi.net: did not receive HSTS header at.search.yahoo.com: did not receive HSTS header atavio.at: could not connect to host atavio.ch: could not connect to host +atavio.de: did not receive HSTS header au.search.yahoo.com: did not receive HSTS header auth.mail.ru: did not receive HSTS header auto4trade.nl: did not receive HSTS header az.search.yahoo.com: did not receive HSTS header azprep.us: could not connect to host -bagelsbakery.com: did not receive HSTS header +balcan-underground.net: did not receive HSTS header +baldwinkoo.com: did not receive HSTS header barcodeberlin.com: did not receive HSTS header bccx.com: could not connect to host bcm.com.au: max-age too low: 0 @@ -59,7 +64,6 @@ chrome-devtools-frontend.appspot.com: did not receive HSTS header (error ignored chrome.google.com: did not receive HSTS header (error ignored - included regardless) cimballa.com: did not receive HSTS header cl.search.yahoo.com: did not receive HSTS header -classdojo.com: did not receive HSTS header cn.search.yahoo.com: did not receive HSTS header co.search.yahoo.com: did not receive HSTS header code.google.com: did not receive HSTS header (error ignored - included regardless) @@ -111,6 +115,7 @@ etsysecure.com: could not connect to host fabianfischer.de: did not receive HSTS header fatzebra.com.au: did not receive HSTS header fi.search.yahoo.com: did not receive HSTS header +filedir.com: could not connect to host fixingdns.com: could not connect to host fj.search.yahoo.com: did not receive HSTS header fm83.nl: did not receive HSTS header @@ -136,10 +141,9 @@ gr.search.yahoo.com: did not receive HSTS header grandmascookieblog.com: did not receive HSTS header greplin.com: could not connect to host groups.google.com: did not receive HSTS header (error ignored - included regardless) -gunnarhafdal.com: could not connect to host hackerone-user-content.com: could not connect to host haste.ch: could not connect to host -hatoko.net: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] +hatoko.net: could not connect to host history.google.com: did not receive HSTS header (error ignored - included regardless) hk.search.yahoo.com: did not receive HSTS header hn.search.yahoo.com: did not receive HSTS header @@ -164,6 +168,7 @@ iop.intuit.com: max-age too low: 86400 irccloud.com: did not receive HSTS header it.search.yahoo.com: did not receive HSTS header janoberst.com: did not receive HSTS header +jelmer.co.uk: could not connect to host jonathan.ir: could not connect to host jottit.com: could not connect to host k-dev.de: could not connect to host @@ -177,12 +182,14 @@ klaxn.com: could not connect to host klaxn.org: could not connect to host koop-bremen.de: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] kr.search.yahoo.com: did not receive HSTS header +krouzkyliduska.cz: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] kryptera.se: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] kz.search.yahoo.com: did not receive HSTS header labina.com.tr: did not receive HSTS header landscape.canonical.com: max-age too low: 2592000 li.search.yahoo.com: did not receive HSTS header library.linode.com: did not receive HSTS header +libraryfreedomproject.org: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] lifeguard.aecom.com: max-age too low: 86400 lists.fedoraproject.org: did not receive HSTS header login.corp.google.com: max-age too low: 7776000 (error ignored - included regardless) @@ -207,12 +214,11 @@ megashur.se: did not receive HSTS header megaxchange.com: did not receive HSTS header meinebo.it: could not connect to host minikneet.nl: did not receive HSTS header -mirindadomo.ru: could not connect to host +mirindadomo.ru: did not receive HSTS header mnemotiv.com: did not receive HSTS header mobilethreat.net: could not connect to host mobilethreatnetwork.net: could not connect to host mocloud.eu: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] -movelaria.com.br: did not receive HSTS header mqas.net: could not connect to host mt.search.yahoo.com: did not receive HSTS header mu.search.yahoo.com: did not receive HSTS header @@ -231,6 +237,7 @@ netztest.at: did not receive HSTS header nexth.de: could not connect to host nexth.net: could not connect to host nexth.us: could not connect to host +ng-security.com: could not connect to host ni.search.yahoo.com: did not receive HSTS header nl.search.yahoo.com: did not receive HSTS header no.search.yahoo.com: did not receive HSTS header @@ -240,10 +247,12 @@ npw.net: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FA null-sec.ru: could not connect to host nutsandboltsmedia.com: did not receive HSTS header nz.search.yahoo.com: did not receive HSTS header +opendesk.cc: did not receive HSTS header openshift.redhat.com: did not receive HSTS header otakurepublic.com: did not receive HSTS header ottospora.nl: could not connect to host pa.search.yahoo.com: did not receive HSTS header +passwd.io: could not connect to host passwordbox.com: did not receive HSTS header passwords.google.com: did not receive HSTS header (error ignored - included regardless) pe.search.yahoo.com: did not receive HSTS header @@ -267,7 +276,6 @@ rapidresearch.me: could not connect to host redlatam.org: did not receive HSTS header redports.org: could not connect to host regar42.fr: could not connect to host -riftnetwork.net: did not receive HSTS header riseup.net: did not receive HSTS header rme.li: did not receive HSTS header ro.search.yahoo.com: did not receive HSTS header @@ -276,7 +284,6 @@ ru.search.yahoo.com: did not receive HSTS header rw.search.yahoo.com: did not receive HSTS header sah3.net: could not connect to host saturngames.co.uk: could not connect to host -savetheinternet.eu: did not receive HSTS header script.google.com: did not receive HSTS header (error ignored - included regardless) se.search.yahoo.com: did not receive HSTS header search.yahoo.com: did not receive HSTS header @@ -312,13 +319,13 @@ sv.search.yahoo.com: did not receive HSTS header sylaps.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] t.facebook.com: did not receive HSTS header tablet.facebook.com: did not receive HSTS header -tageau.com: could not connect to host talk.google.com: could not connect to host talk.google.com: could not connect to host (error ignored - included regardless) talkgadget.google.com: did not receive HSTS header (error ignored - included regardless) tandarts-haarlem.nl: did not receive HSTS header taxsquirrel.com: did not receive HSTS header tc-bonito.de: did not receive HSTS header +techllage.com: did not receive HSTS header tektoria.de: did not receive HSTS header temehu.com: did not receive HSTS header terrax.berlin: could not connect to host @@ -339,12 +346,16 @@ ustr.gov: max-age too low: 86400 uy.search.yahoo.com: did not receive HSTS header uz.search.yahoo.com: did not receive HSTS header ve.search.yahoo.com: did not receive HSTS header +vhost.co.id: could not connect to host viennan.net: did not receive HSTS header vn.search.yahoo.com: did not receive HSTS header vyncke.org: did not receive HSTS header wallet.google.com: did not receive HSTS header (error ignored - included regardless) +wearvr.com: did not receive HSTS header webmail.mayfirst.org: did not receive HSTS header +wideup.net: did not receive HSTS header wikidsystems.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] +withustrading.com: did not receive HSTS header wiz.biz: could not connect to host wohnungsbau-ludwigsburg.de: did not receive HSTS header www.apollo-auto.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no] diff --git a/security/manager/boot/src/nsSTSPreloadList.inc b/security/manager/boot/src/nsSTSPreloadList.inc index ee4d64bd557..d14e5d2e24c 100644 --- a/security/manager/boot/src/nsSTSPreloadList.inc +++ b/security/manager/boot/src/nsSTSPreloadList.inc @@ -8,7 +8,7 @@ /*****************************************************************************/ #include -const PRTime gPreloadListExpirationTime = INT64_C(1437214651606000); +const PRTime gPreloadListExpirationTime = INT64_C(1437819438137000); class nsSTSPreload { @@ -26,6 +26,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "1a-vermessung.at", true }, { "1a-werkstattgeraete.de", true }, { "2048game.co.uk", true }, + { "2600hq.com", true }, { "302.nyc", true }, { "5apps.com", false }, { "7183.org", true }, @@ -63,6 +64,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "alexsexton.com", true }, { "alexyang.me", true }, { "alpha.irccloud.com", false }, + { "alza.cz", true }, { "anadoluefessporkulubu.org", true }, { "andere-gedanken.net", true }, { "andreasbreitenlohner.de", true }, @@ -105,6 +107,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "arguggi.co.uk", true }, { "arivo.com.br", true }, { "arlen.io", true }, + { "armytricka.cz", true }, { "aroonchande.com", true }, { "arteseideias.com.pt", true }, { "arty.name", true }, @@ -112,7 +115,6 @@ static const nsSTSPreload kSTSPreloadList[] = { { "ask.stg.fedoraproject.org", true }, { "atavio.at", true }, { "atavio.ch", true }, - { "atavio.de", true }, { "atc.io", true }, { "athenelive.com", true }, { "atishchenko.com", true }, @@ -130,8 +132,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "badges.fedoraproject.org", true }, { "badges.stg.fedoraproject.org", true }, { "baer.im", true }, - { "balcan-underground.net", true }, - { "baldwinkoo.com", true }, + { "bagelsbakery.com", true }, { "balikonos.cz", true }, { "bank.simple.com", false }, { "barslecht.com", true }, @@ -192,6 +193,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "bookingapp.nl", true }, { "boxcryptor.com", true }, { "boypoint.de", true }, + { "bradkovach.com", true }, { "brage.info", true }, { "brakemanpro.com", true }, { "bran.cc", true }, @@ -251,6 +253,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "cktennis.com", true }, { "clan-ww.com", true }, { "clapping-rhymes.com", true }, + { "classdojo.com", true }, { "clerkendweller.uk", true }, { "clintwilson.technology", true }, { "cloud.google.com", true }, @@ -285,7 +288,9 @@ static const nsSTSPreload kSTSPreloadList[] = { { "crm.onlime.ch", false }, { "crowdjuris.com", true }, { "crypto.cat", false }, + { "crypto.graphics", true }, { "cryptobin.org", true }, + { "cryptography.io", true }, { "cryptopartyatx.org", true }, { "cryptopush.com", true }, { "cs50.harvard.edu", true }, @@ -306,9 +311,12 @@ static const nsSTSPreload kSTSPreloadList[] = { { "cyphertite.com", true }, { "cyprus-company-service.com", true }, { "czbix.com", true }, + { "danielalvarez.net", true }, + { "danonsecurity.com", true }, { "danskoferie.dk", true }, { "daphne.informatik.uni-freiburg.de", true }, { "darchoods.net", false }, + { "darknode.in", true }, { "darkpony.ru", true }, { "darkserver.fedoraproject.org", true }, { "darkserver.stg.fedoraproject.org", true }, @@ -320,6 +328,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "datenkeks.de", true }, { "daveoc64.co.uk", true }, { "davidlyness.com", true }, + { "davidmcevoy.org.uk", true }, { "davidnoren.com", true }, { "daylightpirates.org", true }, { "dccode.gov", true }, @@ -339,6 +348,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "devinfo.net", true }, { "diamante.ro", true }, { "die-besten-weisheiten.de", true }, + { "diedrich.co", true }, { "dillonkorman.com", true }, { "dinamoelektrik.com", true }, { "disking.co.uk", true }, @@ -353,6 +363,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "doc.python.org", true }, { "docs.google.com", true }, { "docs.python.org", true }, + { "domainkauf.de", true }, { "domains.google.com", true }, { "donmez.ws", false }, { "donotcall.gov", true }, @@ -388,12 +399,14 @@ static const nsSTSPreload kSTSPreloadList[] = { { "electronic-ignition-system.com", true }, { "elliquiy.com", true }, { "emailprivacytester.com", true }, + { "emptypath.com", true }, { "encircleapp.com", true }, { "encryptallthethings.net", true }, { "encrypted.google.com", true }, { "energy-drink-magazin.de", true }, { "enorekcah.com", true }, { "entropia.de", false }, + { "eromixx.com", true }, { "erotische-aanbiedingen.nl", true }, { "errors.zenpayroll.com", false }, { "esoa.net", true }, @@ -409,7 +422,10 @@ static const nsSTSPreload kSTSPreloadList[] = { { "expatads.com", true }, { "explodie.org", true }, { "extendwings.com", true }, + { "ezequiel-garzon.com", true }, + { "ezequiel-garzon.net", true }, { "f-droid.org", true }, + { "fa-works.com", true }, { "fabhub.io", true }, { "facebook.com", false }, { "factor.cc", false }, @@ -438,6 +454,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "firstlook.org", true }, { "fischer-its.com", true }, { "fj.simple.com", false }, + { "flagspot.net", true }, { "flamer-scene.com", true }, { "fleximus.org", false }, { "floobits.com", true }, @@ -481,6 +498,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "getdigitized.net", true }, { "getfedora.org", true }, { "getfittedstore.com", true }, + { "getmango.com", true }, { "getssl.uz", true }, { "giacomopelagatti.it", true }, { "github.com", true }, @@ -494,12 +512,16 @@ static const nsSTSPreload kSTSPreloadList[] = { { "gnetwork.eu", true }, { "go.xero.com", false }, { "gocardless.com", true }, + { "gokmenguresci.com", true }, + { "goodwin43.ru", true }, { "googlemail.com", false }, { "googleplex.com", true }, { "goto.google.com", true }, { "gotowned.org", true }, + { "gotspot.com", true }, { "gplintegratedit.com", true }, { "gpsfix.cz", true }, + { "gra2.com", true }, { "grc.com", false }, { "greensolid.biz", true }, { "grepular.com", true }, @@ -507,7 +529,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "groups.google.com", true }, { "gtraxapp.com", true }, { "gudini.net", true }, - { "gugga.dk", true }, + { "gugga.dk", false }, { "guidetoiceland.is", true }, { "gunnarhafdal.com", true }, { "guphi.net", true }, @@ -543,6 +565,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "hg.python.org", true }, { "hicoria.com", true }, { "history.google.com", true }, + { "hledejpravnika.cz", true }, { "honeybadger.io", false }, { "horseboners.xxx", true }, { "horza.org", true }, @@ -572,6 +595,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "ihrlotto.de", true }, { "ijohan.nl", true }, { "ikkatsu-satei.jp", true }, + { "ilikerainbows.co", true }, { "ilikerainbows.co.uk", false }, { "imaginary.ca", true }, { "imgg.es", true }, @@ -579,6 +603,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "in.xero.com", false }, { "inb4.us", true }, { "inbox.google.com", true }, + { "indiecert.net", true }, { "iniiter.com", true }, { "inkbunny.net", true }, { "inleaked.com", true }, @@ -593,6 +618,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "iranianlawschool.com", true }, { "iridiumbrowser.de", true }, { "irische-segenswuensche.info", true }, + { "irmag.ru", true }, { "ironfistdesign.com", true }, { "isitchristmas.com", true }, { "isogram.nl", true }, @@ -621,10 +647,12 @@ static const nsSTSPreload kSTSPreloadList[] = { { "jmedved.com", true }, { "johannes.io", true }, { "johners.me", true }, + { "johnmichel.org", true }, { "jonas-keidel.de", true }, { "jonaswitmer.ch", true }, { "jonathan.ir", true }, { "jonnybarnes.uk", true }, + { "jonpads.com", true }, { "jrc9.ca", true }, { "julian-kipka.de", true }, { "jwilsson.com", true }, @@ -641,6 +669,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "kdex.de", true }, { "kdyby.org", true }, { "keeleysam.com", true }, + { "keeleysam.me", true }, { "keepa.com", true }, { "keepclean.me", true }, { "keeperapp.com", true }, @@ -673,7 +702,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "koenvdheuvel.me", true }, { "kojipkgs.fedoraproject.org", true }, { "kollawat.me", true }, - { "komandakovalchuk.com", true }, + { "komandakovalchuk.com", false }, { "konklone.com", true }, { "koop-bremen.de", true }, { "koordinate.net", true }, @@ -686,6 +715,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "laf.in.net", true }, { "lagerauftrag.info", true }, { "lancejames.com", true }, + { "lapetition.be", true }, { "lasst-uns-beten.de", true }, { "lastpass.com", false }, { "launchkey.com", true }, @@ -741,6 +771,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "m.facebook.com", false }, { "m.mail.ru", true }, { "m0wef.uk", true }, + { "maartenvandekamp.nl", true }, { "mach-politik.ch", true }, { "madars.org", true }, { "madeitwor.se", true }, @@ -781,6 +812,9 @@ static const nsSTSPreload kSTSPreloadList[] = { { "max.gov", true }, { "mbasic.facebook.com", false }, { "mbp.banking.co.at", false }, + { "mcard.vn", true }, + { "mccrypto.de", true }, + { "mcnext.net", true }, { "md5file.com", true }, { "mdfnet.se", false }, { "meamod.com", true }, @@ -799,6 +833,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "miasarafina.de", true }, { "michalspacek.cz", true }, { "miconcinemas.com", true }, + { "micropple.net", true }, { "mig5.net", true }, { "mike-bland.com", true }, { "miketabor.com", true }, @@ -840,6 +875,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "mtouch.facebook.com", false }, { "mudcrab.us", true }, { "munich-rage.de", true }, + { "munki.org", true }, { "munuc.org", true }, { "musicgamegalaxy.de", true }, { "mustika.cf", true }, @@ -875,6 +911,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "neko.li", true }, { "nemovement.org", true }, { "net-safe.info", true }, + { "netbox.cc", true }, { "netera.se", true }, { "netrider.net.au", true }, { "netzbit.de", true }, @@ -913,6 +950,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "offshore-firma.org", true }, { "ohling.org", true }, { "okmx.de", true }, + { "olivierlemoal.fr", true }, { "omitech.co.uk", true }, { "onedot.nl", true }, { "onedrive.com", true }, @@ -920,7 +958,6 @@ static const nsSTSPreload kSTSPreloadList[] = { { "onsitemassageco.com", true }, { "ooonja.de", true }, { "openacademies.com", true }, - { "opendesk.cc", true }, { "oplop.appspot.com", true }, { "opsmate.com", false }, { "optimus.io", true }, @@ -969,6 +1006,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "perfectionis.me", true }, { "personaldatabasen.no", true }, { "pestici.de", true }, + { "petplum.com", true }, { "petrolplus.ru", true }, { "pharmaboard.de", true }, { "philosopherswool.com", true }, @@ -977,8 +1015,10 @@ static const nsSTSPreload kSTSPreloadList[] = { { "phryanjr.com", false }, { "phurl.de", true }, { "picksin.club", true }, + { "picsto.re", true }, { "pieperhome.de", true }, { "pierre-schmitz.com", true }, + { "pirateproxy.sx", true }, { "pixel.facebook.com", false }, { "pixi.me", true }, { "play.google.com", true }, @@ -1006,6 +1046,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "propagandism.org", true }, { "prowhisky.de", true }, { "proximato.com", true }, + { "proxybay.info", true }, { "ptn.moscow", true }, { "puac.de", true }, { "pubkey.is", true }, @@ -1031,6 +1072,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "ravchat.com", true }, { "rawstorieslondon.com", true }, { "reaconverter.com", true }, + { "red-t-shirt.ru", true }, { "redirect.fedoraproject.org", true }, { "redirect.stg.fedoraproject.org", true }, { "redletter.link", true }, @@ -1045,6 +1087,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "research.facebook.com", false }, { "reserve-online.net", true }, { "residentsinsurance.co.uk", true }, + { "resources.flowfinity.com", true }, { "reviews.anime.my", true }, { "riccy.org", true }, { "richiemail.net", true }, @@ -1092,6 +1135,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "saulchristie.com", true }, { "save.gov", true }, { "saveaward.gov", true }, + { "savetheinternet.eu", true }, { "savvytime.com", true }, { "schachburg.de", true }, { "schokokeks.org", false }, @@ -1130,6 +1174,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "shodan.io", true }, { "shopontarget.com", true }, { "shortdiary.me", true }, + { "siewert-kau.de", true }, { "sigterm.sh", true }, { "sikayetvar.com", true }, { "silentcircle.com", false }, @@ -1143,6 +1188,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "sites.google.com", true }, { "sitesten.com", true }, { "sjoorm.com", true }, + { "skeeley.com", true }, { "skhosting.eu", true }, { "skogsbruket.fi", true }, { "skogskultur.fi", true }, @@ -1159,6 +1205,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "snakehosting.dk", true }, { "snowflake.ch", false }, { "sockeye.cc", true }, + { "soia.ca", true }, { "sorz.org", true }, { "souki.cz", true }, { "soulogic.com", true }, @@ -1201,6 +1248,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "subrosa.io", true }, { "suite73.org", true }, { "sunjaydhama.com", true }, + { "suos.io", true }, { "supplies24.at", true }, { "supplies24.es", true }, { "support.mayfirst.org", false }, @@ -1213,6 +1261,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "sysctl.se", true }, { "sysdb.io", true }, { "syss.de", true }, + { "syzygy-tables.info", true }, { "tadigitalstore.com", true }, { "tageau.com", true }, { "taglondon.org", true }, @@ -1230,7 +1279,6 @@ static const nsSTSPreload kSTSPreloadList[] = { { "teachforcanada.ca", true }, { "teamnorthgermany.de", true }, { "techhipster.net", true }, - { "techllage.com", true }, { "techloaner.com", true }, { "tegelsensanitaironline.nl", true }, { "tekshrek.com", true }, @@ -1267,6 +1315,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "tno.io", true }, { "tobias-kluge.de", true }, { "todesschaf.org", true }, + { "todoist.com", true }, { "tollmanz.com", true }, { "tomfisher.eu", true }, { "tomharling.co.uk", true }, @@ -1313,6 +1362,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "twisto.cz", true }, { "twitter.com", false }, { "twitteroauth.com", true }, + { "twofactorauth.org", true }, { "typingrevolution.com", true }, { "uae-company-service.com", true }, { "ub3rk1tten.com", true }, @@ -1342,14 +1392,15 @@ static const nsSTSPreload kSTSPreloadList[] = { { "vmoagents.com", false }, { "vocaloid.my", true }, { "vortexhobbies.com", true }, + { "vox.vg", true }, { "vpnzoom.com", true }, { "vrobert.fr", false }, { "w-spotlight.appspot.com", true }, { "wallet.google.com", true }, + { "walnutgaming.com", true }, { "warrencreative.com", false }, { "watsonhall.uk", true }, { "wbg-vs.de", true }, - { "wearvr.com", true }, { "webandmore.de", false }, { "webandwords.com.au", true }, { "webassadors.com", false }, @@ -1363,6 +1414,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "webmail.gigahost.dk", false }, { "webmail.onlime.ch", false }, { "webmail.schokokeks.org", false }, + { "webrebels.org", true }, { "websenat.de", true }, { "webtalis.nl", true }, { "webtiles.co.uk", true }, @@ -1389,6 +1441,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "wherephoto.com", true }, { "whocalld.com", true }, { "whonix.org", true }, + { "widememory.com", true }, { "wieninternational.at", true }, { "wifirst.net", true }, { "wiki.python.org", true }, @@ -1404,6 +1457,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "wubthecaptain.eu", true }, { "wunderlist.com", true }, { "wundi.net", true }, + { "wvr-law.de", true }, { "www.aclu.org", false }, { "www.airbnb.com", true }, { "www.apollo-auto.com", true }, @@ -1452,7 +1506,10 @@ static const nsSTSPreload kSTSPreloadList[] = { { "www.wepay.com", false }, { "www.zenpayroll.com", false }, { "wzrd.in", true }, + { "wzyboy.org", true }, { "xbrlsuccess.appspot.com", true }, + { "xenesisziarovky.sk", true }, + { "xf-liam.com", true }, { "xn--maraa-rta.org", true }, { "xps2pdf.co.uk", true }, { "xuntier.ch", true }, @@ -1461,6 +1518,8 @@ static const nsSTSPreload kSTSPreloadList[] = { { "yanovich.net", true }, { "yaporn.tv", false }, { "yetii.net", true }, + { "yksityisyydensuoja.fi", true }, + { "yokeepo.com", true }, { "yorcom.nl", true }, { "yoursecondphone.co", true }, { "ypart.eu", true }, @@ -1473,4 +1532,5 @@ static const nsSTSPreload kSTSPreloadList[] = { { "zhovner.com", false }, { "zixiao.wang", true }, { "zlavomat.sk", true }, + { "zravypapir.cz", true }, }; diff --git a/security/manager/ssl/tests/unit/test_ocsp_timeout.js b/security/manager/ssl/tests/unit/test_ocsp_timeout.js index ff2d7a658ae..80e4fa1a777 100644 --- a/security/manager/ssl/tests/unit/test_ocsp_timeout.js +++ b/security/manager/ssl/tests/unit/test_ocsp_timeout.js @@ -64,10 +64,14 @@ function add_tests_in_mode(useHardFail) { // With OCSP hard-fail on, we timeout after 10 seconds. // With OCSP soft-fail, we timeout after 2 seconds. + // Date() is not guaranteed to be monotonic, so add extra fuzz time to + // prevent intermittent failures (this only appeared to be a problem on + // Windows XP). See Bug 1121117. + const FUZZ_MS = 300; if (useHardFail) { - do_check_true(timeDifference > 10000); + do_check_true(timeDifference + FUZZ_MS > 10000); } else { - do_check_true(timeDifference > 2000); + do_check_true(timeDifference + FUZZ_MS > 2000); } // Make sure we didn't wait too long. // (Unfortunately, we probably can't have a tight upper bound on diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO index bd6b016fe0d..5e95d43bbaf 100644 --- a/security/nss/TAG-INFO +++ b/security/nss/TAG-INFO @@ -1 +1 @@ -NSS_3_18_RC0 +NSS_3_18_RTM diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep index 590d1bfaeee..5182f75552c 100644 --- a/security/nss/coreconf/coreconf.dep +++ b/security/nss/coreconf/coreconf.dep @@ -10,4 +10,3 @@ */ #error "Do not include this header file." - diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h index 02caa8250a4..6e0bdb0892f 100644 --- a/security/nss/lib/certdb/cert.h +++ b/security/nss/lib/certdb/cert.h @@ -932,11 +932,6 @@ extern char * CERT_FindNSStringExtension (CERTCertificate *cert, int oidtag); extern SECStatus CERT_FindCertExtensionByOID (CERTCertificate *cert, SECItem *oid, SECItem *value); -/* Find a URL extension in the cert. -** The caller must free the result string using PORT_Free. -*/ -extern char *CERT_FindCertURLExtension (CERTCertificate *cert, SECOidTag tag); - /* Returns the decoded value of the authKeyID extension. ** Note that this uses passed in the arena to allocate storage for the result */ diff --git a/security/nss/lib/certdb/certdb.h b/security/nss/lib/certdb/certdb.h index d0d53c30f64..d358dfd822f 100644 --- a/security/nss/lib/certdb/certdb.h +++ b/security/nss/lib/certdb/certdb.h @@ -75,6 +75,21 @@ SECStatus SEC_DeletePermCertificate(CERTCertificate *cert); PRBool SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old); +/* +** Extract the validity times from a CRL +** "crl" is the CRL +** "notBefore" is the start of the validity period (last update) +** "notAfter" is the end of the validity period (next update) +*/ +SECStatus +SEC_GetCrlTimes(CERTCrl *crl, PRTime *notBefore, PRTime *notAfter); + +/* +** Check the validity times of a crl vs. time 't', allowing +** some slop for broken clocks and stuff. +** "crl" is the certificate to be checked +** "t" is the time to check against +*/ SECCertTimeValidity SEC_CheckCrlTimes(CERTCrl *crl, PRTime t); diff --git a/security/nss/lib/certdb/certv3.c b/security/nss/lib/certdb/certv3.c index fdf3d5f3859..1735b5e44cd 100644 --- a/security/nss/lib/certdb/certv3.c +++ b/security/nss/lib/certdb/certv3.c @@ -43,72 +43,6 @@ CERT_StartCertExtensions(CERTCertificate *cert) return (cert_StartExtensions ((void *)cert, cert->arena, SetExts)); } -/* find a URL extension in the cert - */ -char * -CERT_FindCertURLExtension(CERTCertificate *cert, SECOidTag tag) -{ - SECStatus rv; - SECItem urlitem = {siBuffer,0}; - SECItem urlstringitem = {siBuffer,0}; - PLArenaPool *arena = NULL; - char *urlstring = NULL; - char *str; - int len; - - if (!cert) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( ! arena ) { - goto loser; - } - - rv = cert_FindExtension(cert->extensions, tag, &urlitem); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = SEC_QuickDERDecodeItem(arena, &urlstringitem, - SEC_ASN1_GET(SEC_IA5StringTemplate), &urlitem); - - if ( rv != SECSuccess ) { - goto loser; - } - - len = urlstringitem.len + 1; - - str = urlstring = (char *)PORT_Alloc(len); - if ( urlstring == NULL ) { - goto loser; - } - - /* copy the URL */ - PORT_Memcpy(str, urlstringitem.data, urlstringitem.len); - str += urlstringitem.len; - - *str = '\0'; - goto done; - -loser: - if ( urlstring ) { - PORT_Free(urlstring); - } - - urlstring = NULL; -done: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - if ( urlitem.data ) { - PORT_Free(urlitem.data); - } - - return(urlstring); -} - /* * get the value of the Netscape Certificate Type Extension */ diff --git a/security/nss/lib/ckfw/builtins/certdata.txt b/security/nss/lib/ckfw/builtins/certdata.txt index eaf40f13f06..00458863372 100644 --- a/security/nss/lib/ckfw/builtins/certdata.txt +++ b/security/nss/lib/ckfw/builtins/certdata.txt @@ -187,9 +187,9 @@ END CKA_SERIAL_NUMBER MULTILINE_OCTAL \002\004\065\336\364\317 END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # Distrust "Distrust a pb.com certificate that does not comply with the baseline requirements." @@ -2457,9 +2457,9 @@ END CKA_SERIAL_NUMBER MULTILINE_OCTAL \002\001\001 END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # @@ -13174,9 +13174,9 @@ END CKA_SERIAL_NUMBER MULTILINE_OCTAL \002\016\112\107\000\001\000\002\345\240\135\326\077\000\121\277 END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # @@ -30320,3 +30320,1273 @@ CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "Staat der Nederlanden Root CA - G3" +# +# Issuer: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL +# Serial Number: 10003001 (0x98a239) +# Subject: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL +# Not Valid Before: Thu Nov 14 11:28:42 2013 +# Not Valid After : Mon Nov 13 23:00:00 2028 +# Fingerprint (SHA-256): 3C:4F:B0:B9:5A:B8:B3:00:32:F4:32:B8:6F:53:5F:E1:72:C1:85:D0:FD:39:86:58:37:CF:36:18:7F:A6:F4:28 +# Fingerprint (SHA1): D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Staat der Nederlanden Root CA - G3" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061 +\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 +\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 +\053\060\051\006\003\125\004\003\014\042\123\164\141\141\164\040 +\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 +\122\157\157\164\040\103\101\040\055\040\107\063 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061 +\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 +\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 +\053\060\051\006\003\125\004\003\014\042\123\164\141\141\164\040 +\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 +\122\157\157\164\040\103\101\040\055\040\107\063 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\004\000\230\242\071 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\164\060\202\003\134\240\003\002\001\002\002\004\000 +\230\242\071\060\015\006\011\052\206\110\206\367\015\001\001\013 +\005\000\060\132\061\013\060\011\006\003\125\004\006\023\002\116 +\114\061\036\060\034\006\003\125\004\012\014\025\123\164\141\141 +\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145 +\156\061\053\060\051\006\003\125\004\003\014\042\123\164\141\141 +\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145 +\156\040\122\157\157\164\040\103\101\040\055\040\107\063\060\036 +\027\015\061\063\061\061\061\064\061\061\062\070\064\062\132\027 +\015\062\070\061\061\061\063\062\063\060\060\060\060\132\060\132 +\061\013\060\011\006\003\125\004\006\023\002\116\114\061\036\060 +\034\006\003\125\004\012\014\025\123\164\141\141\164\040\144\145 +\162\040\116\145\144\145\162\154\141\156\144\145\156\061\053\060 +\051\006\003\125\004\003\014\042\123\164\141\141\164\040\144\145 +\162\040\116\145\144\145\162\154\141\156\144\145\156\040\122\157 +\157\164\040\103\101\040\055\040\107\063\060\202\002\042\060\015 +\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002 +\017\000\060\202\002\012\002\202\002\001\000\276\062\242\124\017 +\160\373\054\134\131\353\154\304\244\121\350\205\052\263\314\112 +\064\362\260\137\363\016\307\034\075\123\036\210\010\150\330\157 +\075\255\302\236\314\202\147\007\047\207\150\161\072\237\165\226 +\042\106\005\260\355\255\307\133\236\052\336\234\374\072\306\225 +\247\365\027\147\030\347\057\111\010\014\134\317\346\314\064\355 +\170\373\120\261\334\153\062\360\242\376\266\074\344\354\132\227 +\307\077\036\160\010\060\240\334\305\263\155\157\320\202\162\021 +\253\322\201\150\131\202\027\267\170\222\140\372\314\336\077\204 +\353\215\070\063\220\012\162\043\372\065\314\046\161\061\321\162 +\050\222\331\133\043\155\146\265\155\007\102\353\246\063\316\222 +\333\300\366\154\143\170\315\312\116\075\265\345\122\233\361\276 +\073\346\124\140\260\146\036\011\253\007\376\124\211\021\102\321 +\367\044\272\140\170\032\230\367\311\021\375\026\301\065\032\124 +\165\357\103\323\345\256\116\316\347\173\303\306\116\141\121\113 +\253\232\105\113\241\037\101\275\110\123\025\161\144\013\206\263 +\345\056\276\316\244\033\301\051\204\242\265\313\010\043\166\103 +\042\044\037\027\004\324\156\234\306\374\177\053\146\032\354\212 +\345\326\317\115\365\143\011\267\025\071\326\173\254\353\343\174 +\351\116\374\165\102\310\355\130\225\014\006\102\242\234\367\344 +\160\263\337\162\157\132\067\100\211\330\205\244\327\361\013\336 +\103\031\324\112\130\054\214\212\071\236\277\204\207\361\026\073 +\066\014\351\323\264\312\154\031\101\122\011\241\035\260\152\277 +\202\357\160\121\041\062\334\005\166\214\313\367\144\344\003\120 +\257\214\221\147\253\305\362\356\130\330\336\276\367\347\061\317 +\154\311\073\161\301\325\210\265\145\274\300\350\027\027\007\022 +\265\134\322\253\040\223\264\346\202\203\160\066\305\315\243\215 +\255\213\354\243\301\103\207\346\103\342\064\276\225\213\065\355 +\007\071\332\250\035\172\237\066\236\022\260\014\145\022\220\025 +\140\331\046\100\104\343\126\140\245\020\324\152\074\375\101\334 +\016\132\107\266\357\227\141\165\117\331\376\307\262\035\324\355 +\135\111\263\251\152\313\146\204\023\325\134\240\334\337\156\167 +\006\321\161\165\310\127\157\257\017\167\133\002\003\001\000\001 +\243\102\060\100\060\017\006\003\125\035\023\001\001\377\004\005 +\060\003\001\001\377\060\016\006\003\125\035\017\001\001\377\004 +\004\003\002\001\006\060\035\006\003\125\035\016\004\026\004\024 +\124\255\372\307\222\127\256\312\065\234\056\022\373\344\272\135 +\040\334\224\127\060\015\006\011\052\206\110\206\367\015\001\001 +\013\005\000\003\202\002\001\000\060\231\235\005\062\310\136\016 +\073\230\001\072\212\244\347\007\367\172\370\347\232\337\120\103 +\123\227\052\075\312\074\107\230\056\341\025\173\361\222\363\141 +\332\220\045\026\145\300\237\124\135\016\003\073\133\167\002\234 +\204\266\015\230\137\064\335\073\143\302\303\050\201\302\234\051 +\056\051\342\310\303\001\362\063\352\052\252\314\011\010\367\145 +\147\306\315\337\323\266\053\247\275\314\321\016\160\137\270\043 +\321\313\221\116\012\364\310\172\345\331\143\066\301\324\337\374 +\042\227\367\140\135\352\051\057\130\262\275\130\275\215\226\117 +\020\165\277\110\173\075\121\207\241\074\164\042\302\374\007\177 +\200\334\304\254\376\152\301\160\060\260\351\216\151\342\054\151 +\201\224\011\272\335\376\115\300\203\214\224\130\300\106\040\257 +\234\037\002\370\065\125\111\057\106\324\300\360\240\226\002\017 +\063\305\161\363\236\043\175\224\267\375\072\323\011\203\006\041 +\375\140\075\256\062\300\322\356\215\246\360\347\264\202\174\012 +\314\160\311\171\200\370\376\114\367\065\204\031\212\061\373\012 +\331\327\177\233\360\242\232\153\303\005\112\355\101\140\024\060 +\321\252\021\102\156\323\043\002\004\013\306\145\335\335\122\167 +\332\201\153\262\250\372\001\070\271\226\352\052\154\147\227\211 +\224\236\274\341\124\325\344\152\170\357\112\275\053\232\075\100 +\176\306\300\165\322\156\373\150\060\354\354\213\235\371\111\065 +\232\032\054\331\263\225\071\325\036\222\367\246\271\145\057\345 +\075\155\072\110\114\010\334\344\050\022\050\276\175\065\134\352 +\340\026\176\023\033\152\327\076\327\236\374\055\165\262\301\024 +\325\043\003\333\133\157\013\076\170\057\015\336\063\215\026\267 +\110\347\203\232\201\017\173\301\103\115\125\004\027\070\112\121 +\325\131\242\211\164\323\237\276\036\113\327\306\155\267\210\044 +\157\140\221\244\202\205\133\126\101\274\320\104\253\152\023\276 +\321\054\130\267\022\063\130\262\067\143\334\023\365\224\035\077 +\100\121\365\117\365\072\355\310\305\353\302\036\035\026\225\172 +\307\176\102\161\223\156\113\025\267\060\337\252\355\127\205\110 +\254\035\152\335\071\151\344\341\171\170\276\316\005\277\241\014 +\367\200\173\041\147\047\060\131 +END + +# Trust for "Staat der Nederlanden Root CA - G3" +# Issuer: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL +# Serial Number: 10003001 (0x98a239) +# Subject: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL +# Not Valid Before: Thu Nov 14 11:28:42 2013 +# Not Valid After : Mon Nov 13 23:00:00 2028 +# Fingerprint (SHA-256): 3C:4F:B0:B9:5A:B8:B3:00:32:F4:32:B8:6F:53:5F:E1:72:C1:85:D0:FD:39:86:58:37:CF:36:18:7F:A6:F4:28 +# Fingerprint (SHA1): D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Staat der Nederlanden Root CA - G3" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\330\353\153\101\121\222\131\340\363\347\205\000\300\075\266\210 +\227\311\356\374 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\013\106\147\007\333\020\057\031\214\065\120\140\321\013\364\067 +END +CKA_ISSUER MULTILINE_OCTAL +\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061 +\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 +\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 +\053\060\051\006\003\125\004\003\014\042\123\164\141\141\164\040 +\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 +\122\157\157\164\040\103\101\040\055\040\107\063 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\004\000\230\242\071 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "Staat der Nederlanden EV Root CA" +# +# Issuer: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL +# Serial Number: 10000013 (0x98968d) +# Subject: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL +# Not Valid Before: Wed Dec 08 11:19:29 2010 +# Not Valid After : Thu Dec 08 11:10:28 2022 +# Fingerprint (SHA-256): 4D:24:91:41:4C:FE:95:67:46:EC:4C:EF:A6:CF:6F:72:E2:8A:13:29:43:2F:9D:8A:90:7A:C4:CB:5D:AD:C1:5A +# Fingerprint (SHA1): 76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Staat der Nederlanden EV Root CA" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\130\061\013\060\011\006\003\125\004\006\023\002\116\114\061 +\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 +\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 +\051\060\047\006\003\125\004\003\014\040\123\164\141\141\164\040 +\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 +\105\126\040\122\157\157\164\040\103\101 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\130\061\013\060\011\006\003\125\004\006\023\002\116\114\061 +\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 +\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 +\051\060\047\006\003\125\004\003\014\040\123\164\141\141\164\040 +\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 +\105\126\040\122\157\157\164\040\103\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\004\000\230\226\215 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\160\060\202\003\130\240\003\002\001\002\002\004\000 +\230\226\215\060\015\006\011\052\206\110\206\367\015\001\001\013 +\005\000\060\130\061\013\060\011\006\003\125\004\006\023\002\116 +\114\061\036\060\034\006\003\125\004\012\014\025\123\164\141\141 +\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145 +\156\061\051\060\047\006\003\125\004\003\014\040\123\164\141\141 +\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145 +\156\040\105\126\040\122\157\157\164\040\103\101\060\036\027\015 +\061\060\061\062\060\070\061\061\061\071\062\071\132\027\015\062 +\062\061\062\060\070\061\061\061\060\062\070\132\060\130\061\013 +\060\011\006\003\125\004\006\023\002\116\114\061\036\060\034\006 +\003\125\004\012\014\025\123\164\141\141\164\040\144\145\162\040 +\116\145\144\145\162\154\141\156\144\145\156\061\051\060\047\006 +\003\125\004\003\014\040\123\164\141\141\164\040\144\145\162\040 +\116\145\144\145\162\154\141\156\144\145\156\040\105\126\040\122 +\157\157\164\040\103\101\060\202\002\042\060\015\006\011\052\206 +\110\206\367\015\001\001\001\005\000\003\202\002\017\000\060\202 +\002\012\002\202\002\001\000\343\307\176\211\371\044\113\072\322 +\063\203\065\054\151\354\334\011\244\343\121\250\045\053\171\270 +\010\075\340\221\272\204\205\306\205\244\312\346\311\056\123\244 +\311\044\036\375\125\146\161\135\054\305\140\150\004\267\331\302 +\122\046\070\210\244\326\073\100\246\302\315\077\315\230\223\263 +\124\024\130\226\125\325\120\376\206\255\244\143\177\134\207\366 +\216\346\047\222\147\027\222\002\003\054\334\326\146\164\355\335 +\147\377\301\141\215\143\117\017\233\155\027\060\046\357\253\322 +\037\020\240\371\305\177\026\151\201\003\107\355\036\150\215\162 +\241\115\262\046\306\272\154\137\155\326\257\321\261\023\216\251 +\255\363\136\151\165\046\030\076\101\053\041\177\356\213\135\007 +\006\235\103\304\051\012\053\374\052\076\206\313\074\203\072\371 +\311\015\332\305\231\342\274\170\101\063\166\341\277\057\135\345 +\244\230\120\014\025\335\340\372\234\177\070\150\320\262\246\172 +\247\321\061\275\176\212\130\047\103\263\272\063\221\323\247\230 +\025\134\232\346\323\017\165\331\374\101\230\227\076\252\045\333 +\217\222\056\260\173\014\137\361\143\251\067\371\233\165\151\114 +\050\046\045\332\325\362\022\160\105\125\343\337\163\136\067\365 +\041\154\220\216\065\132\311\323\043\353\323\300\276\170\254\102 +\050\130\146\245\106\155\160\002\327\020\371\113\124\374\135\206 +\112\207\317\177\312\105\254\021\132\265\040\121\215\057\210\107 +\227\071\300\317\272\300\102\001\100\231\110\041\013\153\247\322 +\375\226\325\321\276\106\235\111\340\013\246\240\042\116\070\320 +\301\074\060\274\160\217\054\165\314\320\305\214\121\073\075\224 +\010\144\046\141\175\271\303\145\217\024\234\041\320\252\375\027 +\162\003\217\275\233\214\346\136\123\236\271\235\357\202\273\341 +\274\342\162\101\133\041\224\323\105\067\224\321\337\011\071\135 +\347\043\252\232\035\312\155\250\012\206\205\212\202\276\102\007 +\326\362\070\202\163\332\207\133\345\074\323\236\076\247\073\236 +\364\003\263\371\361\175\023\164\002\377\273\241\345\372\000\171 +\034\246\146\101\210\134\140\127\246\056\011\304\272\375\232\317 +\247\037\100\303\273\314\132\012\125\113\073\070\166\121\270\143 +\213\204\224\026\346\126\363\002\003\001\000\001\243\102\060\100 +\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001 +\377\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001 +\006\060\035\006\003\125\035\016\004\026\004\024\376\253\000\220 +\230\236\044\374\251\314\032\212\373\047\270\277\060\156\250\073 +\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\003 +\202\002\001\000\317\167\054\156\126\276\116\263\266\204\000\224 +\253\107\311\015\322\166\307\206\237\035\007\323\266\264\273\010 +\170\257\151\322\013\111\336\063\305\254\255\302\210\002\175\006 +\267\065\002\301\140\311\277\304\350\224\336\324\323\251\023\045 +\132\376\156\242\256\175\005\334\175\363\154\360\176\246\215\356 +\331\327\316\130\027\350\251\051\256\163\110\207\347\233\312\156 +\051\241\144\137\031\023\367\256\006\020\377\121\306\233\115\125 +\045\117\223\231\020\001\123\165\361\023\316\307\246\101\101\322 +\277\210\245\177\105\374\254\270\245\265\063\014\202\304\373\007 +\366\152\345\045\204\137\006\312\301\206\071\021\333\130\315\167 +\073\054\302\114\017\136\232\343\360\253\076\141\033\120\044\302 +\300\364\361\031\360\021\051\266\245\030\002\233\327\143\114\160 +\214\107\243\003\103\134\271\135\106\240\015\157\377\131\216\276 +\335\237\162\303\133\053\337\214\133\316\345\014\106\154\222\262 +\012\243\114\124\102\030\025\022\030\275\332\374\272\164\156\377 +\301\266\240\144\330\251\137\125\256\237\134\152\166\226\330\163 +\147\207\373\115\177\134\356\151\312\163\020\373\212\251\375\236 +\275\066\070\111\111\207\364\016\024\360\351\207\270\077\247\117 +\172\132\216\171\324\223\344\273\150\122\204\254\154\351\363\230 +\160\125\162\062\371\064\253\053\111\265\315\040\142\344\072\172 +\147\143\253\226\334\155\256\227\354\374\237\166\126\210\056\146 +\317\133\266\311\244\260\327\005\272\341\047\057\223\273\046\052 +\242\223\260\033\363\216\276\035\100\243\271\066\217\076\202\032 +\032\136\210\352\120\370\131\342\203\106\051\013\343\104\134\341 +\225\266\151\220\232\024\157\227\256\201\317\150\357\231\232\276 +\265\347\341\177\370\372\023\107\026\114\314\155\010\100\347\213 +\170\157\120\202\104\120\077\146\006\212\253\103\204\126\112\017 +\040\055\206\016\365\322\333\322\172\212\113\315\245\350\116\361 +\136\046\045\001\131\043\240\176\322\366\176\041\127\327\047\274 +\025\127\114\244\106\301\340\203\036\014\114\115\037\117\006\031 +\342\371\250\364\072\202\241\262\171\103\171\326\255\157\172\047 +\220\003\244\352\044\207\077\331\275\331\351\362\137\120\111\034 +\356\354\327\056 +END + +# Trust for "Staat der Nederlanden EV Root CA" +# Issuer: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL +# Serial Number: 10000013 (0x98968d) +# Subject: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL +# Not Valid Before: Wed Dec 08 11:19:29 2010 +# Not Valid After : Thu Dec 08 11:10:28 2022 +# Fingerprint (SHA-256): 4D:24:91:41:4C:FE:95:67:46:EC:4C:EF:A6:CF:6F:72:E2:8A:13:29:43:2F:9D:8A:90:7A:C4:CB:5D:AD:C1:5A +# Fingerprint (SHA1): 76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Staat der Nederlanden EV Root CA" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\166\342\176\301\117\333\202\301\300\246\165\265\005\276\075\051 +\264\355\333\273 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\374\006\257\173\350\032\361\232\264\350\322\160\037\300\365\272 +END +CKA_ISSUER MULTILINE_OCTAL +\060\130\061\013\060\011\006\003\125\004\006\023\002\116\114\061 +\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 +\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 +\051\060\047\006\003\125\004\003\014\040\123\164\141\141\164\040 +\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 +\105\126\040\122\157\157\164\040\103\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\004\000\230\226\215 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "IdenTrust Commercial Root CA 1" +# +# Issuer: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US +# Serial Number:0a:01:42:80:00:00:01:45:23:c8:44:b5:00:00:00:02 +# Subject: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US +# Not Valid Before: Thu Jan 16 18:12:23 2014 +# Not Valid After : Mon Jan 16 18:12:23 2034 +# Fingerprint (SHA-256): 5D:56:49:9B:E4:D2:E0:8B:CF:CA:D0:8A:3E:38:72:3D:50:50:3B:DE:70:69:48:E4:2F:55:60:30:19:E5:28:AE +# Fingerprint (SHA1): DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25 +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "IdenTrust Commercial Root CA 1" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\112\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 +\165\163\164\061\047\060\045\006\003\125\004\003\023\036\111\144 +\145\156\124\162\165\163\164\040\103\157\155\155\145\162\143\151 +\141\154\040\122\157\157\164\040\103\101\040\061 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\112\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 +\165\163\164\061\047\060\045\006\003\125\004\003\023\036\111\144 +\145\156\124\162\165\163\164\040\103\157\155\155\145\162\143\151 +\141\154\040\122\157\157\164\040\103\101\040\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\012\001\102\200\000\000\001\105\043\310\104\265\000\000 +\000\002 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\140\060\202\003\110\240\003\002\001\002\002\020\012 +\001\102\200\000\000\001\105\043\310\104\265\000\000\000\002\060 +\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\112 +\061\013\060\011\006\003\125\004\006\023\002\125\123\061\022\060 +\020\006\003\125\004\012\023\011\111\144\145\156\124\162\165\163 +\164\061\047\060\045\006\003\125\004\003\023\036\111\144\145\156 +\124\162\165\163\164\040\103\157\155\155\145\162\143\151\141\154 +\040\122\157\157\164\040\103\101\040\061\060\036\027\015\061\064 +\060\061\061\066\061\070\061\062\062\063\132\027\015\063\064\060 +\061\061\066\061\070\061\062\062\063\132\060\112\061\013\060\011 +\006\003\125\004\006\023\002\125\123\061\022\060\020\006\003\125 +\004\012\023\011\111\144\145\156\124\162\165\163\164\061\047\060 +\045\006\003\125\004\003\023\036\111\144\145\156\124\162\165\163 +\164\040\103\157\155\155\145\162\143\151\141\154\040\122\157\157 +\164\040\103\101\040\061\060\202\002\042\060\015\006\011\052\206 +\110\206\367\015\001\001\001\005\000\003\202\002\017\000\060\202 +\002\012\002\202\002\001\000\247\120\031\336\077\231\075\324\063 +\106\361\157\121\141\202\262\251\117\217\147\211\135\204\331\123 +\335\014\050\331\327\360\377\256\225\103\162\231\371\265\135\174 +\212\301\102\341\061\120\164\321\201\015\174\315\233\041\253\103 +\342\254\255\136\206\156\363\011\212\037\132\062\275\242\353\224 +\371\350\134\012\354\377\230\322\257\161\263\264\123\237\116\207 +\357\222\274\275\354\117\062\060\210\113\027\136\127\304\123\302 +\366\002\227\215\331\142\053\277\044\037\142\215\337\303\270\051 +\113\111\170\074\223\140\210\042\374\231\332\066\310\302\242\324 +\054\124\000\147\065\156\163\277\002\130\360\244\335\345\260\242 +\046\172\312\340\066\245\031\026\365\375\267\357\256\077\100\365 +\155\132\004\375\316\064\312\044\334\164\043\033\135\063\023\022 +\135\304\001\045\366\060\335\002\135\237\340\325\107\275\264\353 +\033\241\273\111\111\330\237\133\002\363\212\344\044\220\344\142 +\117\117\301\257\213\016\164\027\250\321\162\210\152\172\001\111 +\314\264\106\171\306\027\261\332\230\036\007\131\372\165\041\205 +\145\335\220\126\316\373\253\245\140\235\304\235\371\122\260\213 +\275\207\371\217\053\043\012\043\166\073\367\063\341\311\000\363 +\151\371\113\242\340\116\274\176\223\071\204\007\367\104\160\176 +\376\007\132\345\261\254\321\030\314\362\065\345\111\111\010\312 +\126\311\075\373\017\030\175\213\073\301\023\302\115\217\311\117 +\016\067\351\037\241\016\152\337\142\056\313\065\006\121\171\054 +\310\045\070\364\372\113\247\211\134\234\322\343\015\071\206\112 +\164\174\325\131\207\302\077\116\014\134\122\364\075\367\122\202 +\361\352\243\254\375\111\064\032\050\363\101\210\072\023\356\350 +\336\377\231\035\137\272\313\350\036\362\271\120\140\300\061\323 +\163\345\357\276\240\355\063\013\164\276\040\040\304\147\154\360 +\010\003\172\125\200\177\106\116\226\247\364\036\076\341\366\330 +\011\341\063\144\053\143\327\062\136\237\371\300\173\017\170\157 +\227\274\223\232\371\234\022\220\170\172\200\207\025\327\162\164 +\234\125\164\170\261\272\341\156\160\004\272\117\240\272\150\303 +\173\377\061\360\163\075\075\224\052\261\013\101\016\240\376\115 +\210\145\153\171\063\264\327\002\003\001\000\001\243\102\060\100 +\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006 +\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001 +\377\060\035\006\003\125\035\016\004\026\004\024\355\104\031\300 +\323\360\006\213\356\244\173\276\102\347\046\124\310\216\066\166 +\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\003 +\202\002\001\000\015\256\220\062\366\246\113\174\104\166\031\141 +\036\047\050\315\136\124\357\045\274\343\010\220\371\051\327\256 +\150\010\341\224\000\130\357\056\056\176\123\122\214\266\134\007 +\352\210\272\231\213\120\224\327\202\200\337\141\011\000\223\255 +\015\024\346\316\301\362\067\224\170\260\137\234\263\242\163\270 +\217\005\223\070\315\215\076\260\270\373\300\317\261\362\354\055 +\055\033\314\354\252\232\263\252\140\202\033\055\073\303\204\075 +\127\212\226\036\234\165\270\323\060\315\140\010\203\220\323\216 +\124\361\115\146\300\135\164\003\100\243\356\205\176\302\037\167 +\234\006\350\301\247\030\135\122\225\355\311\335\045\236\155\372 +\251\355\243\072\064\320\131\173\332\355\120\363\065\277\355\353 +\024\115\061\307\140\364\332\361\207\234\342\110\342\306\305\067 +\373\006\020\372\165\131\146\061\107\051\332\166\232\034\351\202 +\256\357\232\271\121\367\210\043\232\151\225\142\074\345\125\200 +\066\327\124\002\377\361\271\135\316\324\043\157\330\105\204\112 +\133\145\357\211\014\335\024\247\040\313\030\245\045\264\015\371 +\001\360\242\322\364\000\310\164\216\241\052\110\216\145\333\023 +\304\342\045\027\175\353\276\207\133\027\040\124\121\223\112\123 +\003\013\354\135\312\063\355\142\375\105\307\057\133\334\130\240 +\200\071\346\372\327\376\023\024\246\355\075\224\112\102\164\324 +\303\167\131\163\315\217\106\276\125\070\357\372\350\221\062\352 +\227\130\004\042\336\070\303\314\274\155\311\063\072\152\012\151 +\077\240\310\352\162\217\214\143\206\043\275\155\074\226\236\225 +\340\111\114\252\242\271\052\033\234\066\201\170\355\303\350\106 +\342\046\131\104\165\036\331\165\211\121\315\020\204\235\141\140 +\313\135\371\227\042\115\216\230\346\343\177\366\133\273\256\315 +\312\112\201\153\136\013\363\121\341\164\053\351\176\047\247\331 +\231\111\116\370\245\200\333\045\017\034\143\142\212\311\063\147 +\153\074\020\203\306\255\336\250\315\026\216\215\360\007\067\161 +\237\362\253\374\101\365\301\213\354\000\067\135\011\345\116\200 +\357\372\261\134\070\006\245\033\112\341\334\070\055\074\334\253 +\037\220\032\325\112\234\356\321\160\154\314\356\364\127\370\030 +\272\204\156\207 +END + +# Trust for "IdenTrust Commercial Root CA 1" +# Issuer: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US +# Serial Number:0a:01:42:80:00:00:01:45:23:c8:44:b5:00:00:00:02 +# Subject: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US +# Not Valid Before: Thu Jan 16 18:12:23 2014 +# Not Valid After : Mon Jan 16 18:12:23 2034 +# Fingerprint (SHA-256): 5D:56:49:9B:E4:D2:E0:8B:CF:CA:D0:8A:3E:38:72:3D:50:50:3B:DE:70:69:48:E4:2F:55:60:30:19:E5:28:AE +# Fingerprint (SHA1): DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25 +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "IdenTrust Commercial Root CA 1" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\337\161\176\252\112\331\116\311\125\204\231\140\055\110\336\137 +\274\360\072\045 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\263\076\167\163\165\356\240\323\343\176\111\143\111\131\273\307 +END +CKA_ISSUER MULTILINE_OCTAL +\060\112\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 +\165\163\164\061\047\060\045\006\003\125\004\003\023\036\111\144 +\145\156\124\162\165\163\164\040\103\157\155\155\145\162\143\151 +\141\154\040\122\157\157\164\040\103\101\040\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\012\001\102\200\000\000\001\105\043\310\104\265\000\000 +\000\002 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "IdenTrust Public Sector Root CA 1" +# +# Issuer: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US +# Serial Number:0a:01:42:80:00:00:01:45:23:cf:46:7c:00:00:00:02 +# Subject: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US +# Not Valid Before: Thu Jan 16 17:53:32 2014 +# Not Valid After : Mon Jan 16 17:53:32 2034 +# Fingerprint (SHA-256): 30:D0:89:5A:9A:44:8A:26:20:91:63:55:22:D1:F5:20:10:B5:86:7A:CA:E1:2C:78:EF:95:8F:D4:F4:38:9F:2F +# Fingerprint (SHA1): BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "IdenTrust Public Sector Root CA 1" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\115\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 +\165\163\164\061\052\060\050\006\003\125\004\003\023\041\111\144 +\145\156\124\162\165\163\164\040\120\165\142\154\151\143\040\123 +\145\143\164\157\162\040\122\157\157\164\040\103\101\040\061 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\115\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 +\165\163\164\061\052\060\050\006\003\125\004\003\023\041\111\144 +\145\156\124\162\165\163\164\040\120\165\142\154\151\143\040\123 +\145\143\164\157\162\040\122\157\157\164\040\103\101\040\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\012\001\102\200\000\000\001\105\043\317\106\174\000\000 +\000\002 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\146\060\202\003\116\240\003\002\001\002\002\020\012 +\001\102\200\000\000\001\105\043\317\106\174\000\000\000\002\060 +\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\115 +\061\013\060\011\006\003\125\004\006\023\002\125\123\061\022\060 +\020\006\003\125\004\012\023\011\111\144\145\156\124\162\165\163 +\164\061\052\060\050\006\003\125\004\003\023\041\111\144\145\156 +\124\162\165\163\164\040\120\165\142\154\151\143\040\123\145\143 +\164\157\162\040\122\157\157\164\040\103\101\040\061\060\036\027 +\015\061\064\060\061\061\066\061\067\065\063\063\062\132\027\015 +\063\064\060\061\061\066\061\067\065\063\063\062\132\060\115\061 +\013\060\011\006\003\125\004\006\023\002\125\123\061\022\060\020 +\006\003\125\004\012\023\011\111\144\145\156\124\162\165\163\164 +\061\052\060\050\006\003\125\004\003\023\041\111\144\145\156\124 +\162\165\163\164\040\120\165\142\154\151\143\040\123\145\143\164 +\157\162\040\122\157\157\164\040\103\101\040\061\060\202\002\042 +\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003 +\202\002\017\000\060\202\002\012\002\202\002\001\000\266\042\224 +\374\244\110\257\350\107\153\012\373\047\166\344\362\077\212\073 +\172\112\054\061\052\214\215\260\251\303\061\153\250\167\166\204 +\046\266\254\201\102\015\010\353\125\130\273\172\370\274\145\175 +\362\240\155\213\250\107\351\142\166\036\021\356\010\024\321\262 +\104\026\364\352\320\372\036\057\136\333\313\163\101\256\274\000 +\260\112\053\100\262\254\341\073\113\302\055\235\344\241\233\354 +\032\072\036\360\010\263\320\344\044\065\007\237\234\264\311\122 +\155\333\007\312\217\265\133\360\203\363\117\307\055\245\310\255 +\313\225\040\244\061\050\127\130\132\344\215\033\232\253\236\015 +\014\362\012\063\071\042\071\012\227\056\363\123\167\271\104\105 +\375\204\313\066\040\201\131\055\232\157\155\110\110\141\312\114 +\337\123\321\257\122\274\104\237\253\057\153\203\162\357\165\200 +\332\006\063\033\135\310\332\143\306\115\315\254\146\061\315\321 +\336\076\207\020\066\341\271\244\172\357\140\120\262\313\312\246 +\126\340\067\257\253\064\023\071\045\350\071\146\344\230\172\252 +\022\230\234\131\146\206\076\255\361\260\312\076\006\017\173\360 +\021\113\067\240\104\155\173\313\250\214\161\364\325\265\221\066 +\314\360\025\306\053\336\121\027\261\227\114\120\075\261\225\131 +\174\005\175\055\041\325\000\277\001\147\242\136\173\246\134\362 +\367\042\361\220\015\223\333\252\104\121\146\314\175\166\003\353 +\152\250\052\070\031\227\166\015\153\212\141\371\274\366\356\166 +\375\160\053\335\051\074\370\012\036\133\102\034\213\126\057\125 +\033\034\241\056\265\307\026\346\370\252\074\222\216\151\266\001 +\301\265\206\235\211\017\013\070\224\124\350\352\334\236\075\045 +\274\123\046\355\325\253\071\252\305\100\114\124\253\262\264\331 +\331\370\327\162\333\034\274\155\275\145\137\357\210\065\052\146 +\057\356\366\263\145\360\063\215\174\230\101\151\106\017\103\034 +\151\372\233\265\320\141\152\315\312\113\331\114\220\106\253\025 +\131\241\107\124\051\056\203\050\137\034\302\242\253\162\027\000 +\006\216\105\354\213\342\063\075\177\332\031\104\344\142\162\303 +\337\042\306\362\126\324\335\137\225\162\355\155\137\367\110\003 +\133\375\305\052\240\366\163\043\204\020\033\001\347\002\003\001 +\000\001\243\102\060\100\060\016\006\003\125\035\017\001\001\377 +\004\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377 +\004\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026 +\004\024\343\161\340\236\330\247\102\331\333\161\221\153\224\223 +\353\303\243\321\024\243\060\015\006\011\052\206\110\206\367\015 +\001\001\013\005\000\003\202\002\001\000\107\372\335\012\260\021 +\221\070\255\115\135\367\345\016\227\124\031\202\110\207\124\214 +\252\144\231\330\132\376\210\001\305\130\245\231\261\043\124\043 +\267\152\035\040\127\345\001\142\101\027\323\011\333\165\313\156 +\124\220\165\376\032\237\201\012\302\335\327\367\011\320\133\162 +\025\344\036\011\152\075\063\363\041\232\346\025\176\255\121\325 +\015\020\355\175\102\300\217\356\300\232\010\325\101\326\134\016 +\041\151\156\200\141\016\025\300\270\317\305\111\022\122\314\276 +\072\314\324\056\070\005\336\065\375\037\157\270\200\150\230\075 +\115\240\312\100\145\322\163\174\365\213\331\012\225\077\330\077 +\043\155\032\321\052\044\031\331\205\263\027\357\170\156\251\130 +\321\043\323\307\023\355\162\045\177\135\261\163\160\320\177\006 +\227\011\204\051\200\141\035\372\136\377\163\254\240\343\211\270 +\034\161\025\306\336\061\177\022\334\341\155\233\257\347\350\237 +\165\170\114\253\106\073\232\316\277\005\030\135\115\025\074\026 +\232\031\120\004\232\262\232\157\145\213\122\137\074\130\004\050 +\045\300\146\141\061\176\271\340\165\271\032\250\201\326\162\027 +\263\305\003\061\065\021\170\170\242\340\351\060\214\177\200\337 +\130\337\074\272\047\226\342\200\064\155\343\230\323\144\047\254 +\110\176\050\167\134\306\045\141\045\370\205\014\145\372\304\062 +\057\245\230\005\344\370\013\147\026\026\306\202\270\062\031\371 +\371\271\171\334\037\315\353\257\253\016\335\033\333\105\344\172 +\347\002\342\225\135\374\151\360\123\151\141\225\165\171\013\136 +\125\346\070\034\224\251\131\063\236\310\161\164\171\177\121\211 +\266\310\152\270\060\310\152\070\303\156\236\341\067\026\352\005 +\142\114\133\022\107\355\247\264\263\130\126\307\111\363\177\022 +\150\011\061\161\360\155\370\116\107\373\326\205\356\305\130\100 +\031\244\035\247\371\113\103\067\334\150\132\117\317\353\302\144 +\164\336\264\025\331\364\124\124\032\057\034\327\227\161\124\220 +\216\331\040\235\123\053\177\253\217\342\352\060\274\120\067\357 +\361\107\265\175\174\054\004\354\150\235\264\111\104\020\364\162 +\113\034\144\347\374\346\153\220\335\151\175\151\375\000\126\245 +\267\254\266\255\267\312\076\001\357\234 +END + +# Trust for "IdenTrust Public Sector Root CA 1" +# Issuer: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US +# Serial Number:0a:01:42:80:00:00:01:45:23:cf:46:7c:00:00:00:02 +# Subject: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US +# Not Valid Before: Thu Jan 16 17:53:32 2014 +# Not Valid After : Mon Jan 16 17:53:32 2034 +# Fingerprint (SHA-256): 30:D0:89:5A:9A:44:8A:26:20:91:63:55:22:D1:F5:20:10:B5:86:7A:CA:E1:2C:78:EF:95:8F:D4:F4:38:9F:2F +# Fingerprint (SHA1): BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "IdenTrust Public Sector Root CA 1" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\272\051\101\140\167\230\077\364\363\357\362\061\005\073\056\352 +\155\115\105\375 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\067\006\245\260\374\211\235\272\364\153\214\032\144\315\325\272 +END +CKA_ISSUER MULTILINE_OCTAL +\060\115\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 +\165\163\164\061\052\060\050\006\003\125\004\003\023\041\111\144 +\145\156\124\162\165\163\164\040\120\165\142\154\151\143\040\123 +\145\143\164\157\162\040\122\157\157\164\040\103\101\040\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\012\001\102\200\000\000\001\105\043\317\106\174\000\000 +\000\002 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "S-TRUST Universal Root CA" +# +# Issuer: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE +# Serial Number:60:56:c5:4b:23:40:5b:64:d4:ed:25:da:d9:d6:1e:1e +# Subject: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE +# Not Valid Before: Tue Oct 22 00:00:00 2013 +# Not Valid After : Thu Oct 21 23:59:59 2038 +# Fingerprint (SHA-256): D8:0F:EF:91:0A:E3:F1:04:72:3B:04:5C:EC:2D:01:9F:44:1C:E6:21:3A:DF:15:67:91:E7:0C:17:90:11:0A:31 +# Fingerprint (SHA1): 1B:3D:11:14:EA:7A:0F:95:58:54:41:95:BF:6B:25:82:AB:40:CE:9A +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "S-TRUST Universal Root CA" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\205\061\013\060\011\006\003\125\004\006\023\002\104\105 +\061\051\060\047\006\003\125\004\012\023\040\104\145\165\164\163 +\143\150\145\162\040\123\160\141\162\153\141\163\163\145\156\040 +\126\145\162\154\141\147\040\107\155\142\110\061\047\060\045\006 +\003\125\004\013\023\036\123\055\124\122\125\123\124\040\103\145 +\162\164\151\146\151\143\141\164\151\157\156\040\123\145\162\166 +\151\143\145\163\061\042\060\040\006\003\125\004\003\023\031\123 +\055\124\122\125\123\124\040\125\156\151\166\145\162\163\141\154 +\040\122\157\157\164\040\103\101 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\205\061\013\060\011\006\003\125\004\006\023\002\104\105 +\061\051\060\047\006\003\125\004\012\023\040\104\145\165\164\163 +\143\150\145\162\040\123\160\141\162\153\141\163\163\145\156\040 +\126\145\162\154\141\147\040\107\155\142\110\061\047\060\045\006 +\003\125\004\013\023\036\123\055\124\122\125\123\124\040\103\145 +\162\164\151\146\151\143\141\164\151\157\156\040\123\145\162\166 +\151\143\145\163\061\042\060\040\006\003\125\004\003\023\031\123 +\055\124\122\125\123\124\040\125\156\151\166\145\162\163\141\154 +\040\122\157\157\164\040\103\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\140\126\305\113\043\100\133\144\324\355\045\332\331\326 +\036\036 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\003\330\060\202\002\300\240\003\002\001\002\002\020\140 +\126\305\113\043\100\133\144\324\355\045\332\331\326\036\036\060 +\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\201 +\205\061\013\060\011\006\003\125\004\006\023\002\104\105\061\051 +\060\047\006\003\125\004\012\023\040\104\145\165\164\163\143\150 +\145\162\040\123\160\141\162\153\141\163\163\145\156\040\126\145 +\162\154\141\147\040\107\155\142\110\061\047\060\045\006\003\125 +\004\013\023\036\123\055\124\122\125\123\124\040\103\145\162\164 +\151\146\151\143\141\164\151\157\156\040\123\145\162\166\151\143 +\145\163\061\042\060\040\006\003\125\004\003\023\031\123\055\124 +\122\125\123\124\040\125\156\151\166\145\162\163\141\154\040\122 +\157\157\164\040\103\101\060\036\027\015\061\063\061\060\062\062 +\060\060\060\060\060\060\132\027\015\063\070\061\060\062\061\062 +\063\065\071\065\071\132\060\201\205\061\013\060\011\006\003\125 +\004\006\023\002\104\105\061\051\060\047\006\003\125\004\012\023 +\040\104\145\165\164\163\143\150\145\162\040\123\160\141\162\153 +\141\163\163\145\156\040\126\145\162\154\141\147\040\107\155\142 +\110\061\047\060\045\006\003\125\004\013\023\036\123\055\124\122 +\125\123\124\040\103\145\162\164\151\146\151\143\141\164\151\157 +\156\040\123\145\162\166\151\143\145\163\061\042\060\040\006\003 +\125\004\003\023\031\123\055\124\122\125\123\124\040\125\156\151 +\166\145\162\163\141\154\040\122\157\157\164\040\103\101\060\202 +\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005 +\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000\250 +\343\013\337\021\067\205\202\232\265\154\146\174\141\077\300\107 +\032\035\106\343\260\125\144\345\270\202\071\050\007\176\027\377 +\364\233\212\360\221\201\352\070\077\041\170\154\110\354\153\057 +\242\323\212\162\262\247\327\331\352\177\264\300\111\153\060\045 +\211\214\353\267\325\100\141\230\342\334\074\040\222\315\145\112 +\162\237\032\216\214\372\045\025\277\363\041\203\050\015\213\257 +\131\021\202\103\134\233\115\045\121\177\130\030\143\140\073\263 +\265\212\213\130\143\067\110\110\220\104\302\100\335\135\367\103 +\151\051\230\134\022\145\136\253\220\222\113\146\337\325\165\022 +\123\124\030\246\336\212\326\273\127\003\071\131\231\030\005\014 +\371\375\025\306\220\144\106\027\202\327\302\112\101\075\375\000 +\276\127\162\030\224\167\033\123\132\211\001\366\063\162\016\223 +\072\334\350\036\375\005\005\326\274\163\340\210\334\253\117\354 +\265\030\206\117\171\204\016\110\052\146\052\335\062\310\170\145 +\310\013\235\130\001\005\161\355\201\365\150\027\156\313\015\264 +\113\330\241\354\256\070\353\034\130\057\241\145\003\064\057\002 +\003\001\000\001\243\102\060\100\060\017\006\003\125\035\023\001 +\001\377\004\005\060\003\001\001\377\060\016\006\003\125\035\017 +\001\001\377\004\004\003\002\001\006\060\035\006\003\125\035\016 +\004\026\004\024\232\175\327\353\353\177\124\230\105\051\264\040 +\253\155\013\226\043\031\244\302\060\015\006\011\052\206\110\206 +\367\015\001\001\013\005\000\003\202\001\001\000\116\226\022\333 +\176\167\136\222\047\236\041\027\030\202\166\330\077\274\245\011 +\004\146\210\211\255\333\125\263\063\152\306\145\304\217\115\363 +\062\066\334\171\004\226\251\167\062\321\227\365\030\153\214\272 +\355\316\021\320\104\307\222\361\264\104\216\355\210\122\110\236 +\325\375\131\370\243\036\121\373\001\122\345\137\345\172\335\252 +\044\117\042\213\335\166\106\366\245\240\017\065\330\312\017\230 +\271\060\135\040\157\302\201\036\275\275\300\376\025\323\070\052 +\011\223\230\047\033\223\173\320\053\064\136\150\245\025\117\321 +\122\303\240\312\240\203\105\035\365\365\267\131\163\135\131\001 +\217\252\302\107\057\024\161\325\051\343\020\265\107\223\045\314 +\043\051\332\267\162\330\221\324\354\033\110\212\042\344\301\052 +\367\072\150\223\237\105\031\156\103\267\314\376\270\221\232\141 +\032\066\151\143\144\222\050\363\157\141\222\205\023\237\311\007 +\054\213\127\334\353\236\171\325\302\336\010\325\124\262\127\116 +\052\062\215\241\342\072\321\020\040\042\071\175\064\105\157\161 +\073\303\035\374\377\262\117\250\342\366\060\036 +END + +# Trust for "S-TRUST Universal Root CA" +# Issuer: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE +# Serial Number:60:56:c5:4b:23:40:5b:64:d4:ed:25:da:d9:d6:1e:1e +# Subject: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE +# Not Valid Before: Tue Oct 22 00:00:00 2013 +# Not Valid After : Thu Oct 21 23:59:59 2038 +# Fingerprint (SHA-256): D8:0F:EF:91:0A:E3:F1:04:72:3B:04:5C:EC:2D:01:9F:44:1C:E6:21:3A:DF:15:67:91:E7:0C:17:90:11:0A:31 +# Fingerprint (SHA1): 1B:3D:11:14:EA:7A:0F:95:58:54:41:95:BF:6B:25:82:AB:40:CE:9A +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "S-TRUST Universal Root CA" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\033\075\021\024\352\172\017\225\130\124\101\225\277\153\045\202 +\253\100\316\232 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\130\366\101\001\256\365\133\121\231\116\134\041\350\117\324\146 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\205\061\013\060\011\006\003\125\004\006\023\002\104\105 +\061\051\060\047\006\003\125\004\012\023\040\104\145\165\164\163 +\143\150\145\162\040\123\160\141\162\153\141\163\163\145\156\040 +\126\145\162\154\141\147\040\107\155\142\110\061\047\060\045\006 +\003\125\004\013\023\036\123\055\124\122\125\123\124\040\103\145 +\162\164\151\146\151\143\141\164\151\157\156\040\123\145\162\166 +\151\143\145\163\061\042\060\040\006\003\125\004\003\023\031\123 +\055\124\122\125\123\124\040\125\156\151\166\145\162\163\141\154 +\040\122\157\157\164\040\103\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\140\126\305\113\043\100\133\144\324\355\045\332\331\326 +\036\036 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "Entrust Root Certification Authority - G2" +# +# Issuer: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US +# Serial Number: 1246989352 (0x4a538c28) +# Subject: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US +# Not Valid Before: Tue Jul 07 17:25:54 2009 +# Not Valid After : Sat Dec 07 17:55:54 2030 +# Fingerprint (SHA-256): 43:DF:57:74:B0:3E:7F:EF:5F:E4:0D:93:1A:7B:ED:F1:BB:2E:6B:42:73:8C:4E:6D:38:41:10:3D:3A:A7:F3:39 +# Fingerprint (SHA1): 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Entrust Root Certification Authority - G2" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 +\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 +\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 +\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 +\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 +\040\062\060\060\071\040\105\156\164\162\165\163\164\054\040\111 +\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 +\151\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060 +\060\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040 +\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 +\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107 +\062 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 +\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 +\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 +\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 +\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 +\040\062\060\060\071\040\105\156\164\162\165\163\164\054\040\111 +\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 +\151\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060 +\060\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040 +\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 +\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107 +\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\004\112\123\214\050 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\004\076\060\202\003\046\240\003\002\001\002\002\004\112 +\123\214\050\060\015\006\011\052\206\110\206\367\015\001\001\013 +\005\000\060\201\276\061\013\060\011\006\003\125\004\006\023\002 +\125\123\061\026\060\024\006\003\125\004\012\023\015\105\156\164 +\162\165\163\164\054\040\111\156\143\056\061\050\060\046\006\003 +\125\004\013\023\037\123\145\145\040\167\167\167\056\145\156\164 +\162\165\163\164\056\156\145\164\057\154\145\147\141\154\055\164 +\145\162\155\163\061\071\060\067\006\003\125\004\013\023\060\050 +\143\051\040\062\060\060\071\040\105\156\164\162\165\163\164\054 +\040\111\156\143\056\040\055\040\146\157\162\040\141\165\164\150 +\157\162\151\172\145\144\040\165\163\145\040\157\156\154\171\061 +\062\060\060\006\003\125\004\003\023\051\105\156\164\162\165\163 +\164\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141 +\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040\055 +\040\107\062\060\036\027\015\060\071\060\067\060\067\061\067\062 +\065\065\064\132\027\015\063\060\061\062\060\067\061\067\065\065 +\065\064\132\060\201\276\061\013\060\011\006\003\125\004\006\023 +\002\125\123\061\026\060\024\006\003\125\004\012\023\015\105\156 +\164\162\165\163\164\054\040\111\156\143\056\061\050\060\046\006 +\003\125\004\013\023\037\123\145\145\040\167\167\167\056\145\156 +\164\162\165\163\164\056\156\145\164\057\154\145\147\141\154\055 +\164\145\162\155\163\061\071\060\067\006\003\125\004\013\023\060 +\050\143\051\040\062\060\060\071\040\105\156\164\162\165\163\164 +\054\040\111\156\143\056\040\055\040\146\157\162\040\141\165\164 +\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154\171 +\061\062\060\060\006\003\125\004\003\023\051\105\156\164\162\165 +\163\164\040\122\157\157\164\040\103\145\162\164\151\146\151\143 +\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040 +\055\040\107\062\060\202\001\042\060\015\006\011\052\206\110\206 +\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012 +\002\202\001\001\000\272\204\266\162\333\236\014\153\342\231\351 +\060\001\247\166\352\062\270\225\101\032\311\332\141\116\130\162 +\317\376\366\202\171\277\163\141\006\012\245\047\330\263\137\323 +\105\116\034\162\326\116\062\362\162\212\017\367\203\031\320\152 +\200\200\000\105\036\260\307\347\232\277\022\127\047\034\243\150 +\057\012\207\275\152\153\016\136\145\363\034\167\325\324\205\215 +\160\041\264\263\062\347\213\242\325\206\071\002\261\270\322\107 +\316\344\311\111\304\073\247\336\373\124\175\127\276\360\350\156 +\302\171\262\072\013\125\342\120\230\026\062\023\134\057\170\126 +\301\302\224\263\362\132\344\047\232\237\044\327\306\354\320\233 +\045\202\343\314\302\304\105\305\214\227\172\006\153\052\021\237 +\251\012\156\110\073\157\333\324\021\031\102\367\217\007\277\365 +\123\137\234\076\364\027\054\346\151\254\116\062\114\142\167\352 +\267\350\345\273\064\274\031\213\256\234\121\347\267\176\265\123 +\261\063\042\345\155\317\160\074\032\372\342\233\147\266\203\364 +\215\245\257\142\114\115\340\130\254\144\064\022\003\370\266\215 +\224\143\044\244\161\002\003\001\000\001\243\102\060\100\060\016 +\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060\017 +\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060 +\035\006\003\125\035\016\004\026\004\024\152\162\046\172\320\036 +\357\175\347\073\151\121\324\154\215\237\220\022\146\253\060\015 +\006\011\052\206\110\206\367\015\001\001\013\005\000\003\202\001 +\001\000\171\237\035\226\306\266\171\077\042\215\207\323\207\003 +\004\140\152\153\232\056\131\211\163\021\254\103\321\365\023\377 +\215\071\053\300\362\275\117\160\214\251\057\352\027\304\013\124 +\236\324\033\226\230\063\074\250\255\142\242\000\166\253\131\151 +\156\006\035\176\304\271\104\215\230\257\022\324\141\333\012\031 +\106\107\363\353\367\143\301\100\005\100\245\322\267\364\265\232 +\066\277\251\210\166\210\004\125\004\053\234\207\177\032\067\074 +\176\055\245\032\330\324\211\136\312\275\254\075\154\330\155\257 +\325\363\166\017\315\073\210\070\042\235\154\223\232\304\075\277 +\202\033\145\077\246\017\135\252\374\345\262\025\312\265\255\306 +\274\075\320\204\350\352\006\162\260\115\071\062\170\277\076\021 +\234\013\244\235\232\041\363\360\233\013\060\170\333\301\334\207 +\103\376\274\143\232\312\305\302\034\311\307\215\377\073\022\130 +\010\346\266\075\354\172\054\116\373\203\226\316\014\074\151\207 +\124\163\244\163\302\223\377\121\020\254\025\124\001\330\374\005 +\261\211\241\177\164\203\232\111\327\334\116\173\212\110\157\213 +\105\366 +END + +# Trust for "Entrust Root Certification Authority - G2" +# Issuer: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US +# Serial Number: 1246989352 (0x4a538c28) +# Subject: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US +# Not Valid Before: Tue Jul 07 17:25:54 2009 +# Not Valid After : Sat Dec 07 17:55:54 2030 +# Fingerprint (SHA-256): 43:DF:57:74:B0:3E:7F:EF:5F:E4:0D:93:1A:7B:ED:F1:BB:2E:6B:42:73:8C:4E:6D:38:41:10:3D:3A:A7:F3:39 +# Fingerprint (SHA1): 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Entrust Root Certification Authority - G2" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\214\364\047\375\171\014\072\321\146\006\215\350\036\127\357\273 +\223\042\162\324 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\113\342\311\221\226\145\014\364\016\132\223\222\240\012\376\262 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 +\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 +\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 +\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 +\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 +\040\062\060\060\071\040\105\156\164\162\165\163\164\054\040\111 +\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 +\151\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060 +\060\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040 +\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 +\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107 +\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\004\112\123\214\050 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "Entrust Root Certification Authority - EC1" +# +# Issuer: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US +# Serial Number:00:a6:8b:79:29:00:00:00:00:50:d0:91:f9 +# Subject: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US +# Not Valid Before: Tue Dec 18 15:25:36 2012 +# Not Valid After : Fri Dec 18 15:55:36 2037 +# Fingerprint (SHA-256): 02:ED:0E:B2:8C:14:DA:45:16:5C:56:67:91:70:0D:64:51:D7:FB:56:F0:B2:AB:1D:3B:8E:B0:70:E5:6E:DF:F5 +# Fingerprint (SHA1): 20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47 +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Entrust Root Certification Authority - EC1" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\277\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 +\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 +\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 +\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 +\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 +\040\062\060\061\062\040\105\156\164\162\165\163\164\054\040\111 +\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 +\151\172\145\144\040\165\163\145\040\157\156\154\171\061\063\060 +\061\006\003\125\004\003\023\052\105\156\164\162\165\163\164\040 +\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 +\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\105 +\103\061 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\277\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 +\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 +\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 +\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 +\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 +\040\062\060\061\062\040\105\156\164\162\165\163\164\054\040\111 +\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 +\151\172\145\144\040\165\163\145\040\157\156\154\171\061\063\060 +\061\006\003\125\004\003\023\052\105\156\164\162\165\163\164\040 +\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 +\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\105 +\103\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\015\000\246\213\171\051\000\000\000\000\120\320\221\371 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\002\371\060\202\002\200\240\003\002\001\002\002\015\000 +\246\213\171\051\000\000\000\000\120\320\221\371\060\012\006\010 +\052\206\110\316\075\004\003\003\060\201\277\061\013\060\011\006 +\003\125\004\006\023\002\125\123\061\026\060\024\006\003\125\004 +\012\023\015\105\156\164\162\165\163\164\054\040\111\156\143\056 +\061\050\060\046\006\003\125\004\013\023\037\123\145\145\040\167 +\167\167\056\145\156\164\162\165\163\164\056\156\145\164\057\154 +\145\147\141\154\055\164\145\162\155\163\061\071\060\067\006\003 +\125\004\013\023\060\050\143\051\040\062\060\061\062\040\105\156 +\164\162\165\163\164\054\040\111\156\143\056\040\055\040\146\157 +\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163\145 +\040\157\156\154\171\061\063\060\061\006\003\125\004\003\023\052 +\105\156\164\162\165\163\164\040\122\157\157\164\040\103\145\162 +\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157 +\162\151\164\171\040\055\040\105\103\061\060\036\027\015\061\062 +\061\062\061\070\061\065\062\065\063\066\132\027\015\063\067\061 +\062\061\070\061\065\065\065\063\066\132\060\201\277\061\013\060 +\011\006\003\125\004\006\023\002\125\123\061\026\060\024\006\003 +\125\004\012\023\015\105\156\164\162\165\163\164\054\040\111\156 +\143\056\061\050\060\046\006\003\125\004\013\023\037\123\145\145 +\040\167\167\167\056\145\156\164\162\165\163\164\056\156\145\164 +\057\154\145\147\141\154\055\164\145\162\155\163\061\071\060\067 +\006\003\125\004\013\023\060\050\143\051\040\062\060\061\062\040 +\105\156\164\162\165\163\164\054\040\111\156\143\056\040\055\040 +\146\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165 +\163\145\040\157\156\154\171\061\063\060\061\006\003\125\004\003 +\023\052\105\156\164\162\165\163\164\040\122\157\157\164\040\103 +\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164 +\150\157\162\151\164\171\040\055\040\105\103\061\060\166\060\020 +\006\007\052\206\110\316\075\002\001\006\005\053\201\004\000\042 +\003\142\000\004\204\023\311\320\272\155\101\173\342\154\320\353 +\125\137\146\002\032\044\364\133\211\151\107\343\270\302\175\361 +\362\002\305\237\240\366\133\325\213\006\031\206\117\123\020\155 +\007\044\047\241\240\370\325\107\031\141\114\175\312\223\047\352 +\164\014\357\157\226\011\376\143\354\160\135\066\255\147\167\256 +\311\235\174\125\104\072\242\143\121\037\365\343\142\324\251\107 +\007\076\314\040\243\102\060\100\060\016\006\003\125\035\017\001 +\001\377\004\004\003\002\001\006\060\017\006\003\125\035\023\001 +\001\377\004\005\060\003\001\001\377\060\035\006\003\125\035\016 +\004\026\004\024\267\143\347\032\335\215\351\010\246\125\203\244 +\340\152\120\101\145\021\102\111\060\012\006\010\052\206\110\316 +\075\004\003\003\003\147\000\060\144\002\060\141\171\330\345\102 +\107\337\034\256\123\231\027\266\157\034\175\341\277\021\224\321 +\003\210\165\344\215\211\244\212\167\106\336\155\141\357\002\365 +\373\265\337\314\376\116\377\376\251\346\247\002\060\133\231\327 +\205\067\006\265\173\010\375\353\047\213\112\224\371\341\372\247 +\216\046\010\350\174\222\150\155\163\330\157\046\254\041\002\270 +\231\267\046\101\133\045\140\256\320\110\032\356\006 +END + +# Trust for "Entrust Root Certification Authority - EC1" +# Issuer: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US +# Serial Number:00:a6:8b:79:29:00:00:00:00:50:d0:91:f9 +# Subject: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US +# Not Valid Before: Tue Dec 18 15:25:36 2012 +# Not Valid After : Fri Dec 18 15:55:36 2037 +# Fingerprint (SHA-256): 02:ED:0E:B2:8C:14:DA:45:16:5C:56:67:91:70:0D:64:51:D7:FB:56:F0:B2:AB:1D:3B:8E:B0:70:E5:6E:DF:F5 +# Fingerprint (SHA1): 20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47 +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Entrust Root Certification Authority - EC1" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\040\330\006\100\337\233\045\365\022\045\072\021\352\367\131\212 +\353\024\265\107 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\266\176\035\360\130\305\111\154\044\073\075\355\230\030\355\274 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\277\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 +\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 +\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 +\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 +\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 +\040\062\060\061\062\040\105\156\164\162\165\163\164\054\040\111 +\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 +\151\172\145\144\040\165\163\145\040\157\156\154\171\061\063\060 +\061\006\003\125\004\003\023\052\105\156\164\162\165\163\164\040 +\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 +\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\105 +\103\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\015\000\246\213\171\051\000\000\000\000\120\320\221\371 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "CFCA EV ROOT" +# +# Issuer: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN +# Serial Number: 407555286 (0x184accd6) +# Subject: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN +# Not Valid Before: Wed Aug 08 03:07:01 2012 +# Not Valid After : Mon Dec 31 03:07:01 2029 +# Fingerprint (SHA-256): 5C:C3:D7:8E:4E:1D:5E:45:54:7A:04:E6:87:3E:64:F9:0C:F9:53:6D:1C:CC:2E:F8:00:F3:55:C4:C5:FD:70:FD +# Fingerprint (SHA1): E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83 +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "CFCA EV ROOT" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\126\061\013\060\011\006\003\125\004\006\023\002\103\116\061 +\060\060\056\006\003\125\004\012\014\047\103\150\151\156\141\040 +\106\151\156\141\156\143\151\141\154\040\103\145\162\164\151\146 +\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 +\171\061\025\060\023\006\003\125\004\003\014\014\103\106\103\101 +\040\105\126\040\122\117\117\124 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\126\061\013\060\011\006\003\125\004\006\023\002\103\116\061 +\060\060\056\006\003\125\004\012\014\047\103\150\151\156\141\040 +\106\151\156\141\156\143\151\141\154\040\103\145\162\164\151\146 +\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 +\171\061\025\060\023\006\003\125\004\003\014\014\103\106\103\101 +\040\105\126\040\122\117\117\124 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\004\030\112\314\326 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\215\060\202\003\165\240\003\002\001\002\002\004\030 +\112\314\326\060\015\006\011\052\206\110\206\367\015\001\001\013 +\005\000\060\126\061\013\060\011\006\003\125\004\006\023\002\103 +\116\061\060\060\056\006\003\125\004\012\014\047\103\150\151\156 +\141\040\106\151\156\141\156\143\151\141\154\040\103\145\162\164 +\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162 +\151\164\171\061\025\060\023\006\003\125\004\003\014\014\103\106 +\103\101\040\105\126\040\122\117\117\124\060\036\027\015\061\062 +\060\070\060\070\060\063\060\067\060\061\132\027\015\062\071\061 +\062\063\061\060\063\060\067\060\061\132\060\126\061\013\060\011 +\006\003\125\004\006\023\002\103\116\061\060\060\056\006\003\125 +\004\012\014\047\103\150\151\156\141\040\106\151\156\141\156\143 +\151\141\154\040\103\145\162\164\151\146\151\143\141\164\151\157 +\156\040\101\165\164\150\157\162\151\164\171\061\025\060\023\006 +\003\125\004\003\014\014\103\106\103\101\040\105\126\040\122\117 +\117\124\060\202\002\042\060\015\006\011\052\206\110\206\367\015 +\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202 +\002\001\000\327\135\153\315\020\077\037\005\131\325\005\115\067 +\261\016\354\230\053\216\025\035\372\223\113\027\202\041\161\020 +\122\327\121\144\160\026\302\125\151\115\216\025\155\237\277\014 +\033\302\340\243\147\326\014\254\317\042\256\257\167\124\052\113 +\114\212\123\122\172\303\356\056\336\263\161\045\301\351\135\075 +\356\241\057\243\367\052\074\311\043\035\152\253\035\241\247\361 +\363\354\240\325\104\317\025\317\162\057\035\143\227\350\231\371 +\375\223\244\124\200\114\122\324\122\253\056\111\337\220\315\270 +\137\276\077\336\241\312\115\040\324\045\350\204\051\123\267\261 +\210\037\377\372\332\220\237\012\251\055\101\077\261\361\030\051 +\356\026\131\054\064\111\032\250\006\327\250\210\322\003\162\172 +\062\342\352\150\115\156\054\226\145\173\312\131\372\362\342\335 +\356\060\054\373\314\106\254\304\143\353\157\177\066\053\064\163 +\022\224\177\337\314\046\236\361\162\135\120\145\131\217\151\263 +\207\136\062\157\303\030\212\265\225\217\260\172\067\336\132\105 +\073\307\066\341\357\147\321\071\323\227\133\163\142\031\110\055 +\207\034\006\373\164\230\040\111\163\360\005\322\033\261\240\243 +\267\033\160\323\210\151\271\132\326\070\364\142\334\045\213\170 +\277\370\350\176\270\134\311\225\117\137\247\055\271\040\153\317 +\153\335\365\015\364\202\267\364\262\146\056\020\050\366\227\132 +\173\226\026\217\001\031\055\154\156\177\071\130\006\144\203\001 +\203\203\303\115\222\335\062\306\207\244\067\351\026\316\252\055 +\150\257\012\201\145\072\160\301\233\255\115\155\124\312\052\055 +\113\205\033\263\200\346\160\105\015\153\136\065\360\177\073\270 +\234\344\004\160\211\022\045\223\332\012\231\042\140\152\143\140 +\116\166\006\230\116\275\203\255\035\130\212\045\205\322\307\145 +\036\055\216\306\337\266\306\341\177\212\004\041\025\051\164\360 +\076\234\220\235\014\056\361\212\076\132\252\014\011\036\307\325 +\074\243\355\227\303\036\064\372\070\371\010\016\343\300\135\053 +\203\321\126\152\311\266\250\124\123\056\170\062\147\075\202\177 +\164\320\373\341\266\005\140\271\160\333\216\013\371\023\130\157 +\161\140\020\122\020\271\301\101\011\357\162\037\147\061\170\377 +\226\005\215\002\003\001\000\001\243\143\060\141\060\037\006\003 +\125\035\043\004\030\060\026\200\024\343\376\055\375\050\320\013 +\265\272\266\242\304\277\006\252\005\214\223\373\057\060\017\006 +\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060\016 +\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060\035 +\006\003\125\035\016\004\026\004\024\343\376\055\375\050\320\013 +\265\272\266\242\304\277\006\252\005\214\223\373\057\060\015\006 +\011\052\206\110\206\367\015\001\001\013\005\000\003\202\002\001 +\000\045\306\272\153\353\207\313\336\202\071\226\075\360\104\247 +\153\204\163\003\336\235\053\117\272\040\177\274\170\262\317\227 +\260\033\234\363\327\171\056\365\110\266\322\373\027\210\346\323 +\172\077\355\123\023\320\342\057\152\171\313\000\043\050\346\036 +\067\127\065\211\204\302\166\117\064\066\255\147\303\316\101\006 +\210\305\367\356\330\032\270\326\013\177\120\377\223\252\027\113 +\214\354\355\122\140\262\244\006\352\116\353\364\153\031\375\353 +\365\032\340\045\052\232\334\307\101\066\367\310\164\005\204\071 +\225\071\326\013\073\244\047\372\010\330\134\036\370\004\140\122 +\021\050\050\003\377\357\123\146\000\245\112\064\026\146\174\375 +\011\244\256\236\147\032\157\101\013\153\006\023\233\217\206\161 +\005\264\057\215\211\146\063\051\166\124\232\021\370\047\372\262 +\077\221\340\316\015\033\363\060\032\255\277\042\135\033\323\277 +\045\005\115\341\222\032\177\231\237\074\104\223\312\324\100\111 +\154\200\207\327\004\072\303\062\122\065\016\126\370\245\335\175 +\304\213\015\021\037\123\313\036\262\027\266\150\167\132\340\324 +\313\310\007\256\365\072\056\216\067\267\320\001\113\103\051\167 +\214\071\227\217\202\132\370\121\345\211\240\030\347\150\177\135 +\012\056\373\243\107\016\075\246\043\172\306\001\307\217\310\136 +\277\155\200\126\276\212\044\272\063\352\237\341\062\021\236\361 +\322\117\200\366\033\100\257\070\236\021\120\171\163\022\022\315 +\346\154\235\054\210\162\074\060\201\006\221\042\352\131\255\332 +\031\056\042\302\215\271\214\207\340\146\274\163\043\137\041\144 +\143\200\110\365\240\074\030\075\224\310\110\101\035\100\272\136 +\376\376\126\071\241\310\317\136\236\031\144\106\020\332\027\221 +\267\005\200\254\213\231\222\175\347\242\330\007\013\066\047\347 +\110\171\140\212\303\327\023\134\370\162\100\337\112\313\317\231 +\000\012\000\013\021\225\332\126\105\003\210\012\237\147\320\325 +\171\261\250\215\100\155\015\302\172\100\372\363\137\144\107\222 +\313\123\271\273\131\316\117\375\320\025\123\001\330\337\353\331 +\346\166\357\320\043\273\073\251\171\263\325\002\051\315\211\243 +\226\017\112\065\347\116\102\300\165\315\007\317\346\054\353\173 +\056 +END + +# Trust for "CFCA EV ROOT" +# Issuer: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN +# Serial Number: 407555286 (0x184accd6) +# Subject: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN +# Not Valid Before: Wed Aug 08 03:07:01 2012 +# Not Valid After : Mon Dec 31 03:07:01 2029 +# Fingerprint (SHA-256): 5C:C3:D7:8E:4E:1D:5E:45:54:7A:04:E6:87:3E:64:F9:0C:F9:53:6D:1C:CC:2E:F8:00:F3:55:C4:C5:FD:70:FD +# Fingerprint (SHA1): E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83 +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "CFCA EV ROOT" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\342\270\051\113\125\204\253\153\130\302\220\106\154\254\077\270 +\071\217\204\203 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\164\341\266\355\046\172\172\104\060\063\224\253\173\047\201\060 +END +CKA_ISSUER MULTILINE_OCTAL +\060\126\061\013\060\011\006\003\125\004\006\023\002\103\116\061 +\060\060\056\006\003\125\004\012\014\047\103\150\151\156\141\040 +\106\151\156\141\156\143\151\141\154\040\103\145\162\164\151\146 +\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 +\171\061\025\060\023\006\003\125\004\003\014\014\103\106\103\101 +\040\105\126\040\122\117\117\124 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\004\030\112\314\326 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE diff --git a/security/nss/lib/ckfw/builtins/nssckbi.h b/security/nss/lib/ckfw/builtins/nssckbi.h index 3dd7c883bea..e0131611cbf 100644 --- a/security/nss/lib/ckfw/builtins/nssckbi.h +++ b/security/nss/lib/ckfw/builtins/nssckbi.h @@ -45,8 +45,8 @@ * of the comment in the CK_VERSION type definition. */ #define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 2 -#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 2 -#define NSS_BUILTINS_LIBRARY_VERSION "2.2" +#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 3 +#define NSS_BUILTINS_LIBRARY_VERSION "2.3" /* These version numbers detail the semantic changes to the ckfw engine. */ #define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1 diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index 794e932e793..abe0604f5d9 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -1065,7 +1065,6 @@ PK11_PrivDecrypt; ;+NSS_3.18 { # NSS 3.18 release ;+ global: __PK11_SetCertificateNickname; -CERT_FindCertURLExtension; SEC_CheckCrlTimes; SEC_GetCrlTimes; ;+ local: diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index 963390c2577..e596f00b797 100644 --- a/security/nss/lib/nss/nss.h +++ b/security/nss/lib/nss/nss.h @@ -37,7 +37,7 @@ #define NSS_VMAJOR 3 #define NSS_VMINOR 18 #define NSS_VPATCH 0 -#define NSS_VBUILD 0 +#define NSS_VBUILD 2 #define NSS_BETA PR_FALSE #ifndef RC_INVOKED diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h index 7cb4dcdee8b..d3de246f8b0 100644 --- a/security/nss/lib/softoken/softkver.h +++ b/security/nss/lib/softoken/softkver.h @@ -29,7 +29,7 @@ #define SOFTOKEN_VMAJOR 3 #define SOFTOKEN_VMINOR 18 #define SOFTOKEN_VPATCH 0 -#define SOFTOKEN_VBUILD 0 +#define SOFTOKEN_VBUILD 2 #define SOFTOKEN_BETA PR_FALSE #endif /* _SOFTKVER_H_ */ diff --git a/security/nss/lib/util/nssutil.h b/security/nss/lib/util/nssutil.h index b9d6384167f..6daa12455e3 100644 --- a/security/nss/lib/util/nssutil.h +++ b/security/nss/lib/util/nssutil.h @@ -23,7 +23,7 @@ #define NSSUTIL_VMAJOR 3 #define NSSUTIL_VMINOR 18 #define NSSUTIL_VPATCH 0 -#define NSSUTIL_VBUILD 0 +#define NSSUTIL_VBUILD 2 #define NSSUTIL_BETA PR_FALSE SEC_BEGIN_PROTOS diff --git a/security/nss/tests/memleak/memleak.sh b/security/nss/tests/memleak/memleak.sh index 6cc4670dadd..54d2530ca6d 100644 --- a/security/nss/tests/memleak/memleak.sh +++ b/security/nss/tests/memleak/memleak.sh @@ -206,7 +206,8 @@ set_test_mode() ${BINDIR}/modutil -dbdir ${CLIENT_DB} -list echo "${SCRIPTNAME}: FIPS is OFF" - cipher_list="A B C D E F :C001 :C002 :C003 :C004 :C005 :C006 :C007 :C008 :C009 :C00A :C010 :C011 :C012 :C013 :C014 c d e f g i j k l m n v y z" + # ciphers l and m removed, see bug 1136095 + cipher_list="A B C D E F :C001 :C002 :C003 :C004 :C005 :C006 :C007 :C008 :C009 :C00A :C010 :C011 :C012 :C013 :C014 c d e f g i j k n v y z" fi } diff --git a/security/patches/reverted-bug-1132496.patch b/security/patches/reverted-bug-1132496.patch deleted file mode 100644 index 4555abe8837..00000000000 --- a/security/patches/reverted-bug-1132496.patch +++ /dev/null @@ -1,1384 +0,0 @@ - -# HG changeset patch -# User Kai Engert -# Date 1424971034 -3600 -# Node ID 484e72583add151908d4e34ff9b2f811df719f54 -# Parent 483fbe78c2b2707a53185e63ab37d72af4883aa5 -Bug 1132496 - February 2015 batch of root CA changes, r=rrelyea - -diff --git a/lib/ckfw/builtins/certdata.txt b/lib/ckfw/builtins/certdata.txt ---- a/lib/ckfw/builtins/certdata.txt -+++ b/lib/ckfw/builtins/certdata.txt -@@ -182,19 +182,19 @@ CKA_ISSUER MULTILINE_OCTAL - \020\060\016\006\003\125\004\012\023\007\105\161\165\151\146\141 - \170\061\055\060\053\006\003\125\004\013\023\044\105\161\165\151 - \146\141\170\040\123\145\143\165\162\145\040\103\145\162\164\151 - \146\151\143\141\164\145\040\101\165\164\150\157\162\151\164\171 - END - CKA_SERIAL_NUMBER MULTILINE_OCTAL - \002\004\065\336\364\317 - END --CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR --CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR --CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST - CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - - # Distrust "Distrust a pb.com certificate that does not comply with the baseline requirements." - # Issuer: OU=Equifax Secure Certificate Authority,O=Equifax,C=US - # Serial Number: 1407252 (0x157914) - # Subject: CN=*.pb.com,OU=Meters,O=Pitney Bowes,L=Danbury,ST=Connecticut,C=US - # Not Valid Before: Mon Feb 01 14:54:04 2010 - # Not Valid After : Tue Sep 30 00:00:00 2014 -@@ -2452,19 +2452,19 @@ CKA_ISSUER MULTILINE_OCTAL - \170\040\123\145\143\165\162\145\040\111\156\143\056\061\055\060 - \053\006\003\125\004\003\023\044\105\161\165\151\146\141\170\040 - \123\145\143\165\162\145\040\107\154\157\142\141\154\040\145\102 - \165\163\151\156\145\163\163\040\103\101\055\061 - END - CKA_SERIAL_NUMBER MULTILINE_OCTAL - \002\001\001 - END --CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR --CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR --CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST - CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - - # - # Certificate "Equifax Secure eBusiness CA 1" - # - # Issuer: CN=Equifax Secure eBusiness CA-1,O=Equifax Secure Inc.,C=US - # Serial Number: 4 (0x4) - # Subject: CN=Equifax Secure eBusiness CA-1,O=Equifax Secure Inc.,C=US -@@ -13169,19 +13169,19 @@ CKA_ISSUER MULTILINE_OCTAL - \103\145\156\164\145\162\040\103\154\141\163\163\040\063\040\103 - \101\061\045\060\043\006\003\125\004\003\023\034\124\103\040\124 - \162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163 - \040\063\040\103\101\040\111\111 - END - CKA_SERIAL_NUMBER MULTILINE_OCTAL - \002\016\112\107\000\001\000\002\345\240\135\326\077\000\121\277 - END --CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR --CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR --CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST - CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - - # - # Certificate "TC TrustCenter Universal CA I" - # - # Issuer: CN=TC TrustCenter Universal CA I,OU=TC TrustCenter Universal CA,O=TC TrustCenter GmbH,C=DE - # Serial Number:1d:a2:00:01:00:02:ec:b7:60:80:78:8d:b6:06 - # Subject: CN=TC TrustCenter Universal CA I,OU=TC TrustCenter Universal CA,O=TC TrustCenter GmbH,C=DE -@@ -30315,8 +30315,1278 @@ END - CKA_SERIAL_NUMBER MULTILINE_OCTAL - \002\020\057\000\156\315\027\160\146\347\137\243\202\012\171\037 - \005\256 - END - CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST - CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST - CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST - CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -+ -+# -+# Certificate "Staat der Nederlanden Root CA - G3" -+# -+# Issuer: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL -+# Serial Number: 10003001 (0x98a239) -+# Subject: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL -+# Not Valid Before: Thu Nov 14 11:28:42 2013 -+# Not Valid After : Mon Nov 13 23:00:00 2028 -+# Fingerprint (SHA-256): 3C:4F:B0:B9:5A:B8:B3:00:32:F4:32:B8:6F:53:5F:E1:72:C1:85:D0:FD:39:86:58:37:CF:36:18:7F:A6:F4:28 -+# Fingerprint (SHA1): D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC -+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "Staat der Nederlanden Root CA - G3" -+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -+CKA_SUBJECT MULTILINE_OCTAL -+\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -+\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 -+\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 -+\053\060\051\006\003\125\004\003\014\042\123\164\141\141\164\040 -+\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 -+\122\157\157\164\040\103\101\040\055\040\107\063 -+END -+CKA_ID UTF8 "0" -+CKA_ISSUER MULTILINE_OCTAL -+\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -+\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 -+\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 -+\053\060\051\006\003\125\004\003\014\042\123\164\141\141\164\040 -+\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 -+\122\157\157\164\040\103\101\040\055\040\107\063 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\004\000\230\242\071 -+END -+CKA_VALUE MULTILINE_OCTAL -+\060\202\005\164\060\202\003\134\240\003\002\001\002\002\004\000 -+\230\242\071\060\015\006\011\052\206\110\206\367\015\001\001\013 -+\005\000\060\132\061\013\060\011\006\003\125\004\006\023\002\116 -+\114\061\036\060\034\006\003\125\004\012\014\025\123\164\141\141 -+\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145 -+\156\061\053\060\051\006\003\125\004\003\014\042\123\164\141\141 -+\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145 -+\156\040\122\157\157\164\040\103\101\040\055\040\107\063\060\036 -+\027\015\061\063\061\061\061\064\061\061\062\070\064\062\132\027 -+\015\062\070\061\061\061\063\062\063\060\060\060\060\132\060\132 -+\061\013\060\011\006\003\125\004\006\023\002\116\114\061\036\060 -+\034\006\003\125\004\012\014\025\123\164\141\141\164\040\144\145 -+\162\040\116\145\144\145\162\154\141\156\144\145\156\061\053\060 -+\051\006\003\125\004\003\014\042\123\164\141\141\164\040\144\145 -+\162\040\116\145\144\145\162\154\141\156\144\145\156\040\122\157 -+\157\164\040\103\101\040\055\040\107\063\060\202\002\042\060\015 -+\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002 -+\017\000\060\202\002\012\002\202\002\001\000\276\062\242\124\017 -+\160\373\054\134\131\353\154\304\244\121\350\205\052\263\314\112 -+\064\362\260\137\363\016\307\034\075\123\036\210\010\150\330\157 -+\075\255\302\236\314\202\147\007\047\207\150\161\072\237\165\226 -+\042\106\005\260\355\255\307\133\236\052\336\234\374\072\306\225 -+\247\365\027\147\030\347\057\111\010\014\134\317\346\314\064\355 -+\170\373\120\261\334\153\062\360\242\376\266\074\344\354\132\227 -+\307\077\036\160\010\060\240\334\305\263\155\157\320\202\162\021 -+\253\322\201\150\131\202\027\267\170\222\140\372\314\336\077\204 -+\353\215\070\063\220\012\162\043\372\065\314\046\161\061\321\162 -+\050\222\331\133\043\155\146\265\155\007\102\353\246\063\316\222 -+\333\300\366\154\143\170\315\312\116\075\265\345\122\233\361\276 -+\073\346\124\140\260\146\036\011\253\007\376\124\211\021\102\321 -+\367\044\272\140\170\032\230\367\311\021\375\026\301\065\032\124 -+\165\357\103\323\345\256\116\316\347\173\303\306\116\141\121\113 -+\253\232\105\113\241\037\101\275\110\123\025\161\144\013\206\263 -+\345\056\276\316\244\033\301\051\204\242\265\313\010\043\166\103 -+\042\044\037\027\004\324\156\234\306\374\177\053\146\032\354\212 -+\345\326\317\115\365\143\011\267\025\071\326\173\254\353\343\174 -+\351\116\374\165\102\310\355\130\225\014\006\102\242\234\367\344 -+\160\263\337\162\157\132\067\100\211\330\205\244\327\361\013\336 -+\103\031\324\112\130\054\214\212\071\236\277\204\207\361\026\073 -+\066\014\351\323\264\312\154\031\101\122\011\241\035\260\152\277 -+\202\357\160\121\041\062\334\005\166\214\313\367\144\344\003\120 -+\257\214\221\147\253\305\362\356\130\330\336\276\367\347\061\317 -+\154\311\073\161\301\325\210\265\145\274\300\350\027\027\007\022 -+\265\134\322\253\040\223\264\346\202\203\160\066\305\315\243\215 -+\255\213\354\243\301\103\207\346\103\342\064\276\225\213\065\355 -+\007\071\332\250\035\172\237\066\236\022\260\014\145\022\220\025 -+\140\331\046\100\104\343\126\140\245\020\324\152\074\375\101\334 -+\016\132\107\266\357\227\141\165\117\331\376\307\262\035\324\355 -+\135\111\263\251\152\313\146\204\023\325\134\240\334\337\156\167 -+\006\321\161\165\310\127\157\257\017\167\133\002\003\001\000\001 -+\243\102\060\100\060\017\006\003\125\035\023\001\001\377\004\005 -+\060\003\001\001\377\060\016\006\003\125\035\017\001\001\377\004 -+\004\003\002\001\006\060\035\006\003\125\035\016\004\026\004\024 -+\124\255\372\307\222\127\256\312\065\234\056\022\373\344\272\135 -+\040\334\224\127\060\015\006\011\052\206\110\206\367\015\001\001 -+\013\005\000\003\202\002\001\000\060\231\235\005\062\310\136\016 -+\073\230\001\072\212\244\347\007\367\172\370\347\232\337\120\103 -+\123\227\052\075\312\074\107\230\056\341\025\173\361\222\363\141 -+\332\220\045\026\145\300\237\124\135\016\003\073\133\167\002\234 -+\204\266\015\230\137\064\335\073\143\302\303\050\201\302\234\051 -+\056\051\342\310\303\001\362\063\352\052\252\314\011\010\367\145 -+\147\306\315\337\323\266\053\247\275\314\321\016\160\137\270\043 -+\321\313\221\116\012\364\310\172\345\331\143\066\301\324\337\374 -+\042\227\367\140\135\352\051\057\130\262\275\130\275\215\226\117 -+\020\165\277\110\173\075\121\207\241\074\164\042\302\374\007\177 -+\200\334\304\254\376\152\301\160\060\260\351\216\151\342\054\151 -+\201\224\011\272\335\376\115\300\203\214\224\130\300\106\040\257 -+\234\037\002\370\065\125\111\057\106\324\300\360\240\226\002\017 -+\063\305\161\363\236\043\175\224\267\375\072\323\011\203\006\041 -+\375\140\075\256\062\300\322\356\215\246\360\347\264\202\174\012 -+\314\160\311\171\200\370\376\114\367\065\204\031\212\061\373\012 -+\331\327\177\233\360\242\232\153\303\005\112\355\101\140\024\060 -+\321\252\021\102\156\323\043\002\004\013\306\145\335\335\122\167 -+\332\201\153\262\250\372\001\070\271\226\352\052\154\147\227\211 -+\224\236\274\341\124\325\344\152\170\357\112\275\053\232\075\100 -+\176\306\300\165\322\156\373\150\060\354\354\213\235\371\111\065 -+\232\032\054\331\263\225\071\325\036\222\367\246\271\145\057\345 -+\075\155\072\110\114\010\334\344\050\022\050\276\175\065\134\352 -+\340\026\176\023\033\152\327\076\327\236\374\055\165\262\301\024 -+\325\043\003\333\133\157\013\076\170\057\015\336\063\215\026\267 -+\110\347\203\232\201\017\173\301\103\115\125\004\027\070\112\121 -+\325\131\242\211\164\323\237\276\036\113\327\306\155\267\210\044 -+\157\140\221\244\202\205\133\126\101\274\320\104\253\152\023\276 -+\321\054\130\267\022\063\130\262\067\143\334\023\365\224\035\077 -+\100\121\365\117\365\072\355\310\305\353\302\036\035\026\225\172 -+\307\176\102\161\223\156\113\025\267\060\337\252\355\127\205\110 -+\254\035\152\335\071\151\344\341\171\170\276\316\005\277\241\014 -+\367\200\173\041\147\047\060\131 -+END -+ -+# Trust for "Staat der Nederlanden Root CA - G3" -+# Issuer: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL -+# Serial Number: 10003001 (0x98a239) -+# Subject: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL -+# Not Valid Before: Thu Nov 14 11:28:42 2013 -+# Not Valid After : Mon Nov 13 23:00:00 2028 -+# Fingerprint (SHA-256): 3C:4F:B0:B9:5A:B8:B3:00:32:F4:32:B8:6F:53:5F:E1:72:C1:85:D0:FD:39:86:58:37:CF:36:18:7F:A6:F4:28 -+# Fingerprint (SHA1): D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC -+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "Staat der Nederlanden Root CA - G3" -+CKA_CERT_SHA1_HASH MULTILINE_OCTAL -+\330\353\153\101\121\222\131\340\363\347\205\000\300\075\266\210 -+\227\311\356\374 -+END -+CKA_CERT_MD5_HASH MULTILINE_OCTAL -+\013\106\147\007\333\020\057\031\214\065\120\140\321\013\364\067 -+END -+CKA_ISSUER MULTILINE_OCTAL -+\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -+\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 -+\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 -+\053\060\051\006\003\125\004\003\014\042\123\164\141\141\164\040 -+\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 -+\122\157\157\164\040\103\101\040\055\040\107\063 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\004\000\230\242\071 -+END -+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -+ -+# -+# Certificate "Staat der Nederlanden EV Root CA" -+# -+# Issuer: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL -+# Serial Number: 10000013 (0x98968d) -+# Subject: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL -+# Not Valid Before: Wed Dec 08 11:19:29 2010 -+# Not Valid After : Thu Dec 08 11:10:28 2022 -+# Fingerprint (SHA-256): 4D:24:91:41:4C:FE:95:67:46:EC:4C:EF:A6:CF:6F:72:E2:8A:13:29:43:2F:9D:8A:90:7A:C4:CB:5D:AD:C1:5A -+# Fingerprint (SHA1): 76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB -+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "Staat der Nederlanden EV Root CA" -+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -+CKA_SUBJECT MULTILINE_OCTAL -+\060\130\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -+\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 -+\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 -+\051\060\047\006\003\125\004\003\014\040\123\164\141\141\164\040 -+\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 -+\105\126\040\122\157\157\164\040\103\101 -+END -+CKA_ID UTF8 "0" -+CKA_ISSUER MULTILINE_OCTAL -+\060\130\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -+\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 -+\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 -+\051\060\047\006\003\125\004\003\014\040\123\164\141\141\164\040 -+\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 -+\105\126\040\122\157\157\164\040\103\101 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\004\000\230\226\215 -+END -+CKA_VALUE MULTILINE_OCTAL -+\060\202\005\160\060\202\003\130\240\003\002\001\002\002\004\000 -+\230\226\215\060\015\006\011\052\206\110\206\367\015\001\001\013 -+\005\000\060\130\061\013\060\011\006\003\125\004\006\023\002\116 -+\114\061\036\060\034\006\003\125\004\012\014\025\123\164\141\141 -+\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145 -+\156\061\051\060\047\006\003\125\004\003\014\040\123\164\141\141 -+\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145 -+\156\040\105\126\040\122\157\157\164\040\103\101\060\036\027\015 -+\061\060\061\062\060\070\061\061\061\071\062\071\132\027\015\062 -+\062\061\062\060\070\061\061\061\060\062\070\132\060\130\061\013 -+\060\011\006\003\125\004\006\023\002\116\114\061\036\060\034\006 -+\003\125\004\012\014\025\123\164\141\141\164\040\144\145\162\040 -+\116\145\144\145\162\154\141\156\144\145\156\061\051\060\047\006 -+\003\125\004\003\014\040\123\164\141\141\164\040\144\145\162\040 -+\116\145\144\145\162\154\141\156\144\145\156\040\105\126\040\122 -+\157\157\164\040\103\101\060\202\002\042\060\015\006\011\052\206 -+\110\206\367\015\001\001\001\005\000\003\202\002\017\000\060\202 -+\002\012\002\202\002\001\000\343\307\176\211\371\044\113\072\322 -+\063\203\065\054\151\354\334\011\244\343\121\250\045\053\171\270 -+\010\075\340\221\272\204\205\306\205\244\312\346\311\056\123\244 -+\311\044\036\375\125\146\161\135\054\305\140\150\004\267\331\302 -+\122\046\070\210\244\326\073\100\246\302\315\077\315\230\223\263 -+\124\024\130\226\125\325\120\376\206\255\244\143\177\134\207\366 -+\216\346\047\222\147\027\222\002\003\054\334\326\146\164\355\335 -+\147\377\301\141\215\143\117\017\233\155\027\060\046\357\253\322 -+\037\020\240\371\305\177\026\151\201\003\107\355\036\150\215\162 -+\241\115\262\046\306\272\154\137\155\326\257\321\261\023\216\251 -+\255\363\136\151\165\046\030\076\101\053\041\177\356\213\135\007 -+\006\235\103\304\051\012\053\374\052\076\206\313\074\203\072\371 -+\311\015\332\305\231\342\274\170\101\063\166\341\277\057\135\345 -+\244\230\120\014\025\335\340\372\234\177\070\150\320\262\246\172 -+\247\321\061\275\176\212\130\047\103\263\272\063\221\323\247\230 -+\025\134\232\346\323\017\165\331\374\101\230\227\076\252\045\333 -+\217\222\056\260\173\014\137\361\143\251\067\371\233\165\151\114 -+\050\046\045\332\325\362\022\160\105\125\343\337\163\136\067\365 -+\041\154\220\216\065\132\311\323\043\353\323\300\276\170\254\102 -+\050\130\146\245\106\155\160\002\327\020\371\113\124\374\135\206 -+\112\207\317\177\312\105\254\021\132\265\040\121\215\057\210\107 -+\227\071\300\317\272\300\102\001\100\231\110\041\013\153\247\322 -+\375\226\325\321\276\106\235\111\340\013\246\240\042\116\070\320 -+\301\074\060\274\160\217\054\165\314\320\305\214\121\073\075\224 -+\010\144\046\141\175\271\303\145\217\024\234\041\320\252\375\027 -+\162\003\217\275\233\214\346\136\123\236\271\235\357\202\273\341 -+\274\342\162\101\133\041\224\323\105\067\224\321\337\011\071\135 -+\347\043\252\232\035\312\155\250\012\206\205\212\202\276\102\007 -+\326\362\070\202\163\332\207\133\345\074\323\236\076\247\073\236 -+\364\003\263\371\361\175\023\164\002\377\273\241\345\372\000\171 -+\034\246\146\101\210\134\140\127\246\056\011\304\272\375\232\317 -+\247\037\100\303\273\314\132\012\125\113\073\070\166\121\270\143 -+\213\204\224\026\346\126\363\002\003\001\000\001\243\102\060\100 -+\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001 -+\377\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001 -+\006\060\035\006\003\125\035\016\004\026\004\024\376\253\000\220 -+\230\236\044\374\251\314\032\212\373\047\270\277\060\156\250\073 -+\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\003 -+\202\002\001\000\317\167\054\156\126\276\116\263\266\204\000\224 -+\253\107\311\015\322\166\307\206\237\035\007\323\266\264\273\010 -+\170\257\151\322\013\111\336\063\305\254\255\302\210\002\175\006 -+\267\065\002\301\140\311\277\304\350\224\336\324\323\251\023\045 -+\132\376\156\242\256\175\005\334\175\363\154\360\176\246\215\356 -+\331\327\316\130\027\350\251\051\256\163\110\207\347\233\312\156 -+\051\241\144\137\031\023\367\256\006\020\377\121\306\233\115\125 -+\045\117\223\231\020\001\123\165\361\023\316\307\246\101\101\322 -+\277\210\245\177\105\374\254\270\245\265\063\014\202\304\373\007 -+\366\152\345\045\204\137\006\312\301\206\071\021\333\130\315\167 -+\073\054\302\114\017\136\232\343\360\253\076\141\033\120\044\302 -+\300\364\361\031\360\021\051\266\245\030\002\233\327\143\114\160 -+\214\107\243\003\103\134\271\135\106\240\015\157\377\131\216\276 -+\335\237\162\303\133\053\337\214\133\316\345\014\106\154\222\262 -+\012\243\114\124\102\030\025\022\030\275\332\374\272\164\156\377 -+\301\266\240\144\330\251\137\125\256\237\134\152\166\226\330\163 -+\147\207\373\115\177\134\356\151\312\163\020\373\212\251\375\236 -+\275\066\070\111\111\207\364\016\024\360\351\207\270\077\247\117 -+\172\132\216\171\324\223\344\273\150\122\204\254\154\351\363\230 -+\160\125\162\062\371\064\253\053\111\265\315\040\142\344\072\172 -+\147\143\253\226\334\155\256\227\354\374\237\166\126\210\056\146 -+\317\133\266\311\244\260\327\005\272\341\047\057\223\273\046\052 -+\242\223\260\033\363\216\276\035\100\243\271\066\217\076\202\032 -+\032\136\210\352\120\370\131\342\203\106\051\013\343\104\134\341 -+\225\266\151\220\232\024\157\227\256\201\317\150\357\231\232\276 -+\265\347\341\177\370\372\023\107\026\114\314\155\010\100\347\213 -+\170\157\120\202\104\120\077\146\006\212\253\103\204\126\112\017 -+\040\055\206\016\365\322\333\322\172\212\113\315\245\350\116\361 -+\136\046\045\001\131\043\240\176\322\366\176\041\127\327\047\274 -+\025\127\114\244\106\301\340\203\036\014\114\115\037\117\006\031 -+\342\371\250\364\072\202\241\262\171\103\171\326\255\157\172\047 -+\220\003\244\352\044\207\077\331\275\331\351\362\137\120\111\034 -+\356\354\327\056 -+END -+ -+# Trust for "Staat der Nederlanden EV Root CA" -+# Issuer: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL -+# Serial Number: 10000013 (0x98968d) -+# Subject: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL -+# Not Valid Before: Wed Dec 08 11:19:29 2010 -+# Not Valid After : Thu Dec 08 11:10:28 2022 -+# Fingerprint (SHA-256): 4D:24:91:41:4C:FE:95:67:46:EC:4C:EF:A6:CF:6F:72:E2:8A:13:29:43:2F:9D:8A:90:7A:C4:CB:5D:AD:C1:5A -+# Fingerprint (SHA1): 76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB -+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "Staat der Nederlanden EV Root CA" -+CKA_CERT_SHA1_HASH MULTILINE_OCTAL -+\166\342\176\301\117\333\202\301\300\246\165\265\005\276\075\051 -+\264\355\333\273 -+END -+CKA_CERT_MD5_HASH MULTILINE_OCTAL -+\374\006\257\173\350\032\361\232\264\350\322\160\037\300\365\272 -+END -+CKA_ISSUER MULTILINE_OCTAL -+\060\130\061\013\060\011\006\003\125\004\006\023\002\116\114\061 -+\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040 -+\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061 -+\051\060\047\006\003\125\004\003\014\040\123\164\141\141\164\040 -+\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040 -+\105\126\040\122\157\157\164\040\103\101 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\004\000\230\226\215 -+END -+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -+ -+# -+# Certificate "IdenTrust Commercial Root CA 1" -+# -+# Issuer: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US -+# Serial Number:0a:01:42:80:00:00:01:45:23:c8:44:b5:00:00:00:02 -+# Subject: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US -+# Not Valid Before: Thu Jan 16 18:12:23 2014 -+# Not Valid After : Mon Jan 16 18:12:23 2034 -+# Fingerprint (SHA-256): 5D:56:49:9B:E4:D2:E0:8B:CF:CA:D0:8A:3E:38:72:3D:50:50:3B:DE:70:69:48:E4:2F:55:60:30:19:E5:28:AE -+# Fingerprint (SHA1): DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25 -+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "IdenTrust Commercial Root CA 1" -+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -+CKA_SUBJECT MULTILINE_OCTAL -+\060\112\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -+\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 -+\165\163\164\061\047\060\045\006\003\125\004\003\023\036\111\144 -+\145\156\124\162\165\163\164\040\103\157\155\155\145\162\143\151 -+\141\154\040\122\157\157\164\040\103\101\040\061 -+END -+CKA_ID UTF8 "0" -+CKA_ISSUER MULTILINE_OCTAL -+\060\112\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -+\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 -+\165\163\164\061\047\060\045\006\003\125\004\003\023\036\111\144 -+\145\156\124\162\165\163\164\040\103\157\155\155\145\162\143\151 -+\141\154\040\122\157\157\164\040\103\101\040\061 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\020\012\001\102\200\000\000\001\105\043\310\104\265\000\000 -+\000\002 -+END -+CKA_VALUE MULTILINE_OCTAL -+\060\202\005\140\060\202\003\110\240\003\002\001\002\002\020\012 -+\001\102\200\000\000\001\105\043\310\104\265\000\000\000\002\060 -+\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\112 -+\061\013\060\011\006\003\125\004\006\023\002\125\123\061\022\060 -+\020\006\003\125\004\012\023\011\111\144\145\156\124\162\165\163 -+\164\061\047\060\045\006\003\125\004\003\023\036\111\144\145\156 -+\124\162\165\163\164\040\103\157\155\155\145\162\143\151\141\154 -+\040\122\157\157\164\040\103\101\040\061\060\036\027\015\061\064 -+\060\061\061\066\061\070\061\062\062\063\132\027\015\063\064\060 -+\061\061\066\061\070\061\062\062\063\132\060\112\061\013\060\011 -+\006\003\125\004\006\023\002\125\123\061\022\060\020\006\003\125 -+\004\012\023\011\111\144\145\156\124\162\165\163\164\061\047\060 -+\045\006\003\125\004\003\023\036\111\144\145\156\124\162\165\163 -+\164\040\103\157\155\155\145\162\143\151\141\154\040\122\157\157 -+\164\040\103\101\040\061\060\202\002\042\060\015\006\011\052\206 -+\110\206\367\015\001\001\001\005\000\003\202\002\017\000\060\202 -+\002\012\002\202\002\001\000\247\120\031\336\077\231\075\324\063 -+\106\361\157\121\141\202\262\251\117\217\147\211\135\204\331\123 -+\335\014\050\331\327\360\377\256\225\103\162\231\371\265\135\174 -+\212\301\102\341\061\120\164\321\201\015\174\315\233\041\253\103 -+\342\254\255\136\206\156\363\011\212\037\132\062\275\242\353\224 -+\371\350\134\012\354\377\230\322\257\161\263\264\123\237\116\207 -+\357\222\274\275\354\117\062\060\210\113\027\136\127\304\123\302 -+\366\002\227\215\331\142\053\277\044\037\142\215\337\303\270\051 -+\113\111\170\074\223\140\210\042\374\231\332\066\310\302\242\324 -+\054\124\000\147\065\156\163\277\002\130\360\244\335\345\260\242 -+\046\172\312\340\066\245\031\026\365\375\267\357\256\077\100\365 -+\155\132\004\375\316\064\312\044\334\164\043\033\135\063\023\022 -+\135\304\001\045\366\060\335\002\135\237\340\325\107\275\264\353 -+\033\241\273\111\111\330\237\133\002\363\212\344\044\220\344\142 -+\117\117\301\257\213\016\164\027\250\321\162\210\152\172\001\111 -+\314\264\106\171\306\027\261\332\230\036\007\131\372\165\041\205 -+\145\335\220\126\316\373\253\245\140\235\304\235\371\122\260\213 -+\275\207\371\217\053\043\012\043\166\073\367\063\341\311\000\363 -+\151\371\113\242\340\116\274\176\223\071\204\007\367\104\160\176 -+\376\007\132\345\261\254\321\030\314\362\065\345\111\111\010\312 -+\126\311\075\373\017\030\175\213\073\301\023\302\115\217\311\117 -+\016\067\351\037\241\016\152\337\142\056\313\065\006\121\171\054 -+\310\045\070\364\372\113\247\211\134\234\322\343\015\071\206\112 -+\164\174\325\131\207\302\077\116\014\134\122\364\075\367\122\202 -+\361\352\243\254\375\111\064\032\050\363\101\210\072\023\356\350 -+\336\377\231\035\137\272\313\350\036\362\271\120\140\300\061\323 -+\163\345\357\276\240\355\063\013\164\276\040\040\304\147\154\360 -+\010\003\172\125\200\177\106\116\226\247\364\036\076\341\366\330 -+\011\341\063\144\053\143\327\062\136\237\371\300\173\017\170\157 -+\227\274\223\232\371\234\022\220\170\172\200\207\025\327\162\164 -+\234\125\164\170\261\272\341\156\160\004\272\117\240\272\150\303 -+\173\377\061\360\163\075\075\224\052\261\013\101\016\240\376\115 -+\210\145\153\171\063\264\327\002\003\001\000\001\243\102\060\100 -+\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006 -+\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001 -+\377\060\035\006\003\125\035\016\004\026\004\024\355\104\031\300 -+\323\360\006\213\356\244\173\276\102\347\046\124\310\216\066\166 -+\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\003 -+\202\002\001\000\015\256\220\062\366\246\113\174\104\166\031\141 -+\036\047\050\315\136\124\357\045\274\343\010\220\371\051\327\256 -+\150\010\341\224\000\130\357\056\056\176\123\122\214\266\134\007 -+\352\210\272\231\213\120\224\327\202\200\337\141\011\000\223\255 -+\015\024\346\316\301\362\067\224\170\260\137\234\263\242\163\270 -+\217\005\223\070\315\215\076\260\270\373\300\317\261\362\354\055 -+\055\033\314\354\252\232\263\252\140\202\033\055\073\303\204\075 -+\127\212\226\036\234\165\270\323\060\315\140\010\203\220\323\216 -+\124\361\115\146\300\135\164\003\100\243\356\205\176\302\037\167 -+\234\006\350\301\247\030\135\122\225\355\311\335\045\236\155\372 -+\251\355\243\072\064\320\131\173\332\355\120\363\065\277\355\353 -+\024\115\061\307\140\364\332\361\207\234\342\110\342\306\305\067 -+\373\006\020\372\165\131\146\061\107\051\332\166\232\034\351\202 -+\256\357\232\271\121\367\210\043\232\151\225\142\074\345\125\200 -+\066\327\124\002\377\361\271\135\316\324\043\157\330\105\204\112 -+\133\145\357\211\014\335\024\247\040\313\030\245\045\264\015\371 -+\001\360\242\322\364\000\310\164\216\241\052\110\216\145\333\023 -+\304\342\045\027\175\353\276\207\133\027\040\124\121\223\112\123 -+\003\013\354\135\312\063\355\142\375\105\307\057\133\334\130\240 -+\200\071\346\372\327\376\023\024\246\355\075\224\112\102\164\324 -+\303\167\131\163\315\217\106\276\125\070\357\372\350\221\062\352 -+\227\130\004\042\336\070\303\314\274\155\311\063\072\152\012\151 -+\077\240\310\352\162\217\214\143\206\043\275\155\074\226\236\225 -+\340\111\114\252\242\271\052\033\234\066\201\170\355\303\350\106 -+\342\046\131\104\165\036\331\165\211\121\315\020\204\235\141\140 -+\313\135\371\227\042\115\216\230\346\343\177\366\133\273\256\315 -+\312\112\201\153\136\013\363\121\341\164\053\351\176\047\247\331 -+\231\111\116\370\245\200\333\045\017\034\143\142\212\311\063\147 -+\153\074\020\203\306\255\336\250\315\026\216\215\360\007\067\161 -+\237\362\253\374\101\365\301\213\354\000\067\135\011\345\116\200 -+\357\372\261\134\070\006\245\033\112\341\334\070\055\074\334\253 -+\037\220\032\325\112\234\356\321\160\154\314\356\364\127\370\030 -+\272\204\156\207 -+END -+ -+# Trust for "IdenTrust Commercial Root CA 1" -+# Issuer: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US -+# Serial Number:0a:01:42:80:00:00:01:45:23:c8:44:b5:00:00:00:02 -+# Subject: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US -+# Not Valid Before: Thu Jan 16 18:12:23 2014 -+# Not Valid After : Mon Jan 16 18:12:23 2034 -+# Fingerprint (SHA-256): 5D:56:49:9B:E4:D2:E0:8B:CF:CA:D0:8A:3E:38:72:3D:50:50:3B:DE:70:69:48:E4:2F:55:60:30:19:E5:28:AE -+# Fingerprint (SHA1): DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25 -+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "IdenTrust Commercial Root CA 1" -+CKA_CERT_SHA1_HASH MULTILINE_OCTAL -+\337\161\176\252\112\331\116\311\125\204\231\140\055\110\336\137 -+\274\360\072\045 -+END -+CKA_CERT_MD5_HASH MULTILINE_OCTAL -+\263\076\167\163\165\356\240\323\343\176\111\143\111\131\273\307 -+END -+CKA_ISSUER MULTILINE_OCTAL -+\060\112\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -+\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 -+\165\163\164\061\047\060\045\006\003\125\004\003\023\036\111\144 -+\145\156\124\162\165\163\164\040\103\157\155\155\145\162\143\151 -+\141\154\040\122\157\157\164\040\103\101\040\061 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\020\012\001\102\200\000\000\001\105\043\310\104\265\000\000 -+\000\002 -+END -+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -+ -+# -+# Certificate "IdenTrust Public Sector Root CA 1" -+# -+# Issuer: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US -+# Serial Number:0a:01:42:80:00:00:01:45:23:cf:46:7c:00:00:00:02 -+# Subject: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US -+# Not Valid Before: Thu Jan 16 17:53:32 2014 -+# Not Valid After : Mon Jan 16 17:53:32 2034 -+# Fingerprint (SHA-256): 30:D0:89:5A:9A:44:8A:26:20:91:63:55:22:D1:F5:20:10:B5:86:7A:CA:E1:2C:78:EF:95:8F:D4:F4:38:9F:2F -+# Fingerprint (SHA1): BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD -+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "IdenTrust Public Sector Root CA 1" -+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -+CKA_SUBJECT MULTILINE_OCTAL -+\060\115\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -+\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 -+\165\163\164\061\052\060\050\006\003\125\004\003\023\041\111\144 -+\145\156\124\162\165\163\164\040\120\165\142\154\151\143\040\123 -+\145\143\164\157\162\040\122\157\157\164\040\103\101\040\061 -+END -+CKA_ID UTF8 "0" -+CKA_ISSUER MULTILINE_OCTAL -+\060\115\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -+\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 -+\165\163\164\061\052\060\050\006\003\125\004\003\023\041\111\144 -+\145\156\124\162\165\163\164\040\120\165\142\154\151\143\040\123 -+\145\143\164\157\162\040\122\157\157\164\040\103\101\040\061 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\020\012\001\102\200\000\000\001\105\043\317\106\174\000\000 -+\000\002 -+END -+CKA_VALUE MULTILINE_OCTAL -+\060\202\005\146\060\202\003\116\240\003\002\001\002\002\020\012 -+\001\102\200\000\000\001\105\043\317\106\174\000\000\000\002\060 -+\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\115 -+\061\013\060\011\006\003\125\004\006\023\002\125\123\061\022\060 -+\020\006\003\125\004\012\023\011\111\144\145\156\124\162\165\163 -+\164\061\052\060\050\006\003\125\004\003\023\041\111\144\145\156 -+\124\162\165\163\164\040\120\165\142\154\151\143\040\123\145\143 -+\164\157\162\040\122\157\157\164\040\103\101\040\061\060\036\027 -+\015\061\064\060\061\061\066\061\067\065\063\063\062\132\027\015 -+\063\064\060\061\061\066\061\067\065\063\063\062\132\060\115\061 -+\013\060\011\006\003\125\004\006\023\002\125\123\061\022\060\020 -+\006\003\125\004\012\023\011\111\144\145\156\124\162\165\163\164 -+\061\052\060\050\006\003\125\004\003\023\041\111\144\145\156\124 -+\162\165\163\164\040\120\165\142\154\151\143\040\123\145\143\164 -+\157\162\040\122\157\157\164\040\103\101\040\061\060\202\002\042 -+\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003 -+\202\002\017\000\060\202\002\012\002\202\002\001\000\266\042\224 -+\374\244\110\257\350\107\153\012\373\047\166\344\362\077\212\073 -+\172\112\054\061\052\214\215\260\251\303\061\153\250\167\166\204 -+\046\266\254\201\102\015\010\353\125\130\273\172\370\274\145\175 -+\362\240\155\213\250\107\351\142\166\036\021\356\010\024\321\262 -+\104\026\364\352\320\372\036\057\136\333\313\163\101\256\274\000 -+\260\112\053\100\262\254\341\073\113\302\055\235\344\241\233\354 -+\032\072\036\360\010\263\320\344\044\065\007\237\234\264\311\122 -+\155\333\007\312\217\265\133\360\203\363\117\307\055\245\310\255 -+\313\225\040\244\061\050\127\130\132\344\215\033\232\253\236\015 -+\014\362\012\063\071\042\071\012\227\056\363\123\167\271\104\105 -+\375\204\313\066\040\201\131\055\232\157\155\110\110\141\312\114 -+\337\123\321\257\122\274\104\237\253\057\153\203\162\357\165\200 -+\332\006\063\033\135\310\332\143\306\115\315\254\146\061\315\321 -+\336\076\207\020\066\341\271\244\172\357\140\120\262\313\312\246 -+\126\340\067\257\253\064\023\071\045\350\071\146\344\230\172\252 -+\022\230\234\131\146\206\076\255\361\260\312\076\006\017\173\360 -+\021\113\067\240\104\155\173\313\250\214\161\364\325\265\221\066 -+\314\360\025\306\053\336\121\027\261\227\114\120\075\261\225\131 -+\174\005\175\055\041\325\000\277\001\147\242\136\173\246\134\362 -+\367\042\361\220\015\223\333\252\104\121\146\314\175\166\003\353 -+\152\250\052\070\031\227\166\015\153\212\141\371\274\366\356\166 -+\375\160\053\335\051\074\370\012\036\133\102\034\213\126\057\125 -+\033\034\241\056\265\307\026\346\370\252\074\222\216\151\266\001 -+\301\265\206\235\211\017\013\070\224\124\350\352\334\236\075\045 -+\274\123\046\355\325\253\071\252\305\100\114\124\253\262\264\331 -+\331\370\327\162\333\034\274\155\275\145\137\357\210\065\052\146 -+\057\356\366\263\145\360\063\215\174\230\101\151\106\017\103\034 -+\151\372\233\265\320\141\152\315\312\113\331\114\220\106\253\025 -+\131\241\107\124\051\056\203\050\137\034\302\242\253\162\027\000 -+\006\216\105\354\213\342\063\075\177\332\031\104\344\142\162\303 -+\337\042\306\362\126\324\335\137\225\162\355\155\137\367\110\003 -+\133\375\305\052\240\366\163\043\204\020\033\001\347\002\003\001 -+\000\001\243\102\060\100\060\016\006\003\125\035\017\001\001\377 -+\004\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377 -+\004\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026 -+\004\024\343\161\340\236\330\247\102\331\333\161\221\153\224\223 -+\353\303\243\321\024\243\060\015\006\011\052\206\110\206\367\015 -+\001\001\013\005\000\003\202\002\001\000\107\372\335\012\260\021 -+\221\070\255\115\135\367\345\016\227\124\031\202\110\207\124\214 -+\252\144\231\330\132\376\210\001\305\130\245\231\261\043\124\043 -+\267\152\035\040\127\345\001\142\101\027\323\011\333\165\313\156 -+\124\220\165\376\032\237\201\012\302\335\327\367\011\320\133\162 -+\025\344\036\011\152\075\063\363\041\232\346\025\176\255\121\325 -+\015\020\355\175\102\300\217\356\300\232\010\325\101\326\134\016 -+\041\151\156\200\141\016\025\300\270\317\305\111\022\122\314\276 -+\072\314\324\056\070\005\336\065\375\037\157\270\200\150\230\075 -+\115\240\312\100\145\322\163\174\365\213\331\012\225\077\330\077 -+\043\155\032\321\052\044\031\331\205\263\027\357\170\156\251\130 -+\321\043\323\307\023\355\162\045\177\135\261\163\160\320\177\006 -+\227\011\204\051\200\141\035\372\136\377\163\254\240\343\211\270 -+\034\161\025\306\336\061\177\022\334\341\155\233\257\347\350\237 -+\165\170\114\253\106\073\232\316\277\005\030\135\115\025\074\026 -+\232\031\120\004\232\262\232\157\145\213\122\137\074\130\004\050 -+\045\300\146\141\061\176\271\340\165\271\032\250\201\326\162\027 -+\263\305\003\061\065\021\170\170\242\340\351\060\214\177\200\337 -+\130\337\074\272\047\226\342\200\064\155\343\230\323\144\047\254 -+\110\176\050\167\134\306\045\141\045\370\205\014\145\372\304\062 -+\057\245\230\005\344\370\013\147\026\026\306\202\270\062\031\371 -+\371\271\171\334\037\315\353\257\253\016\335\033\333\105\344\172 -+\347\002\342\225\135\374\151\360\123\151\141\225\165\171\013\136 -+\125\346\070\034\224\251\131\063\236\310\161\164\171\177\121\211 -+\266\310\152\270\060\310\152\070\303\156\236\341\067\026\352\005 -+\142\114\133\022\107\355\247\264\263\130\126\307\111\363\177\022 -+\150\011\061\161\360\155\370\116\107\373\326\205\356\305\130\100 -+\031\244\035\247\371\113\103\067\334\150\132\117\317\353\302\144 -+\164\336\264\025\331\364\124\124\032\057\034\327\227\161\124\220 -+\216\331\040\235\123\053\177\253\217\342\352\060\274\120\067\357 -+\361\107\265\175\174\054\004\354\150\235\264\111\104\020\364\162 -+\113\034\144\347\374\346\153\220\335\151\175\151\375\000\126\245 -+\267\254\266\255\267\312\076\001\357\234 -+END -+ -+# Trust for "IdenTrust Public Sector Root CA 1" -+# Issuer: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US -+# Serial Number:0a:01:42:80:00:00:01:45:23:cf:46:7c:00:00:00:02 -+# Subject: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US -+# Not Valid Before: Thu Jan 16 17:53:32 2014 -+# Not Valid After : Mon Jan 16 17:53:32 2034 -+# Fingerprint (SHA-256): 30:D0:89:5A:9A:44:8A:26:20:91:63:55:22:D1:F5:20:10:B5:86:7A:CA:E1:2C:78:EF:95:8F:D4:F4:38:9F:2F -+# Fingerprint (SHA1): BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD -+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "IdenTrust Public Sector Root CA 1" -+CKA_CERT_SHA1_HASH MULTILINE_OCTAL -+\272\051\101\140\167\230\077\364\363\357\362\061\005\073\056\352 -+\155\115\105\375 -+END -+CKA_CERT_MD5_HASH MULTILINE_OCTAL -+\067\006\245\260\374\211\235\272\364\153\214\032\144\315\325\272 -+END -+CKA_ISSUER MULTILINE_OCTAL -+\060\115\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -+\022\060\020\006\003\125\004\012\023\011\111\144\145\156\124\162 -+\165\163\164\061\052\060\050\006\003\125\004\003\023\041\111\144 -+\145\156\124\162\165\163\164\040\120\165\142\154\151\143\040\123 -+\145\143\164\157\162\040\122\157\157\164\040\103\101\040\061 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\020\012\001\102\200\000\000\001\105\043\317\106\174\000\000 -+\000\002 -+END -+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -+ -+# -+# Certificate "S-TRUST Universal Root CA" -+# -+# Issuer: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE -+# Serial Number:60:56:c5:4b:23:40:5b:64:d4:ed:25:da:d9:d6:1e:1e -+# Subject: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE -+# Not Valid Before: Tue Oct 22 00:00:00 2013 -+# Not Valid After : Thu Oct 21 23:59:59 2038 -+# Fingerprint (SHA-256): D8:0F:EF:91:0A:E3:F1:04:72:3B:04:5C:EC:2D:01:9F:44:1C:E6:21:3A:DF:15:67:91:E7:0C:17:90:11:0A:31 -+# Fingerprint (SHA1): 1B:3D:11:14:EA:7A:0F:95:58:54:41:95:BF:6B:25:82:AB:40:CE:9A -+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "S-TRUST Universal Root CA" -+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -+CKA_SUBJECT MULTILINE_OCTAL -+\060\201\205\061\013\060\011\006\003\125\004\006\023\002\104\105 -+\061\051\060\047\006\003\125\004\012\023\040\104\145\165\164\163 -+\143\150\145\162\040\123\160\141\162\153\141\163\163\145\156\040 -+\126\145\162\154\141\147\040\107\155\142\110\061\047\060\045\006 -+\003\125\004\013\023\036\123\055\124\122\125\123\124\040\103\145 -+\162\164\151\146\151\143\141\164\151\157\156\040\123\145\162\166 -+\151\143\145\163\061\042\060\040\006\003\125\004\003\023\031\123 -+\055\124\122\125\123\124\040\125\156\151\166\145\162\163\141\154 -+\040\122\157\157\164\040\103\101 -+END -+CKA_ID UTF8 "0" -+CKA_ISSUER MULTILINE_OCTAL -+\060\201\205\061\013\060\011\006\003\125\004\006\023\002\104\105 -+\061\051\060\047\006\003\125\004\012\023\040\104\145\165\164\163 -+\143\150\145\162\040\123\160\141\162\153\141\163\163\145\156\040 -+\126\145\162\154\141\147\040\107\155\142\110\061\047\060\045\006 -+\003\125\004\013\023\036\123\055\124\122\125\123\124\040\103\145 -+\162\164\151\146\151\143\141\164\151\157\156\040\123\145\162\166 -+\151\143\145\163\061\042\060\040\006\003\125\004\003\023\031\123 -+\055\124\122\125\123\124\040\125\156\151\166\145\162\163\141\154 -+\040\122\157\157\164\040\103\101 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\020\140\126\305\113\043\100\133\144\324\355\045\332\331\326 -+\036\036 -+END -+CKA_VALUE MULTILINE_OCTAL -+\060\202\003\330\060\202\002\300\240\003\002\001\002\002\020\140 -+\126\305\113\043\100\133\144\324\355\045\332\331\326\036\036\060 -+\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\201 -+\205\061\013\060\011\006\003\125\004\006\023\002\104\105\061\051 -+\060\047\006\003\125\004\012\023\040\104\145\165\164\163\143\150 -+\145\162\040\123\160\141\162\153\141\163\163\145\156\040\126\145 -+\162\154\141\147\040\107\155\142\110\061\047\060\045\006\003\125 -+\004\013\023\036\123\055\124\122\125\123\124\040\103\145\162\164 -+\151\146\151\143\141\164\151\157\156\040\123\145\162\166\151\143 -+\145\163\061\042\060\040\006\003\125\004\003\023\031\123\055\124 -+\122\125\123\124\040\125\156\151\166\145\162\163\141\154\040\122 -+\157\157\164\040\103\101\060\036\027\015\061\063\061\060\062\062 -+\060\060\060\060\060\060\132\027\015\063\070\061\060\062\061\062 -+\063\065\071\065\071\132\060\201\205\061\013\060\011\006\003\125 -+\004\006\023\002\104\105\061\051\060\047\006\003\125\004\012\023 -+\040\104\145\165\164\163\143\150\145\162\040\123\160\141\162\153 -+\141\163\163\145\156\040\126\145\162\154\141\147\040\107\155\142 -+\110\061\047\060\045\006\003\125\004\013\023\036\123\055\124\122 -+\125\123\124\040\103\145\162\164\151\146\151\143\141\164\151\157 -+\156\040\123\145\162\166\151\143\145\163\061\042\060\040\006\003 -+\125\004\003\023\031\123\055\124\122\125\123\124\040\125\156\151 -+\166\145\162\163\141\154\040\122\157\157\164\040\103\101\060\202 -+\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005 -+\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000\250 -+\343\013\337\021\067\205\202\232\265\154\146\174\141\077\300\107 -+\032\035\106\343\260\125\144\345\270\202\071\050\007\176\027\377 -+\364\233\212\360\221\201\352\070\077\041\170\154\110\354\153\057 -+\242\323\212\162\262\247\327\331\352\177\264\300\111\153\060\045 -+\211\214\353\267\325\100\141\230\342\334\074\040\222\315\145\112 -+\162\237\032\216\214\372\045\025\277\363\041\203\050\015\213\257 -+\131\021\202\103\134\233\115\045\121\177\130\030\143\140\073\263 -+\265\212\213\130\143\067\110\110\220\104\302\100\335\135\367\103 -+\151\051\230\134\022\145\136\253\220\222\113\146\337\325\165\022 -+\123\124\030\246\336\212\326\273\127\003\071\131\231\030\005\014 -+\371\375\025\306\220\144\106\027\202\327\302\112\101\075\375\000 -+\276\127\162\030\224\167\033\123\132\211\001\366\063\162\016\223 -+\072\334\350\036\375\005\005\326\274\163\340\210\334\253\117\354 -+\265\030\206\117\171\204\016\110\052\146\052\335\062\310\170\145 -+\310\013\235\130\001\005\161\355\201\365\150\027\156\313\015\264 -+\113\330\241\354\256\070\353\034\130\057\241\145\003\064\057\002 -+\003\001\000\001\243\102\060\100\060\017\006\003\125\035\023\001 -+\001\377\004\005\060\003\001\001\377\060\016\006\003\125\035\017 -+\001\001\377\004\004\003\002\001\006\060\035\006\003\125\035\016 -+\004\026\004\024\232\175\327\353\353\177\124\230\105\051\264\040 -+\253\155\013\226\043\031\244\302\060\015\006\011\052\206\110\206 -+\367\015\001\001\013\005\000\003\202\001\001\000\116\226\022\333 -+\176\167\136\222\047\236\041\027\030\202\166\330\077\274\245\011 -+\004\146\210\211\255\333\125\263\063\152\306\145\304\217\115\363 -+\062\066\334\171\004\226\251\167\062\321\227\365\030\153\214\272 -+\355\316\021\320\104\307\222\361\264\104\216\355\210\122\110\236 -+\325\375\131\370\243\036\121\373\001\122\345\137\345\172\335\252 -+\044\117\042\213\335\166\106\366\245\240\017\065\330\312\017\230 -+\271\060\135\040\157\302\201\036\275\275\300\376\025\323\070\052 -+\011\223\230\047\033\223\173\320\053\064\136\150\245\025\117\321 -+\122\303\240\312\240\203\105\035\365\365\267\131\163\135\131\001 -+\217\252\302\107\057\024\161\325\051\343\020\265\107\223\045\314 -+\043\051\332\267\162\330\221\324\354\033\110\212\042\344\301\052 -+\367\072\150\223\237\105\031\156\103\267\314\376\270\221\232\141 -+\032\066\151\143\144\222\050\363\157\141\222\205\023\237\311\007 -+\054\213\127\334\353\236\171\325\302\336\010\325\124\262\127\116 -+\052\062\215\241\342\072\321\020\040\042\071\175\064\105\157\161 -+\073\303\035\374\377\262\117\250\342\366\060\036 -+END -+ -+# Trust for "S-TRUST Universal Root CA" -+# Issuer: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE -+# Serial Number:60:56:c5:4b:23:40:5b:64:d4:ed:25:da:d9:d6:1e:1e -+# Subject: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE -+# Not Valid Before: Tue Oct 22 00:00:00 2013 -+# Not Valid After : Thu Oct 21 23:59:59 2038 -+# Fingerprint (SHA-256): D8:0F:EF:91:0A:E3:F1:04:72:3B:04:5C:EC:2D:01:9F:44:1C:E6:21:3A:DF:15:67:91:E7:0C:17:90:11:0A:31 -+# Fingerprint (SHA1): 1B:3D:11:14:EA:7A:0F:95:58:54:41:95:BF:6B:25:82:AB:40:CE:9A -+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "S-TRUST Universal Root CA" -+CKA_CERT_SHA1_HASH MULTILINE_OCTAL -+\033\075\021\024\352\172\017\225\130\124\101\225\277\153\045\202 -+\253\100\316\232 -+END -+CKA_CERT_MD5_HASH MULTILINE_OCTAL -+\130\366\101\001\256\365\133\121\231\116\134\041\350\117\324\146 -+END -+CKA_ISSUER MULTILINE_OCTAL -+\060\201\205\061\013\060\011\006\003\125\004\006\023\002\104\105 -+\061\051\060\047\006\003\125\004\012\023\040\104\145\165\164\163 -+\143\150\145\162\040\123\160\141\162\153\141\163\163\145\156\040 -+\126\145\162\154\141\147\040\107\155\142\110\061\047\060\045\006 -+\003\125\004\013\023\036\123\055\124\122\125\123\124\040\103\145 -+\162\164\151\146\151\143\141\164\151\157\156\040\123\145\162\166 -+\151\143\145\163\061\042\060\040\006\003\125\004\003\023\031\123 -+\055\124\122\125\123\124\040\125\156\151\166\145\162\163\141\154 -+\040\122\157\157\164\040\103\101 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\020\140\126\305\113\043\100\133\144\324\355\045\332\331\326 -+\036\036 -+END -+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -+ -+# -+# Certificate "Entrust Root Certification Authority - G2" -+# -+# Issuer: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US -+# Serial Number: 1246989352 (0x4a538c28) -+# Subject: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US -+# Not Valid Before: Tue Jul 07 17:25:54 2009 -+# Not Valid After : Sat Dec 07 17:55:54 2030 -+# Fingerprint (SHA-256): 43:DF:57:74:B0:3E:7F:EF:5F:E4:0D:93:1A:7B:ED:F1:BB:2E:6B:42:73:8C:4E:6D:38:41:10:3D:3A:A7:F3:39 -+# Fingerprint (SHA1): 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 -+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "Entrust Root Certification Authority - G2" -+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -+CKA_SUBJECT MULTILINE_OCTAL -+\060\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123 -+\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 -+\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 -+\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 -+\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 -+\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 -+\040\062\060\060\071\040\105\156\164\162\165\163\164\054\040\111 -+\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 -+\151\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060 -+\060\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040 -+\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 -+\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107 -+\062 -+END -+CKA_ID UTF8 "0" -+CKA_ISSUER MULTILINE_OCTAL -+\060\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123 -+\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 -+\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 -+\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 -+\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 -+\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 -+\040\062\060\060\071\040\105\156\164\162\165\163\164\054\040\111 -+\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 -+\151\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060 -+\060\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040 -+\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 -+\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107 -+\062 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\004\112\123\214\050 -+END -+CKA_VALUE MULTILINE_OCTAL -+\060\202\004\076\060\202\003\046\240\003\002\001\002\002\004\112 -+\123\214\050\060\015\006\011\052\206\110\206\367\015\001\001\013 -+\005\000\060\201\276\061\013\060\011\006\003\125\004\006\023\002 -+\125\123\061\026\060\024\006\003\125\004\012\023\015\105\156\164 -+\162\165\163\164\054\040\111\156\143\056\061\050\060\046\006\003 -+\125\004\013\023\037\123\145\145\040\167\167\167\056\145\156\164 -+\162\165\163\164\056\156\145\164\057\154\145\147\141\154\055\164 -+\145\162\155\163\061\071\060\067\006\003\125\004\013\023\060\050 -+\143\051\040\062\060\060\071\040\105\156\164\162\165\163\164\054 -+\040\111\156\143\056\040\055\040\146\157\162\040\141\165\164\150 -+\157\162\151\172\145\144\040\165\163\145\040\157\156\154\171\061 -+\062\060\060\006\003\125\004\003\023\051\105\156\164\162\165\163 -+\164\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141 -+\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040\055 -+\040\107\062\060\036\027\015\060\071\060\067\060\067\061\067\062 -+\065\065\064\132\027\015\063\060\061\062\060\067\061\067\065\065 -+\065\064\132\060\201\276\061\013\060\011\006\003\125\004\006\023 -+\002\125\123\061\026\060\024\006\003\125\004\012\023\015\105\156 -+\164\162\165\163\164\054\040\111\156\143\056\061\050\060\046\006 -+\003\125\004\013\023\037\123\145\145\040\167\167\167\056\145\156 -+\164\162\165\163\164\056\156\145\164\057\154\145\147\141\154\055 -+\164\145\162\155\163\061\071\060\067\006\003\125\004\013\023\060 -+\050\143\051\040\062\060\060\071\040\105\156\164\162\165\163\164 -+\054\040\111\156\143\056\040\055\040\146\157\162\040\141\165\164 -+\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154\171 -+\061\062\060\060\006\003\125\004\003\023\051\105\156\164\162\165 -+\163\164\040\122\157\157\164\040\103\145\162\164\151\146\151\143 -+\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040 -+\055\040\107\062\060\202\001\042\060\015\006\011\052\206\110\206 -+\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012 -+\002\202\001\001\000\272\204\266\162\333\236\014\153\342\231\351 -+\060\001\247\166\352\062\270\225\101\032\311\332\141\116\130\162 -+\317\376\366\202\171\277\163\141\006\012\245\047\330\263\137\323 -+\105\116\034\162\326\116\062\362\162\212\017\367\203\031\320\152 -+\200\200\000\105\036\260\307\347\232\277\022\127\047\034\243\150 -+\057\012\207\275\152\153\016\136\145\363\034\167\325\324\205\215 -+\160\041\264\263\062\347\213\242\325\206\071\002\261\270\322\107 -+\316\344\311\111\304\073\247\336\373\124\175\127\276\360\350\156 -+\302\171\262\072\013\125\342\120\230\026\062\023\134\057\170\126 -+\301\302\224\263\362\132\344\047\232\237\044\327\306\354\320\233 -+\045\202\343\314\302\304\105\305\214\227\172\006\153\052\021\237 -+\251\012\156\110\073\157\333\324\021\031\102\367\217\007\277\365 -+\123\137\234\076\364\027\054\346\151\254\116\062\114\142\167\352 -+\267\350\345\273\064\274\031\213\256\234\121\347\267\176\265\123 -+\261\063\042\345\155\317\160\074\032\372\342\233\147\266\203\364 -+\215\245\257\142\114\115\340\130\254\144\064\022\003\370\266\215 -+\224\143\044\244\161\002\003\001\000\001\243\102\060\100\060\016 -+\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060\017 -+\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060 -+\035\006\003\125\035\016\004\026\004\024\152\162\046\172\320\036 -+\357\175\347\073\151\121\324\154\215\237\220\022\146\253\060\015 -+\006\011\052\206\110\206\367\015\001\001\013\005\000\003\202\001 -+\001\000\171\237\035\226\306\266\171\077\042\215\207\323\207\003 -+\004\140\152\153\232\056\131\211\163\021\254\103\321\365\023\377 -+\215\071\053\300\362\275\117\160\214\251\057\352\027\304\013\124 -+\236\324\033\226\230\063\074\250\255\142\242\000\166\253\131\151 -+\156\006\035\176\304\271\104\215\230\257\022\324\141\333\012\031 -+\106\107\363\353\367\143\301\100\005\100\245\322\267\364\265\232 -+\066\277\251\210\166\210\004\125\004\053\234\207\177\032\067\074 -+\176\055\245\032\330\324\211\136\312\275\254\075\154\330\155\257 -+\325\363\166\017\315\073\210\070\042\235\154\223\232\304\075\277 -+\202\033\145\077\246\017\135\252\374\345\262\025\312\265\255\306 -+\274\075\320\204\350\352\006\162\260\115\071\062\170\277\076\021 -+\234\013\244\235\232\041\363\360\233\013\060\170\333\301\334\207 -+\103\376\274\143\232\312\305\302\034\311\307\215\377\073\022\130 -+\010\346\266\075\354\172\054\116\373\203\226\316\014\074\151\207 -+\124\163\244\163\302\223\377\121\020\254\025\124\001\330\374\005 -+\261\211\241\177\164\203\232\111\327\334\116\173\212\110\157\213 -+\105\366 -+END -+ -+# Trust for "Entrust Root Certification Authority - G2" -+# Issuer: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US -+# Serial Number: 1246989352 (0x4a538c28) -+# Subject: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US -+# Not Valid Before: Tue Jul 07 17:25:54 2009 -+# Not Valid After : Sat Dec 07 17:55:54 2030 -+# Fingerprint (SHA-256): 43:DF:57:74:B0:3E:7F:EF:5F:E4:0D:93:1A:7B:ED:F1:BB:2E:6B:42:73:8C:4E:6D:38:41:10:3D:3A:A7:F3:39 -+# Fingerprint (SHA1): 8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4 -+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "Entrust Root Certification Authority - G2" -+CKA_CERT_SHA1_HASH MULTILINE_OCTAL -+\214\364\047\375\171\014\072\321\146\006\215\350\036\127\357\273 -+\223\042\162\324 -+END -+CKA_CERT_MD5_HASH MULTILINE_OCTAL -+\113\342\311\221\226\145\014\364\016\132\223\222\240\012\376\262 -+END -+CKA_ISSUER MULTILINE_OCTAL -+\060\201\276\061\013\060\011\006\003\125\004\006\023\002\125\123 -+\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 -+\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 -+\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 -+\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 -+\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 -+\040\062\060\060\071\040\105\156\164\162\165\163\164\054\040\111 -+\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 -+\151\172\145\144\040\165\163\145\040\157\156\154\171\061\062\060 -+\060\006\003\125\004\003\023\051\105\156\164\162\165\163\164\040 -+\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 -+\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107 -+\062 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\004\112\123\214\050 -+END -+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -+ -+# -+# Certificate "Entrust Root Certification Authority - EC1" -+# -+# Issuer: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US -+# Serial Number:00:a6:8b:79:29:00:00:00:00:50:d0:91:f9 -+# Subject: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US -+# Not Valid Before: Tue Dec 18 15:25:36 2012 -+# Not Valid After : Fri Dec 18 15:55:36 2037 -+# Fingerprint (SHA-256): 02:ED:0E:B2:8C:14:DA:45:16:5C:56:67:91:70:0D:64:51:D7:FB:56:F0:B2:AB:1D:3B:8E:B0:70:E5:6E:DF:F5 -+# Fingerprint (SHA1): 20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47 -+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "Entrust Root Certification Authority - EC1" -+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -+CKA_SUBJECT MULTILINE_OCTAL -+\060\201\277\061\013\060\011\006\003\125\004\006\023\002\125\123 -+\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 -+\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 -+\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 -+\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 -+\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 -+\040\062\060\061\062\040\105\156\164\162\165\163\164\054\040\111 -+\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 -+\151\172\145\144\040\165\163\145\040\157\156\154\171\061\063\060 -+\061\006\003\125\004\003\023\052\105\156\164\162\165\163\164\040 -+\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 -+\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\105 -+\103\061 -+END -+CKA_ID UTF8 "0" -+CKA_ISSUER MULTILINE_OCTAL -+\060\201\277\061\013\060\011\006\003\125\004\006\023\002\125\123 -+\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 -+\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 -+\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 -+\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 -+\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 -+\040\062\060\061\062\040\105\156\164\162\165\163\164\054\040\111 -+\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 -+\151\172\145\144\040\165\163\145\040\157\156\154\171\061\063\060 -+\061\006\003\125\004\003\023\052\105\156\164\162\165\163\164\040 -+\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 -+\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\105 -+\103\061 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\015\000\246\213\171\051\000\000\000\000\120\320\221\371 -+END -+CKA_VALUE MULTILINE_OCTAL -+\060\202\002\371\060\202\002\200\240\003\002\001\002\002\015\000 -+\246\213\171\051\000\000\000\000\120\320\221\371\060\012\006\010 -+\052\206\110\316\075\004\003\003\060\201\277\061\013\060\011\006 -+\003\125\004\006\023\002\125\123\061\026\060\024\006\003\125\004 -+\012\023\015\105\156\164\162\165\163\164\054\040\111\156\143\056 -+\061\050\060\046\006\003\125\004\013\023\037\123\145\145\040\167 -+\167\167\056\145\156\164\162\165\163\164\056\156\145\164\057\154 -+\145\147\141\154\055\164\145\162\155\163\061\071\060\067\006\003 -+\125\004\013\023\060\050\143\051\040\062\060\061\062\040\105\156 -+\164\162\165\163\164\054\040\111\156\143\056\040\055\040\146\157 -+\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163\145 -+\040\157\156\154\171\061\063\060\061\006\003\125\004\003\023\052 -+\105\156\164\162\165\163\164\040\122\157\157\164\040\103\145\162 -+\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157 -+\162\151\164\171\040\055\040\105\103\061\060\036\027\015\061\062 -+\061\062\061\070\061\065\062\065\063\066\132\027\015\063\067\061 -+\062\061\070\061\065\065\065\063\066\132\060\201\277\061\013\060 -+\011\006\003\125\004\006\023\002\125\123\061\026\060\024\006\003 -+\125\004\012\023\015\105\156\164\162\165\163\164\054\040\111\156 -+\143\056\061\050\060\046\006\003\125\004\013\023\037\123\145\145 -+\040\167\167\167\056\145\156\164\162\165\163\164\056\156\145\164 -+\057\154\145\147\141\154\055\164\145\162\155\163\061\071\060\067 -+\006\003\125\004\013\023\060\050\143\051\040\062\060\061\062\040 -+\105\156\164\162\165\163\164\054\040\111\156\143\056\040\055\040 -+\146\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165 -+\163\145\040\157\156\154\171\061\063\060\061\006\003\125\004\003 -+\023\052\105\156\164\162\165\163\164\040\122\157\157\164\040\103 -+\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164 -+\150\157\162\151\164\171\040\055\040\105\103\061\060\166\060\020 -+\006\007\052\206\110\316\075\002\001\006\005\053\201\004\000\042 -+\003\142\000\004\204\023\311\320\272\155\101\173\342\154\320\353 -+\125\137\146\002\032\044\364\133\211\151\107\343\270\302\175\361 -+\362\002\305\237\240\366\133\325\213\006\031\206\117\123\020\155 -+\007\044\047\241\240\370\325\107\031\141\114\175\312\223\047\352 -+\164\014\357\157\226\011\376\143\354\160\135\066\255\147\167\256 -+\311\235\174\125\104\072\242\143\121\037\365\343\142\324\251\107 -+\007\076\314\040\243\102\060\100\060\016\006\003\125\035\017\001 -+\001\377\004\004\003\002\001\006\060\017\006\003\125\035\023\001 -+\001\377\004\005\060\003\001\001\377\060\035\006\003\125\035\016 -+\004\026\004\024\267\143\347\032\335\215\351\010\246\125\203\244 -+\340\152\120\101\145\021\102\111\060\012\006\010\052\206\110\316 -+\075\004\003\003\003\147\000\060\144\002\060\141\171\330\345\102 -+\107\337\034\256\123\231\027\266\157\034\175\341\277\021\224\321 -+\003\210\165\344\215\211\244\212\167\106\336\155\141\357\002\365 -+\373\265\337\314\376\116\377\376\251\346\247\002\060\133\231\327 -+\205\067\006\265\173\010\375\353\047\213\112\224\371\341\372\247 -+\216\046\010\350\174\222\150\155\163\330\157\046\254\041\002\270 -+\231\267\046\101\133\045\140\256\320\110\032\356\006 -+END -+ -+# Trust for "Entrust Root Certification Authority - EC1" -+# Issuer: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US -+# Serial Number:00:a6:8b:79:29:00:00:00:00:50:d0:91:f9 -+# Subject: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US -+# Not Valid Before: Tue Dec 18 15:25:36 2012 -+# Not Valid After : Fri Dec 18 15:55:36 2037 -+# Fingerprint (SHA-256): 02:ED:0E:B2:8C:14:DA:45:16:5C:56:67:91:70:0D:64:51:D7:FB:56:F0:B2:AB:1D:3B:8E:B0:70:E5:6E:DF:F5 -+# Fingerprint (SHA1): 20:D8:06:40:DF:9B:25:F5:12:25:3A:11:EA:F7:59:8A:EB:14:B5:47 -+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "Entrust Root Certification Authority - EC1" -+CKA_CERT_SHA1_HASH MULTILINE_OCTAL -+\040\330\006\100\337\233\045\365\022\045\072\021\352\367\131\212 -+\353\024\265\107 -+END -+CKA_CERT_MD5_HASH MULTILINE_OCTAL -+\266\176\035\360\130\305\111\154\044\073\075\355\230\030\355\274 -+END -+CKA_ISSUER MULTILINE_OCTAL -+\060\201\277\061\013\060\011\006\003\125\004\006\023\002\125\123 -+\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165 -+\163\164\054\040\111\156\143\056\061\050\060\046\006\003\125\004 -+\013\023\037\123\145\145\040\167\167\167\056\145\156\164\162\165 -+\163\164\056\156\145\164\057\154\145\147\141\154\055\164\145\162 -+\155\163\061\071\060\067\006\003\125\004\013\023\060\050\143\051 -+\040\062\060\061\062\040\105\156\164\162\165\163\164\054\040\111 -+\156\143\056\040\055\040\146\157\162\040\141\165\164\150\157\162 -+\151\172\145\144\040\165\163\145\040\157\156\154\171\061\063\060 -+\061\006\003\125\004\003\023\052\105\156\164\162\165\163\164\040 -+\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\151 -+\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\105 -+\103\061 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\015\000\246\213\171\051\000\000\000\000\120\320\221\371 -+END -+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -+ -+# -+# Certificate "CFCA EV ROOT" -+# -+# Issuer: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN -+# Serial Number: 407555286 (0x184accd6) -+# Subject: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN -+# Not Valid Before: Wed Aug 08 03:07:01 2012 -+# Not Valid After : Mon Dec 31 03:07:01 2029 -+# Fingerprint (SHA-256): 5C:C3:D7:8E:4E:1D:5E:45:54:7A:04:E6:87:3E:64:F9:0C:F9:53:6D:1C:CC:2E:F8:00:F3:55:C4:C5:FD:70:FD -+# Fingerprint (SHA1): E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83 -+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "CFCA EV ROOT" -+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -+CKA_SUBJECT MULTILINE_OCTAL -+\060\126\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -+\060\060\056\006\003\125\004\012\014\047\103\150\151\156\141\040 -+\106\151\156\141\156\143\151\141\154\040\103\145\162\164\151\146 -+\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 -+\171\061\025\060\023\006\003\125\004\003\014\014\103\106\103\101 -+\040\105\126\040\122\117\117\124 -+END -+CKA_ID UTF8 "0" -+CKA_ISSUER MULTILINE_OCTAL -+\060\126\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -+\060\060\056\006\003\125\004\012\014\047\103\150\151\156\141\040 -+\106\151\156\141\156\143\151\141\154\040\103\145\162\164\151\146 -+\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 -+\171\061\025\060\023\006\003\125\004\003\014\014\103\106\103\101 -+\040\105\126\040\122\117\117\124 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\004\030\112\314\326 -+END -+CKA_VALUE MULTILINE_OCTAL -+\060\202\005\215\060\202\003\165\240\003\002\001\002\002\004\030 -+\112\314\326\060\015\006\011\052\206\110\206\367\015\001\001\013 -+\005\000\060\126\061\013\060\011\006\003\125\004\006\023\002\103 -+\116\061\060\060\056\006\003\125\004\012\014\047\103\150\151\156 -+\141\040\106\151\156\141\156\143\151\141\154\040\103\145\162\164 -+\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162 -+\151\164\171\061\025\060\023\006\003\125\004\003\014\014\103\106 -+\103\101\040\105\126\040\122\117\117\124\060\036\027\015\061\062 -+\060\070\060\070\060\063\060\067\060\061\132\027\015\062\071\061 -+\062\063\061\060\063\060\067\060\061\132\060\126\061\013\060\011 -+\006\003\125\004\006\023\002\103\116\061\060\060\056\006\003\125 -+\004\012\014\047\103\150\151\156\141\040\106\151\156\141\156\143 -+\151\141\154\040\103\145\162\164\151\146\151\143\141\164\151\157 -+\156\040\101\165\164\150\157\162\151\164\171\061\025\060\023\006 -+\003\125\004\003\014\014\103\106\103\101\040\105\126\040\122\117 -+\117\124\060\202\002\042\060\015\006\011\052\206\110\206\367\015 -+\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202 -+\002\001\000\327\135\153\315\020\077\037\005\131\325\005\115\067 -+\261\016\354\230\053\216\025\035\372\223\113\027\202\041\161\020 -+\122\327\121\144\160\026\302\125\151\115\216\025\155\237\277\014 -+\033\302\340\243\147\326\014\254\317\042\256\257\167\124\052\113 -+\114\212\123\122\172\303\356\056\336\263\161\045\301\351\135\075 -+\356\241\057\243\367\052\074\311\043\035\152\253\035\241\247\361 -+\363\354\240\325\104\317\025\317\162\057\035\143\227\350\231\371 -+\375\223\244\124\200\114\122\324\122\253\056\111\337\220\315\270 -+\137\276\077\336\241\312\115\040\324\045\350\204\051\123\267\261 -+\210\037\377\372\332\220\237\012\251\055\101\077\261\361\030\051 -+\356\026\131\054\064\111\032\250\006\327\250\210\322\003\162\172 -+\062\342\352\150\115\156\054\226\145\173\312\131\372\362\342\335 -+\356\060\054\373\314\106\254\304\143\353\157\177\066\053\064\163 -+\022\224\177\337\314\046\236\361\162\135\120\145\131\217\151\263 -+\207\136\062\157\303\030\212\265\225\217\260\172\067\336\132\105 -+\073\307\066\341\357\147\321\071\323\227\133\163\142\031\110\055 -+\207\034\006\373\164\230\040\111\163\360\005\322\033\261\240\243 -+\267\033\160\323\210\151\271\132\326\070\364\142\334\045\213\170 -+\277\370\350\176\270\134\311\225\117\137\247\055\271\040\153\317 -+\153\335\365\015\364\202\267\364\262\146\056\020\050\366\227\132 -+\173\226\026\217\001\031\055\154\156\177\071\130\006\144\203\001 -+\203\203\303\115\222\335\062\306\207\244\067\351\026\316\252\055 -+\150\257\012\201\145\072\160\301\233\255\115\155\124\312\052\055 -+\113\205\033\263\200\346\160\105\015\153\136\065\360\177\073\270 -+\234\344\004\160\211\022\045\223\332\012\231\042\140\152\143\140 -+\116\166\006\230\116\275\203\255\035\130\212\045\205\322\307\145 -+\036\055\216\306\337\266\306\341\177\212\004\041\025\051\164\360 -+\076\234\220\235\014\056\361\212\076\132\252\014\011\036\307\325 -+\074\243\355\227\303\036\064\372\070\371\010\016\343\300\135\053 -+\203\321\126\152\311\266\250\124\123\056\170\062\147\075\202\177 -+\164\320\373\341\266\005\140\271\160\333\216\013\371\023\130\157 -+\161\140\020\122\020\271\301\101\011\357\162\037\147\061\170\377 -+\226\005\215\002\003\001\000\001\243\143\060\141\060\037\006\003 -+\125\035\043\004\030\060\026\200\024\343\376\055\375\050\320\013 -+\265\272\266\242\304\277\006\252\005\214\223\373\057\060\017\006 -+\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060\016 -+\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060\035 -+\006\003\125\035\016\004\026\004\024\343\376\055\375\050\320\013 -+\265\272\266\242\304\277\006\252\005\214\223\373\057\060\015\006 -+\011\052\206\110\206\367\015\001\001\013\005\000\003\202\002\001 -+\000\045\306\272\153\353\207\313\336\202\071\226\075\360\104\247 -+\153\204\163\003\336\235\053\117\272\040\177\274\170\262\317\227 -+\260\033\234\363\327\171\056\365\110\266\322\373\027\210\346\323 -+\172\077\355\123\023\320\342\057\152\171\313\000\043\050\346\036 -+\067\127\065\211\204\302\166\117\064\066\255\147\303\316\101\006 -+\210\305\367\356\330\032\270\326\013\177\120\377\223\252\027\113 -+\214\354\355\122\140\262\244\006\352\116\353\364\153\031\375\353 -+\365\032\340\045\052\232\334\307\101\066\367\310\164\005\204\071 -+\225\071\326\013\073\244\047\372\010\330\134\036\370\004\140\122 -+\021\050\050\003\377\357\123\146\000\245\112\064\026\146\174\375 -+\011\244\256\236\147\032\157\101\013\153\006\023\233\217\206\161 -+\005\264\057\215\211\146\063\051\166\124\232\021\370\047\372\262 -+\077\221\340\316\015\033\363\060\032\255\277\042\135\033\323\277 -+\045\005\115\341\222\032\177\231\237\074\104\223\312\324\100\111 -+\154\200\207\327\004\072\303\062\122\065\016\126\370\245\335\175 -+\304\213\015\021\037\123\313\036\262\027\266\150\167\132\340\324 -+\313\310\007\256\365\072\056\216\067\267\320\001\113\103\051\167 -+\214\071\227\217\202\132\370\121\345\211\240\030\347\150\177\135 -+\012\056\373\243\107\016\075\246\043\172\306\001\307\217\310\136 -+\277\155\200\126\276\212\044\272\063\352\237\341\062\021\236\361 -+\322\117\200\366\033\100\257\070\236\021\120\171\163\022\022\315 -+\346\154\235\054\210\162\074\060\201\006\221\042\352\131\255\332 -+\031\056\042\302\215\271\214\207\340\146\274\163\043\137\041\144 -+\143\200\110\365\240\074\030\075\224\310\110\101\035\100\272\136 -+\376\376\126\071\241\310\317\136\236\031\144\106\020\332\027\221 -+\267\005\200\254\213\231\222\175\347\242\330\007\013\066\047\347 -+\110\171\140\212\303\327\023\134\370\162\100\337\112\313\317\231 -+\000\012\000\013\021\225\332\126\105\003\210\012\237\147\320\325 -+\171\261\250\215\100\155\015\302\172\100\372\363\137\144\107\222 -+\313\123\271\273\131\316\117\375\320\025\123\001\330\337\353\331 -+\346\166\357\320\043\273\073\251\171\263\325\002\051\315\211\243 -+\226\017\112\065\347\116\102\300\165\315\007\317\346\054\353\173 -+\056 -+END -+ -+# Trust for "CFCA EV ROOT" -+# Issuer: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN -+# Serial Number: 407555286 (0x184accd6) -+# Subject: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN -+# Not Valid Before: Wed Aug 08 03:07:01 2012 -+# Not Valid After : Mon Dec 31 03:07:01 2029 -+# Fingerprint (SHA-256): 5C:C3:D7:8E:4E:1D:5E:45:54:7A:04:E6:87:3E:64:F9:0C:F9:53:6D:1C:CC:2E:F8:00:F3:55:C4:C5:FD:70:FD -+# Fingerprint (SHA1): E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83 -+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -+CKA_TOKEN CK_BBOOL CK_TRUE -+CKA_PRIVATE CK_BBOOL CK_FALSE -+CKA_MODIFIABLE CK_BBOOL CK_FALSE -+CKA_LABEL UTF8 "CFCA EV ROOT" -+CKA_CERT_SHA1_HASH MULTILINE_OCTAL -+\342\270\051\113\125\204\253\153\130\302\220\106\154\254\077\270 -+\071\217\204\203 -+END -+CKA_CERT_MD5_HASH MULTILINE_OCTAL -+\164\341\266\355\046\172\172\104\060\063\224\253\173\047\201\060 -+END -+CKA_ISSUER MULTILINE_OCTAL -+\060\126\061\013\060\011\006\003\125\004\006\023\002\103\116\061 -+\060\060\056\006\003\125\004\012\014\047\103\150\151\156\141\040 -+\106\151\156\141\156\143\151\141\154\040\103\145\162\164\151\146 -+\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 -+\171\061\025\060\023\006\003\125\004\003\014\014\103\106\103\101 -+\040\105\126\040\122\117\117\124 -+END -+CKA_SERIAL_NUMBER MULTILINE_OCTAL -+\002\004\030\112\314\326 -+END -+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -diff --git a/lib/ckfw/builtins/nssckbi.h b/lib/ckfw/builtins/nssckbi.h ---- a/lib/ckfw/builtins/nssckbi.h -+++ b/lib/ckfw/builtins/nssckbi.h -@@ -40,18 +40,18 @@ - * ... - * - NSS 3.29 branch: 250-255 - * - * NSS_BUILTINS_LIBRARY_VERSION_MINOR is a CK_BYTE. It's not clear - * whether we may use its full range (0-255) or only 0-99 because - * of the comment in the CK_VERSION type definition. - */ - #define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 2 --#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 2 --#define NSS_BUILTINS_LIBRARY_VERSION "2.2" -+#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 3 -+#define NSS_BUILTINS_LIBRARY_VERSION "2.3" - - /* These version numbers detail the semantic changes to the ckfw engine. */ - #define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1 - #define NSS_BUILTINS_HARDWARE_VERSION_MINOR 0 - - /* These version numbers detail the semantic changes to ckbi itself - * (new PKCS #11 objects), etc. */ - #define NSS_BUILTINS_FIRMWARE_VERSION_MAJOR 1 - diff --git a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp index f961068c88e..89ecfcc628c 100644 --- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp +++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp @@ -272,6 +272,12 @@ SandboxBroker::SetSecurityLevelForGMPlugin() L"\\??\\pipe\\chrome.*"); ret = ret && (sandbox::SBOX_ALL_OK == result); + // Add the policy for the client side of the crash server pipe. + result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, + sandbox::TargetPolicy::FILES_ALLOW_ANY, + L"\\??\\pipe\\gecko-crash-server-pipe.*"); + ret = ret && (sandbox::SBOX_ALL_OK == result); + #ifdef DEBUG // The plugin process can't create named events, but we'll // make an exception for the events used in logging. Removing diff --git a/testing/config/mozharness/android_arm_4_3_config.py b/testing/config/mozharness/android_arm_4_3_config.py index 68dd1a6ceba..fa27cc35c42 100644 --- a/testing/config/mozharness/android_arm_4_3_config.py +++ b/testing/config/mozharness/android_arm_4_3_config.py @@ -25,8 +25,8 @@ config = { "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s", "--quiet", "--log-raw=%(raw_log_file)s", - "--total-chunks=2", - "--manifest=tests/dom/canvas/test/_webgl-conformance.ini", + "--total-chunks=4", + "--subsuite=webgl", ], }, "robocop": { diff --git a/testing/config/mozharness/android_arm_config.py b/testing/config/mozharness/android_arm_config.py index 37d32b3240f..45e0e931362 100644 --- a/testing/config/mozharness/android_arm_config.py +++ b/testing/config/mozharness/android_arm_config.py @@ -28,7 +28,7 @@ config = { "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s", "--quiet", "--log-raw=%(raw_log_file)s", "--total-chunks=4", - "--manifest=tests/dom/canvas/test/_webgl-conformance.ini", + "--subsuite=webgl", ], }, "robocop": { diff --git a/testing/marionette/client/marionette/runner/base.py b/testing/marionette/client/marionette/runner/base.py index 236f5221635..9070117218a 100644 --- a/testing/marionette/client/marionette/runner/base.py +++ b/testing/marionette/client/marionette/runner/base.py @@ -548,10 +548,10 @@ class BaseMarionetteTestRunner(object): # In the event we're gathering debug without starting a session, skip marionette commands if marionette.session is not None: try: - marionette.set_context(marionette.CONTEXT_CHROME) - rv['screenshot'] = marionette.screenshot() - marionette.set_context(marionette.CONTEXT_CONTENT) - rv['source'] = marionette.page_source + with marionette.using_context(marionette.CONTEXT_CHROME): + rv['screenshot'] = marionette.screenshot() + with marionette.using_context(marionette.CONTEXT_CONTENT): + rv['source'] = marionette.page_source except: logger = get_default_logger() logger.warning('Failed to gather test failure debug.', exc_info=True) diff --git a/testing/marionette/client/marionette/tests/unit/test_teardown_context_preserved.py b/testing/marionette/client/marionette/tests/unit/test_teardown_context_preserved.py new file mode 100644 index 00000000000..344d5f6aee5 --- /dev/null +++ b/testing/marionette/client/marionette/tests/unit/test_teardown_context_preserved.py @@ -0,0 +1,21 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +from marionette import MarionetteTestCase, SkipTest + + +class TestTearDownContext(MarionetteTestCase): + def setUp(self): + MarionetteTestCase.setUp(self) + self.marionette.set_context(self.marionette.CONTEXT_CHROME) + + def tearDown(self): + self.assertEqual(self.get_context(), self.marionette.CONTEXT_CHROME) + MarionetteTestCase.tearDown(self) + + def get_context(self): + return self.marionette._send_message('getContext', 'value') + + def test_skipped_teardown_ok(self): + raise SkipTest("This should leave our teardown method in chrome context") diff --git a/testing/marionette/client/marionette/tests/unit/unit-tests.ini b/testing/marionette/client/marionette/tests/unit/unit-tests.ini index 455b23804a2..5e30ee0db8b 100644 --- a/testing/marionette/client/marionette/tests/unit/unit-tests.ini +++ b/testing/marionette/client/marionette/tests/unit/unit-tests.ini @@ -148,3 +148,4 @@ skip-if = os == "linux" # Bug 1085717 [test_modal_dialogs.py] b2g = false [test_key_actions.py] +[test_teardown_context_preserved.py] diff --git a/testing/mochitest/mochitest_options.py b/testing/mochitest/mochitest_options.py index 9ddb50195c6..57d22083d3b 100644 --- a/testing/mochitest/mochitest_options.py +++ b/testing/mochitest/mochitest_options.py @@ -867,7 +867,7 @@ class B2GOptions(MochitestOptions): defaults["testPath"] = "" defaults["extensionsToExclude"] = ["specialpowers"] # See dependencies of bug 1038943. - defaults["defaultLeakThreshold"] = 5404 + defaults["defaultLeakThreshold"] = 5536 self.set_defaults(**defaults) def verifyRemoteOptions(self, options): diff --git a/testing/mochitest/runtests.py b/testing/mochitest/runtests.py index 9aa367207e9..bb3ff0d476d 100644 --- a/testing/mochitest/runtests.py +++ b/testing/mochitest/runtests.py @@ -417,7 +417,7 @@ class MochitestServer(object): time.sleep(1) i += 1 else: - self._log.error( + self._log.info( "TEST-UNEXPECTED-FAIL | runtests.py | Timed out while waiting for server startup.") self.stop() sys.exit(1) @@ -580,9 +580,7 @@ class MochitestUtilsMixin(object): if options.logFile: options.logFile = self.getLogFilePath(options.logFile) - # Note that all tests under options.subsuite need to be browser chrome - # tests. - if options.browserChrome or options.chrome or options.subsuite or \ + if options.browserChrome or options.chrome or \ options.a11y or options.webapprtChrome or options.jetpackPackage or \ options.jetpackAddon: self.makeTestConfig(options) @@ -928,7 +926,7 @@ toolbar#nav-bar { # Call installChromeJar(). if not os.path.isdir(os.path.join(SCRIPT_DIR, self.jarDir)): - self.log.error( + self.log.info( "TEST-UNEXPECTED-FAIL | invalid setup: missing mochikit extension") return None @@ -1419,7 +1417,7 @@ class Mochitest(MochitestUtilsMixin): # TODO: this should really be upstreamed somewhere, maybe mozprofile certificateStatus = self.fillCertificateDB(options) if certificateStatus: - self.log.error( + self.log.info( "TEST-UNEXPECTED-FAIL | runtests.py | Certificate integration failed") return None @@ -1611,7 +1609,7 @@ class Mochitest(MochitestUtilsMixin): processPID) if isPidAlive(processPID): foundZombie = True - self.log.error( + self.log.info( "TEST-UNEXPECTED-FAIL | zombiecheck | child process %d still alive after shutdown" % processPID) self.killAndGetStack( @@ -1698,9 +1696,9 @@ class Mochitest(MochitestUtilsMixin): os.close(tmpfd) env["MOZ_PROCESS_LOG"] = processLog - if interactive: - # If an interactive debugger is attached, - # don't use timeouts, and don't capture ctrl-c. + if debuggerInfo: + # If a debugger is attached, don't use timeouts, and don't + # capture ctrl-c. timeout = None signal.signal(signal.SIGINT, lambda sigid, frame: None) @@ -1800,7 +1798,7 @@ class Mochitest(MochitestUtilsMixin): # record post-test information if status: self.message_logger.dump_buffered() - self.log.error( + self.log.info( "TEST-UNEXPECTED-FAIL | %s | application terminated with exit code %s" % (self.lastTestSeen, status)) else: @@ -2035,18 +2033,19 @@ class Mochitest(MochitestUtilsMixin): def _psInfo(line): if pname in line: self.log.info(line) - process = mozprocess.ProcessHandler(['ps', '-f', '--no-headers'], + process = mozprocess.ProcessHandler(['ps', '-f'], processOutputLine=_psInfo) process.run() process.wait() def _psKill(line): parts = line.split() - pid = int(parts[0]) - if len(parts) == 3 and parts[2] == pname and parts[1] == '1': - self.log.info("killing %s orphan with pid %d" % (pname, pid)) - killPid(pid, self.log) - process = mozprocess.ProcessHandler(['ps', '-o', 'pid,ppid,comm', '--no-headers'], + if len(parts) == 3 and parts[0].isdigit(): + pid = int(parts[0]) + if parts[2] == pname and parts[1] == '1': + self.log.info("killing %s orphan with pid %d" % (pname, pid)) + killPid(pid, self.log) + process = mozprocess.ProcessHandler(['ps', '-o', 'pid,ppid,comm'], processOutputLine=_psKill) process.run() process.wait() @@ -2291,7 +2290,7 @@ class Mochitest(MochitestUtilsMixin): self.message_logger.dump_buffered() self.message_logger.buffering = False - self.log.error(error_message) + self.log.info(error_message) browserProcessId = browserProcessId or proc.pid self.killAndGetStack( diff --git a/testing/mozbase/mozprocess/mozprocess/processhandler.py b/testing/mozbase/mozprocess/mozprocess/processhandler.py index e9d83d6826c..0d15ced63e0 100644 --- a/testing/mozbase/mozprocess/mozprocess/processhandler.py +++ b/testing/mozbase/mozprocess/mozprocess/processhandler.py @@ -716,19 +716,15 @@ falling back to not using job objects for managing child processes""" :param sig: Signal used to kill the process, defaults to SIGKILL (has no effect on Windows) """ - try: - self.proc.kill(sig=sig) + if not hasattr(self, 'proc'): + raise RuntimeError("Calling kill() on a non started process is not" + " allowed.") + self.proc.kill(sig=sig) - # When we kill the the managed process we also have to wait for the - # reader thread to be finished. Otherwise consumers would have to assume - # that it still has not completely shutdown. - return self.wait() - except AttributeError: - # Try to print a relevant error message. - if not hasattr(self, 'proc'): - print >> sys.stderr, "Unable to kill Process because call to ProcessHandler constructor failed." - else: - raise + # When we kill the the managed process we also have to wait for the + # reader thread to be finished. Otherwise consumers would have to assume + # that it still has not completely shutdown. + return self.wait() def poll(self): """Check if child process has terminated @@ -742,7 +738,10 @@ falling back to not using job objects for managing child processes""" # Ensure that we first check for the reader status. Otherwise # we might mark the process as finished while output is still getting # processed. - if self.reader.is_alive(): + if not hasattr(self, 'proc'): + raise RuntimeError("Calling poll() on a non started process is not" + " allowed.") + elif self.reader.is_alive(): return None elif hasattr(self.proc, "returncode"): return self.proc.returncode diff --git a/testing/mozbase/mozprocess/tests/test_mozprocess_kill.py b/testing/mozbase/mozprocess/tests/test_mozprocess_kill.py index bb04ab5ceac..19859f4a989 100644 --- a/testing/mozbase/mozprocess/tests/test_mozprocess_kill.py +++ b/testing/mozbase/mozprocess/tests/test_mozprocess_kill.py @@ -11,6 +11,12 @@ here = os.path.dirname(os.path.abspath(__file__)) class ProcTestKill(proctest.ProcTest): """ Class to test various process tree killing scenatios """ + def test_kill_before_run(self): + """Process is not started, and kill() is called""" + + p = processhandler.ProcessHandler([self.python, '-V']) + self.assertRaises(RuntimeError, p.kill) + def test_process_kill(self): """Process is started, we kill it""" diff --git a/testing/mozbase/mozprocess/tests/test_mozprocess_poll.py b/testing/mozbase/mozprocess/tests/test_mozprocess_poll.py index 30a1be3f88a..94b186e7fcf 100644 --- a/testing/mozbase/mozprocess/tests/test_mozprocess_poll.py +++ b/testing/mozbase/mozprocess/tests/test_mozprocess_poll.py @@ -21,7 +21,7 @@ class ProcTestPoll(proctest.ProcTest): p = processhandler.ProcessHandler([self.python, self.proclaunch, "process_normal_finish_python.ini"], cwd=here) - self.assertRaises(AttributeError, p.poll) + self.assertRaises(RuntimeError, p.poll) def test_poll_while_running(self): """Process is started, and poll() is called""" @@ -122,5 +122,6 @@ class ProcTestPoll(proctest.ProcTest): returncode, p.didTimeout) + if __name__ == '__main__': unittest.main() diff --git a/testing/mozharness/mozharness.json b/testing/mozharness/mozharness.json index 2408f3a7dcf..8937a49a1d0 100644 --- a/testing/mozharness/mozharness.json +++ b/testing/mozharness/mozharness.json @@ -1,4 +1,4 @@ { "repo": "https://hg.mozilla.org/build/mozharness", - "revision": "75c435ef19ca" + "revision": "7b5d3fcc48c6" } diff --git a/testing/taskcluster/tasks/decision/branch.yml b/testing/taskcluster/tasks/decision/branch.yml index 62992af39b2..cf2227d709b 100644 --- a/testing/taskcluster/tasks/decision/branch.yml +++ b/testing/taskcluster/tasks/decision/branch.yml @@ -2,7 +2,7 @@ metadata: name: 'Task graph used to build {{project}} specific jobs' description: | - {{project}} push for {{owner}} with comment: {{comment}}. + {{project}} push for {{owner}} owner: mozilla-taskcluster-maintenance@mozilla.com source: "{{{source}}}" diff --git a/testing/taskcluster/tasks/decision/try.yml b/testing/taskcluster/tasks/decision/try.yml index 032ad50c717..fc310c3e34b 100644 --- a/testing/taskcluster/tasks/decision/try.yml +++ b/testing/taskcluster/tasks/decision/try.yml @@ -2,7 +2,7 @@ metadata: name: 'Taskcluster decision task for {{project}}' description: | - Try push for {{owner}} with {{comment}}. + Try push for {{owner}}. owner: mozilla-taskcluster-maintenance@mozilla.com source: "{{{source}}}" diff --git a/testing/taskcluster/tasks/test.yml b/testing/taskcluster/tasks/test.yml index 144a37c688e..5537dcf2eed 100644 --- a/testing/taskcluster/tasks/test.yml +++ b/testing/taskcluster/tasks/test.yml @@ -29,6 +29,7 @@ task: GAIA_REV: '{{{gaia_rev}}}' MOZHARNESS_REPOSITORY: '{{mozharness_repository}}' MOZHARNESS_REV: '{{mozharness_rev}}' + MOZILLA_BUILD_URL: '{{build_url}}' # All builds share a common artifact directory for ease of uploading. artifacts: diff --git a/toolkit/components/aboutmemory/tests/test_memoryReporters.xul b/toolkit/components/aboutmemory/tests/test_memoryReporters.xul index 7824404ed5e..c3d289515f2 100644 --- a/toolkit/components/aboutmemory/tests/test_memoryReporters.xul +++ b/toolkit/components/aboutmemory/tests/test_memoryReporters.xul @@ -157,6 +157,8 @@ "vsizeMaxContiguous", "resident", "residentFast", + "residentPeak", + "residentUnique", "heapAllocated", "heapOverheadRatio", "JSMainRuntimeGCHeap", diff --git a/toolkit/content/devicestorage.properties b/toolkit/content/devicestorage.properties index 083db336047..5129a585c89 100644 --- a/toolkit/content/devicestorage.properties +++ b/toolkit/content/devicestorage.properties @@ -1,4 +1,4 @@ # Extensions we recognize for DeviceStorage storage areas pictures=*.jpe; *.jpg; *.jpeg; *.gif; *.png; *.bmp; -music=*.mp3; *.oga; *.ogg; *.m4a; *.m4b; *.m4p; *.m4r; *.3gp; *.3gpp; *.mp4; *.m3u; *.pls; *.opus; *.amr; *.wav; *.lcka; *.mka; +music=*.mp3; *.oga; *.ogg; *.m4a; *.m4b; *.m4p; *.m4r; *.3gp; *.3gpp; *.mp4; *.m3u; *.pls; *.opus; *.amr; *.wav; *.lcka; *.mka; *.flac; videos=*.mp4; *.mpeg; *.mpg; *.ogv; *.ogx; *.webm; *.3gp; *.3gpp; *.3g2; *.ogg; *.m4v; *.ts; *.m2ts; *.avi; *.divx; *.mkv; diff --git a/toolkit/devtools/tern/comment.js b/toolkit/devtools/tern/comment.js old mode 100755 new mode 100644 diff --git a/toolkit/devtools/tern/condense.js b/toolkit/devtools/tern/condense.js old mode 100755 new mode 100644 diff --git a/toolkit/devtools/tern/def.js b/toolkit/devtools/tern/def.js old mode 100755 new mode 100644 diff --git a/toolkit/devtools/tern/infer.js b/toolkit/devtools/tern/infer.js old mode 100755 new mode 100644 diff --git a/toolkit/devtools/tern/signal.js b/toolkit/devtools/tern/signal.js old mode 100755 new mode 100644 diff --git a/toolkit/devtools/tern/tern.js b/toolkit/devtools/tern/tern.js old mode 100755 new mode 100644 diff --git a/toolkit/modules/AppConstants.jsm b/toolkit/modules/AppConstants.jsm index b086e462e57..0c89a3ebfc4 100644 --- a/toolkit/modules/AppConstants.jsm +++ b/toolkit/modules/AppConstants.jsm @@ -108,6 +108,13 @@ let AppConstants = Object.freeze({ false, #endif + E10S_TESTING_ONLY: +#ifdef E10S_TESTING_ONLY + true, +#else + false, +#endif + MOZ_APP_VERSION: "@MOZ_APP_VERSION@", ANDROID_PACKAGE_NAME: "@ANDROID_PACKAGE_NAME@", diff --git a/toolkit/mozapps/installer/packager.mk b/toolkit/mozapps/installer/packager.mk index ba79ce2e995..b40d9f87a6b 100644 --- a/toolkit/mozapps/installer/packager.mk +++ b/toolkit/mozapps/installer/packager.mk @@ -33,7 +33,6 @@ endif # set earlier in this file. stage-package: $(MOZ_PKG_MANIFEST) - @rm -rf $(DIST)/$(PKG_PATH)$(PKG_BASENAME).tar $(DIST)/$(PKG_PATH)$(PKG_BASENAME).dmg $@ $(EXCLUDE_LIST) OMNIJAR_NAME=$(OMNIJAR_NAME) \ $(PYTHON) $(MOZILLA_DIR)/toolkit/mozapps/installer/packager.py $(DEFINES) \ --format $(MOZ_PACKAGER_FORMAT) \ diff --git a/tools/profiler/GeckoProfiler.h b/tools/profiler/GeckoProfiler.h index 6c6c6fcf57d..9080001b6d8 100644 --- a/tools/profiler/GeckoProfiler.h +++ b/tools/profiler/GeckoProfiler.h @@ -50,6 +50,7 @@ #define SAMPLER_H #include "js/TypeDecls.h" +#include "mozilla/UniquePtr.h" namespace mozilla { class TimeStamp; @@ -170,11 +171,6 @@ static inline void profiler_save_profile_to_file(char* aFilename) { } // Returns a null terminated char* array. static inline char** profiler_get_features() { return nullptr; } -// Print the current location to the console. This functill will do it best effort -// to show the profiler's combined js/c++ if the profiler is running. Note that -// printing the location require symbolicating which is very slow. -static inline void profiler_print_location() {} - // Discard the profile, throw away the profile and notify 'profiler-locked'. // This function is to be used when entering private browsing to prevent // the profiler from collecting sensitive data. @@ -230,4 +226,28 @@ public: } }; +class ProfilerBacktrace; + +class MOZ_STACK_CLASS GeckoProfilerTracingRAII { +public: + GeckoProfilerTracingRAII(const char* aCategory, const char* aInfo, + mozilla::UniquePtr aBacktrace + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : mCategory(aCategory) + , mInfo(aInfo) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + profiler_tracing(mCategory, mInfo, aBacktrace.release(), TRACING_INTERVAL_START); + } + + ~GeckoProfilerTracingRAII() { + profiler_tracing(mCategory, mInfo, TRACING_INTERVAL_END); + } + +protected: + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER + const char* mCategory; + const char* mInfo; +}; + #endif // ifndef SAMPLER_H diff --git a/tools/profiler/GeckoProfilerImpl.h b/tools/profiler/GeckoProfilerImpl.h index eeafb0da0fe..c12b88550a4 100644 --- a/tools/profiler/GeckoProfilerImpl.h +++ b/tools/profiler/GeckoProfilerImpl.h @@ -166,16 +166,6 @@ const char** profiler_get_features() return mozilla_sampler_get_features(); } -static inline -void profiler_print_location() -{ - if (!sps_version2()) { - return mozilla_sampler_print_location1(); - } else { - return mozilla_sampler_print_location2(); - } -} - static inline void profiler_lock() { diff --git a/tools/profiler/ProfileEntry.cpp b/tools/profiler/ProfileEntry.cpp index b2b02b0357c..ebd894b4f85 100644 --- a/tools/profiler/ProfileEntry.cpp +++ b/tools/profiler/ProfileEntry.cpp @@ -11,6 +11,7 @@ // JS #include "jsapi.h" +#include "js/ProfilingFrameIterator.h" #include "js/TrackedOptimizationInfo.h" // JSON @@ -23,6 +24,10 @@ #define snprintf _snprintf #endif +using mozilla::Maybe; +using mozilla::Some; +using mozilla::Nothing; + //////////////////////////////////////////////////////////////////////// // BEGIN ProfileEntry @@ -275,7 +280,70 @@ public: } }; -void ProfileBuffer::StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JSRuntime* rt) +bool UniqueJITOptimizations::OptimizationKey::operator<(const OptimizationKey& other) const +{ + if (mEntryAddr == other.mEntryAddr) { + return mIndex < other.mIndex; + } + return mEntryAddr < other.mEntryAddr; +} + +Maybe UniqueJITOptimizations::getIndex(void* addr, JSRuntime* rt) +{ + void* entryAddr; + Maybe optIndex = JS::TrackedOptimizationIndexAtAddr(rt, addr, &entryAddr); + if (optIndex.isNothing()) { + return Nothing(); + } + + OptimizationKey key; + key.mEntryAddr = entryAddr; + key.mIndex = optIndex.value(); + + auto iter = mOptToIndexMap.find(key); + if (iter != mOptToIndexMap.end()) { + MOZ_ASSERT(iter->second < mOpts.length()); + return Some(iter->second); + } + + unsigned keyIndex = mOpts.length(); + mOptToIndexMap.insert(std::make_pair(key, keyIndex)); + MOZ_ALWAYS_TRUE(mOpts.append(key)); + return Some(keyIndex); +} + +void UniqueJITOptimizations::stream(JSStreamWriter& b, JSRuntime* rt) +{ + b.BeginArray(); + for (size_t i = 0; i < mOpts.length(); i++) { + b.BeginObject(); + b.Name("types"); + b.BeginArray(); + StreamOptimizationTypeInfoOp typeInfoOp(b); + JS::ForEachTrackedOptimizationTypeInfo(rt, mOpts[i].mEntryAddr, mOpts[i].mIndex, + typeInfoOp); + b.EndArray(); + + b.Name("attempts"); + b.BeginArray(); + JSScript *script; + jsbytecode *pc; + StreamOptimizationAttemptsOp attemptOp(b); + JS::ForEachTrackedOptimizationAttempt(rt, mOpts[i].mEntryAddr, mOpts[i].mIndex, + attemptOp, &script, &pc); + b.EndArray(); + + unsigned line, column; + line = JS_PCToLineNumber(script, pc, &column); + b.NameValue("line", line); + b.NameValue("column", column); + b.EndObject(); + } + b.EndArray(); +} + +void ProfileBuffer::StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JSRuntime* rt, + UniqueJITOptimizations &aUniqueOpts) { b.BeginArray(); @@ -406,17 +474,22 @@ void ProfileBuffer::StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JS // TODOshu: cannot stream tracked optimization info if // the JS engine has already shut down when streaming. if (rt) { - JSScript *optsScript; - jsbytecode *optsPC; - b.Name("opts"); - b.BeginArray(); - StreamOptimizationTypeInfoOp typeInfoOp(b); - JS::ForEachTrackedOptimizationTypeInfo(rt, pc, typeInfoOp); - StreamOptimizationAttemptsOp attemptOp(b); - JS::ForEachTrackedOptimizationAttempt(rt, pc, attemptOp, - &optsScript, &optsPC); - b.EndArray(); - b.NameValue("optsLine", JS_PCToLineNumber(optsScript, optsPC)); + JS::ProfilingFrameIterator::FrameKind frameKind = + JS::GetProfilingFrameKindFromNativeAddr(rt, pc); + MOZ_ASSERT(frameKind == JS::ProfilingFrameIterator::Frame_Ion || + frameKind == JS::ProfilingFrameIterator::Frame_Baseline); + const char* jitLevelString = + (frameKind == JS::ProfilingFrameIterator::Frame_Ion) ? "ion" + : "baseline"; + b.NameValue("implementation", jitLevelString); + + // Sampled JIT optimizations are deduplicated by + // aUniqueOpts to save space. Stream an index that + // references into the optimizations array. + Maybe optsIndex = aUniqueOpts.getIndex(pc, rt); + if (optsIndex.isSome()) { + b.NameValue("optsIndex", optsIndex.value()); + } } } b.EndObject(); @@ -576,7 +649,13 @@ void ThreadProfile::StreamJSObject(JSStreamWriter& b) b.NameValue("tid", static_cast(mThreadId)); b.Name("samples"); - mBuffer->StreamSamplesToJSObject(b, mThreadId, mPseudoStack->mRuntime); + UniqueJITOptimizations uniqueOpts; + mBuffer->StreamSamplesToJSObject(b, mThreadId, mPseudoStack->mRuntime, uniqueOpts); + + if (!uniqueOpts.empty()) { + b.Name("optimizations"); + uniqueOpts.stream(b, mPseudoStack->mRuntime); + } b.Name("markers"); mBuffer->StreamMarkersToJSObject(b, mThreadId); diff --git a/tools/profiler/ProfileEntry.h b/tools/profiler/ProfileEntry.h index c57799ae5c8..4b7bf967a07 100644 --- a/tools/profiler/ProfileEntry.h +++ b/tools/profiler/ProfileEntry.h @@ -7,13 +7,16 @@ #ifndef MOZ_PROFILE_ENTRY_H #define MOZ_PROFILE_ENTRY_H +#include #include #include "GeckoProfiler.h" #include "platform.h" #include "JSStreamWriter.h" #include "ProfilerBacktrace.h" #include "nsRefPtr.h" +#include "mozilla/Maybe.h" #include "mozilla/Mutex.h" +#include "mozilla/Vector.h" #include "gtest/MozGtestFriend.h" #include "mozilla/UniquePtr.h" @@ -71,6 +74,26 @@ private: typedef void (*IterateTagsCallback)(const ProfileEntry& entry, const char* tagStringData); +class UniqueJITOptimizations { + public: + bool empty() const { + return mOpts.empty(); + } + + mozilla::Maybe getIndex(void* addr, JSRuntime* rt); + void stream(JSStreamWriter& b, JSRuntime* rt); + + private: + struct OptimizationKey { + void* mEntryAddr; + uint8_t mIndex; + bool operator<(const OptimizationKey& other) const; + }; + + mozilla::Vector mOpts; + std::map mOptToIndexMap; +}; + class ProfileBuffer { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ProfileBuffer) @@ -79,7 +102,8 @@ public: void addTag(const ProfileEntry& aTag); void IterateTagsForThread(IterateTagsCallback aCallback, int aThreadId); - void StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JSRuntime* rt); + void StreamSamplesToJSObject(JSStreamWriter& b, int aThreadId, JSRuntime* rt, + UniqueJITOptimizations& aUniqueOpts); void StreamMarkersToJSObject(JSStreamWriter& b, int aThreadId); void DuplicateLastSample(int aThreadId); @@ -184,8 +208,6 @@ public: int64_t mRssMemory; int64_t mUssMemory; #endif - - void StreamTrackedOptimizations(JSStreamWriter& b, void* addr, uint8_t index); }; #endif /* ndef MOZ_PROFILE_ENTRY_H */ diff --git a/tools/profiler/TableTicker.cpp b/tools/profiler/TableTicker.cpp index 6f401ce8fc4..a64a4ec870b 100644 --- a/tools/profiler/TableTicker.cpp +++ b/tools/profiler/TableTicker.cpp @@ -565,6 +565,17 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native if (nativeIndex >= 0) nativeStackAddr = (uint8_t *) aNativeStack.sp_array[nativeIndex]; + // If there's a native stack entry which has the same SP as a + // pseudo stack entry, pretend we didn't see the native stack + // entry. Ditto for a native stack entry which has the same SP as + // a JS stack entry. In effect this means pseudo or JS entries + // trump conflicting native entries. + if (nativeStackAddr && (pseudoStackAddr == nativeStackAddr || jsStackAddr == nativeStackAddr)) { + nativeStackAddr = nullptr; + nativeIndex--; + MOZ_ASSERT(pseudoStackAddr || jsStackAddr); + } + // Sanity checks. MOZ_ASSERT_IF(pseudoStackAddr, pseudoStackAddr != jsStackAddr && pseudoStackAddr != nativeStackAddr); @@ -590,7 +601,21 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native // Stringifying optimization information is delayed until streaming // time. To re-lookup the entry in the JitcodeGlobalTable, we need to // store the JIT code address ('J') in the circular buffer. - if (jsFrames[jsIndex].hasTrackedOptimizations) { + // + // Note that we cannot do this when we are sychronously sampling the + // current thread; that is, when called from profiler_get_backtrace. The + // captured backtrace is usually externally stored for an indeterminate + // amount of time, such as in nsRefreshDriver. Problematically, the + // stored backtrace may be alive across a GC during which the profiler + // itself is disabled. In that case, the JS engine is free to discard + // its JIT code. This means that if we inserted such 'J' entries into + // the buffer, nsRefreshDriver would now be holding on to a backtrace + // with stale JIT code return addresses. + MOZ_ASSERT_IF(jsFrames[jsIndex].hasTrackedOptimizations, + jsFrames[jsIndex].kind == JS::ProfilingFrameIterator::Frame_Ion); + if (!aSample->isSamplingCurrentThread && + (jsFrames[jsIndex].kind == JS::ProfilingFrameIterator::Frame_Ion || + jsFrames[jsIndex].kind == JS::ProfilingFrameIterator::Frame_Baseline)) { aProfile.addTag(ProfileEntry('J', jsFrames[jsIndex].returnAddress)); } @@ -885,33 +910,3 @@ SyncProfile* TableTicker::GetBacktrace() return profile; } - -static void print_callback(const ProfileEntry& entry, const char* tagStringData) -{ - switch (entry.getTagName()) { - case 's': - case 'c': - printf_stderr(" %s\n", tagStringData); - } -} - -void mozilla_sampler_print_location1() -{ - if (!stack_key_initialized) - profiler_init(nullptr); - - SyncProfile* syncProfile = NewSyncProfile(); - if (!syncProfile) { - return; - } - - syncProfile->BeginUnwind(); - doSampleStackTrace(*syncProfile, nullptr, false); - syncProfile->EndUnwind(); - - printf_stderr("Backtrace:\n"); - syncProfile->IterateTags(print_callback); - delete syncProfile; -} - - diff --git a/tools/profiler/platform.cpp b/tools/profiler/platform.cpp index eb17bd5b93f..cf4d51669fb 100644 --- a/tools/profiler/platform.cpp +++ b/tools/profiler/platform.cpp @@ -48,6 +48,7 @@ static bool sIsProfiling = false; // is raced on static bool sIsGPUProfiling = false; // is raced on static bool sIsLayersDump = false; // is raced on static bool sIsDisplayListDump = false; // is raced on +static bool sIsRestyleProfiling = false; // is raced on // env variables to control the profiler const char* PROFILER_MODE = "MOZ_PROFILER_MODE"; @@ -763,6 +764,7 @@ void mozilla_sampler_start(int aProfileEntries, double aInterval, sIsGPUProfiling = t->ProfileGPU(); sIsLayersDump = t->LayersDump(); sIsDisplayListDump = t->DisplayListDump(); + sIsRestyleProfiling = t->ProfileRestyle(); if (Sampler::CanNotifyObservers()) { nsCOMPtr os = mozilla::services::GetObserverService(); @@ -835,6 +837,7 @@ void mozilla_sampler_stop() sIsGPUProfiling = false; sIsLayersDump = false; sIsDisplayListDump = false; + sIsRestyleProfiling = false; if (Sampler::CanNotifyObservers()) { nsCOMPtr os = mozilla::services::GetObserverService(); @@ -883,6 +886,10 @@ bool mozilla_sampler_feature_active(const char* aName) return sIsDisplayListDump; } + if (strcmp(aName, "restyle") == 0) { + return sIsRestyleProfiling; + } + return false; } @@ -901,11 +908,6 @@ void mozilla_sampler_frame_number(int frameNumber) sFrameNumber = frameNumber; } -void mozilla_sampler_print_location2() -{ - // FIXME -} - void mozilla_sampler_lock() { profiler_stop(); diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp index 30b067ae023..8656ce4266c 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -542,6 +542,7 @@ static nsExtraMimeTypeEntry extraMimeEntries [] = { AUDIO_OGG, "opus", "Opus Audio" }, #ifdef MOZ_WIDGET_GONK { AUDIO_AMR, "amr", "Adaptive Multi-Rate Audio" }, + { AUDIO_FLAC, "flac", "FLAC Audio" }, { VIDEO_AVI, "avi", "Audio Video Interleave" }, { VIDEO_AVI, "divx", "Audio Video Interleave" }, { VIDEO_MPEG_TS, "ts", "MPEG Transport Stream" }, diff --git a/widget/android/APZCCallbackHandler.cpp b/widget/android/APZCCallbackHandler.cpp index cd2f35783ac..0ef8d1f5e02 100644 --- a/widget/android/APZCCallbackHandler.cpp +++ b/widget/android/APZCCallbackHandler.cpp @@ -152,14 +152,6 @@ APZCCallbackHandler::HandleLongTap(const CSSPoint& aPoint, NS_LITERAL_CSTRING("Gesture:LongPress"), data)); } -void -APZCCallbackHandler::HandleLongTapUp(const CSSPoint& aPoint, - Modifiers aModifiers, - const mozilla::layers::ScrollableLayerGuid& aGuid) -{ - HandleSingleTap(aPoint, aModifiers, aGuid); -} - void APZCCallbackHandler::SendAsyncScrollDOMEvent(bool aIsRoot, const CSSRect& aContentRect, diff --git a/widget/android/APZCCallbackHandler.h b/widget/android/APZCCallbackHandler.h index faccd1487d9..1a596a96b68 100644 --- a/widget/android/APZCCallbackHandler.h +++ b/widget/android/APZCCallbackHandler.h @@ -55,8 +55,6 @@ public: // GeckoContentController methods void HandleLongTap(const mozilla::CSSPoint& aPoint, Modifiers aModifiers, const mozilla::layers::ScrollableLayerGuid& aGuid, uint64_t aInputBlockId) MOZ_OVERRIDE; - void HandleLongTapUp(const mozilla::CSSPoint& aPoint, Modifiers aModifiers, - const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE; void SendAsyncScrollDOMEvent(bool aIsRoot, const mozilla::CSSRect& aContentRect, const mozilla::CSSSize& aScrollableSize) MOZ_OVERRIDE; void PostDelayedTask(Task* aTask, int aDelayMs) MOZ_OVERRIDE; diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 2ac035b53c6..2328a452386 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -1601,10 +1601,6 @@ nsChildView::NotifyIMEInternal(const IMENotification& aIMENotification) mTextInputHandler->OnFocusChangeInGecko(true); return NS_OK; case NOTIFY_IME_OF_BLUR: - // When we're going to be deactive, we must disable the secure event input - // mode, see the Carbon Event Manager Reference. - TextInputHandler::EnsureSecureEventInputDisabled(); - NS_ENSURE_TRUE(mTextInputHandler, NS_ERROR_NOT_AVAILABLE); mTextInputHandler->OnFocusChangeInGecko(false); return NS_OK; @@ -5503,6 +5499,8 @@ static int32_t RoundUp(double aDouble) nsIWidgetListener* listener = mGeckoChild->GetWidgetListener(); if (listener) listener->WindowDeactivated(); + + TextInputHandler::EnsureSecureEventInputDisabled(); } // If the call to removeFromSuperview isn't delayed from nsChildView:: diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index 51714eaf313..8b70f93b9c2 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -2124,9 +2124,6 @@ nsCocoaWindow::NotifyIMEInternal(const IMENotification& aIMENotification) } return NS_OK; case NOTIFY_IME_OF_BLUR: - // When we're going to be deactive, we must disable the secure event input - // mode, see the Carbon Event Manager Reference. - TextInputHandler::EnsureSecureEventInputDisabled(); return NS_OK; default: return NS_ERROR_NOT_IMPLEMENTED; @@ -2401,6 +2398,8 @@ nsCocoaWindow::ExecuteNativeKeyBinding(NativeKeyBindingsType aType, if ([window isSheet]) [WindowDelegate paintMenubarForWindow:[NSApp mainWindow]]; + TextInputHandler::EnsureSecureEventInputDisabled(); + NS_OBJC_END_TRY_ABORT_BLOCK; } diff --git a/widget/windows/winrt/APZController.cpp b/widget/windows/winrt/APZController.cpp index ef72721b44e..97e79bc67e9 100644 --- a/widget/windows/winrt/APZController.cpp +++ b/widget/windows/winrt/APZController.cpp @@ -235,13 +235,6 @@ APZController::HandleLongTap(const CSSPoint& aPoint, ContentReceivedInputBlock(aInputBlockId, false); } -void -APZController::HandleLongTapUp(const CSSPoint& aPoint, - Modifiers aModifiers, - const ScrollableLayerGuid& aGuid) -{ -} - // requests that we send a mozbrowserasyncscroll domevent. not in use. void APZController::SendAsyncScrollDOMEvent(bool aIsRoot, diff --git a/widget/windows/winrt/APZController.h b/widget/windows/winrt/APZController.h index b53168d9697..8e09052a31d 100644 --- a/widget/windows/winrt/APZController.h +++ b/widget/windows/winrt/APZController.h @@ -50,9 +50,6 @@ public: Modifiers aModifiers, const mozilla::layers::ScrollableLayerGuid& aGuid, uint64_t aInputBlockId); - virtual void HandleLongTapUp(const mozilla::CSSPoint& aPoint, - Modifiers aModifiers, - const mozilla::layers::ScrollableLayerGuid& aGuid); virtual void SendAsyncScrollDOMEvent(bool aIsRoot, const mozilla::CSSRect &aContentRect, const mozilla::CSSSize &aScrollableSize); virtual void PostDelayedTask(Task* aTask, int aDelayMs); virtual bool GetRootZoomConstraints(ZoomConstraints* aOutConstraints); diff --git a/xpcom/base/nsIMemoryReporter.idl b/xpcom/base/nsIMemoryReporter.idl index 44602e03572..b89cf34fab5 100644 --- a/xpcom/base/nsIMemoryReporter.idl +++ b/xpcom/base/nsIMemoryReporter.idl @@ -205,7 +205,7 @@ interface nsIFinishReportingCallback : nsISupports void callback(in nsISupports data); }; -[scriptable, builtinclass, uuid(51e17609-e98a-47cc-9f95-095ef3c3823e)] +[scriptable, builtinclass, uuid(5e4eaa5a-4808-4b97-8005-e7cdc4d73693)] interface nsIMemoryReporterManager : nsISupports { /* @@ -344,6 +344,8 @@ interface nsIMemoryReporterManager : nsISupports * |residentFast|, and so |resident| and |residentFast| should not be used * together. * + * |residentPeak| (UNITS_BYTES) The peak resident size. + * * |residentUnique| (UNITS_BYTES) The unique set size (a.k.a. USS). * * |heapAllocated| (UNITS_BYTES) Memory mapped by the heap allocator. @@ -381,6 +383,7 @@ interface nsIMemoryReporterManager : nsISupports readonly attribute int64_t vsizeMaxContiguous; readonly attribute int64_t resident; readonly attribute int64_t residentFast; + readonly attribute int64_t residentPeak; readonly attribute int64_t residentUnique; readonly attribute int64_t heapAllocated; diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index 413e8514f27..b00c69ea5d3 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -141,7 +141,7 @@ ResidentFastDistinguishedAmount(int64_t* aN) return ResidentDistinguishedAmount(aN); } -#define HAVE_RESIDENT_UNIQUE_REPORTER +#define HAVE_RESIDENT_UNIQUE_REPORTER 1 static nsresult ResidentUniqueDistinguishedAmount(int64_t* aN) { @@ -291,7 +291,7 @@ GetKinfoVmentrySelf(int64_t* aPrss, uint64_t* aMaxreg) return NS_OK; } -#define HAVE_PRIVATE_REPORTER +#define HAVE_PRIVATE_REPORTER 1 static nsresult PrivateDistinguishedAmount(int64_t* aN) { @@ -529,7 +529,7 @@ VsizeMaxContiguousDistinguishedAmount(int64_t* aN) return NS_OK; } -#define HAVE_PRIVATE_REPORTER +#define HAVE_PRIVATE_REPORTER 1 static nsresult PrivateDistinguishedAmount(int64_t* aN) { @@ -804,6 +804,53 @@ NS_IMPL_ISUPPORTS(ResidentReporter, nsIMemoryReporter) #include +#define HAVE_RESIDENT_PEAK_REPORTER 1 + +static nsresult +ResidentPeakDistinguishedAmount(int64_t* aN) +{ + struct rusage usage; + if (0 == getrusage(RUSAGE_SELF, &usage)) { + // The units for ru_maxrrs: + // - Mac: bytes + // - Solaris: pages? But some sources it actually always returns 0, so + // check for that + // - Linux, {Net/Open/Free}BSD, DragonFly: KiB +#ifdef XP_MACOSX + *aN = usage.ru_maxrss; +#elif defined(SOLARIS) + *aN = usage.ru_maxrss * getpagesize(); +#else + *aN = usage.ru_maxrss * 1024; +#endif + if (*aN > 0) { + return NS_OK; + } + } + return NS_ERROR_FAILURE; +} + +class ResidentPeakReporter MOZ_FINAL : public nsIMemoryReporter +{ + ~ResidentPeakReporter() {} + +public: + NS_DECL_ISUPPORTS + + NS_METHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData, bool aAnonymize) MOZ_OVERRIDE + { + int64_t amount = 0; + nsresult rv = ResidentPeakDistinguishedAmount(&amount); + NS_ENSURE_SUCCESS(rv, rv); + + return MOZ_COLLECT_REPORT( + "resident-peak", KIND_OTHER, UNITS_BYTES, amount, +"The peak 'resident' value for the lifetime of the process."); + } +}; +NS_IMPL_ISUPPORTS(ResidentPeakReporter, nsIMemoryReporter) + #define HAVE_PAGE_FAULT_REPORTERS 1 class PageFaultsSoftReporter MOZ_FINAL : public nsIMemoryReporter @@ -880,7 +927,7 @@ public: }; NS_IMPL_ISUPPORTS(PageFaultsHardReporter, nsIMemoryReporter) -#endif // HAVE_PAGE_FAULT_REPORTERS +#endif // XP_UNIX /** ** memory reporter implementation for jemalloc and OSX malloc, @@ -1154,6 +1201,10 @@ nsMemoryReporterManager::Init() RegisterStrongReporter(new VsizeMaxContiguousReporter()); #endif +#ifdef HAVE_RESIDENT_PEAK_REPORTER + RegisterStrongReporter(new ResidentPeakReporter()); +#endif + #ifdef HAVE_RESIDENT_UNIQUE_REPORTER RegisterStrongReporter(new ResidentUniqueReporter()); #endif @@ -1859,6 +1910,30 @@ nsMemoryReporterManager::ResidentFast() #endif } +NS_IMETHODIMP +nsMemoryReporterManager::GetResidentPeak(int64_t* aAmount) +{ +#ifdef HAVE_RESIDENT_PEAK_REPORTER + return ResidentPeakDistinguishedAmount(aAmount); +#else + *aAmount = 0; + return NS_ERROR_NOT_AVAILABLE; +#endif +} + +/*static*/ int64_t +nsMemoryReporterManager::ResidentPeak() +{ +#ifdef HAVE_RESIDENT_PEAK_REPORTER + int64_t amount = 0; + nsresult rv = ResidentPeakDistinguishedAmount(&amount); + NS_ENSURE_SUCCESS(rv, 0); + return amount; +#else + return 0; +#endif +} + NS_IMETHODIMP nsMemoryReporterManager::GetResidentUnique(int64_t* aAmount) { diff --git a/xpcom/base/nsMemoryReporterManager.h b/xpcom/base/nsMemoryReporterManager.h index 6955defd0a9..9235e4e5e27 100644 --- a/xpcom/base/nsMemoryReporterManager.h +++ b/xpcom/base/nsMemoryReporterManager.h @@ -151,6 +151,9 @@ public: // when debugging transient memory spikes with printf instrumentation. static int64_t ResidentFast(); + // Convenience function to get peak RSS easily from other code. + static int64_t ResidentPeak(); + // Convenience function to get USS easily from other code. This is useful // when debugging unshared memory pages for forked processes. static int64_t ResidentUnique();