mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central to b2g-inbound
This commit is contained in:
commit
f3cb2827b1
@ -42,7 +42,7 @@
|
||||
<hbox id="clientBox">
|
||||
<vbox id="leftBox" flex="1"/>
|
||||
<vbox id="rightBox" flex="1">
|
||||
#expand <label id="version">__MOZ_APP_VERSION_ABOUT__</label>
|
||||
#expand <label id="version">__MOZ_APP_VERSION_DISPLAY__</label>
|
||||
<label id="distribution" class="text-blurb"/>
|
||||
<label id="distributionId" class="text-blurb"/>
|
||||
|
||||
|
@ -25,7 +25,7 @@ BROWSER_CHROME_MANIFESTS += [
|
||||
]
|
||||
|
||||
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
|
||||
DEFINES['MOZ_APP_VERSION_ABOUT'] = CONFIG['MOZ_APP_VERSION_ABOUT']
|
||||
DEFINES['MOZ_APP_VERSION_DISPLAY'] = CONFIG['MOZ_APP_VERSION_DISPLAY']
|
||||
|
||||
DEFINES['APP_LICENSE_BLOCK'] = '%s/content/overrides/app-license.html' % SRCDIR
|
||||
|
||||
|
@ -38,7 +38,7 @@ MOZ_SERVICES_METRICS=1
|
||||
MOZ_SERVICES_SYNC=1
|
||||
MOZ_SERVICES_CLOUDSYNC=1
|
||||
MOZ_APP_VERSION=$FIREFOX_VERSION
|
||||
MOZ_APP_VERSION_ABOUT=$FIREFOX_VERSION_ABOUT
|
||||
MOZ_APP_VERSION_DISPLAY=$FIREFOX_VERSION_DISPLAY
|
||||
MOZ_EXTENSIONS_DEFAULT=" gio"
|
||||
# MOZ_APP_DISPLAYNAME will be set by branding/configure.sh
|
||||
# MOZ_BRANDING_DIRECTORY is the default branding directory used when none is
|
||||
|
@ -3,11 +3,6 @@
|
||||
* 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/. */
|
||||
%endif
|
||||
%filter substitution
|
||||
%define smallSeparatorDark linear-gradient(transparent 15%, #5a6169 15%, #5a6169 85%, transparent 85%)
|
||||
%define smallSeparatorLight linear-gradient(transparent 15%, #aaa 15%, #aaa 85%, transparent 85%)
|
||||
%define solidSeparatorDark linear-gradient(#2d5b7d, #2d5b7d)
|
||||
%define solidSeparatorLight linear-gradient(#aaa, #aaa)
|
||||
|
||||
/* CSS Variables specific to the devtools toolbar that aren't defined by the themes */
|
||||
.theme-light {
|
||||
@ -554,73 +549,57 @@
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.devtools-sidebar-tabs tabs > tab {
|
||||
border-image: linear-gradient(transparent 15%, var(--theme-splitter-color) 15%, var(--theme-splitter-color) 85%, transparent 85%) 1 1;
|
||||
}
|
||||
|
||||
.devtools-sidebar-tabs tabs > tab[selected],
|
||||
.devtools-sidebar-tabs tabs > tab[selected] + tab {
|
||||
border-image: linear-gradient(var(--theme-splitter-color), var(--theme-splitter-color)) 1 1;
|
||||
}
|
||||
|
||||
.devtools-sidebar-tabs tabs > tab:first-child {
|
||||
-moz-border-start-width: 0;
|
||||
}
|
||||
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab {
|
||||
border-image: @smallSeparatorDark@ 1 1;
|
||||
}
|
||||
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab:hover {
|
||||
background: hsla(206,37%,4%,.2);
|
||||
border-image: @smallSeparatorDark@ 1 1;
|
||||
}
|
||||
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab:hover:active {
|
||||
background: hsla(206,37%,4%,.4);
|
||||
border-image: @smallSeparatorDark@ 1 1;
|
||||
}
|
||||
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab[selected] + tab {
|
||||
border-image: @solidSeparatorDark@ 1 1;
|
||||
}
|
||||
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab[selected] + tab:hover {
|
||||
background: hsla(206,37%,4%,.2);
|
||||
border-image: @solidSeparatorDark@ 1 1;
|
||||
}
|
||||
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab[selected] + tab:hover:active {
|
||||
background: hsla(206,37%,4%,.4);
|
||||
border-image: @solidSeparatorDark@ 1 1;
|
||||
}
|
||||
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab[selected],
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab[selected]:hover:active {
|
||||
color: var(--theme-selection-color);
|
||||
background: #1d4f73;
|
||||
border-image: @solidSeparatorDark@ 1 1;
|
||||
}
|
||||
|
||||
.theme-light .devtools-sidebar-tabs tabs > tab {
|
||||
border-image: @smallSeparatorLight@ 1 1;
|
||||
}
|
||||
|
||||
.theme-light .devtools-sidebar-tabs tabs > tab:hover {
|
||||
background: #ddd;
|
||||
border-image: @smallSeparatorLight@ 1 1;
|
||||
}
|
||||
|
||||
.theme-light .devtools-sidebar-tabs tabs > tab:hover:active {
|
||||
background: #ddd;
|
||||
border-image: @smallSeparatorLight@ 1 1;
|
||||
}
|
||||
|
||||
.theme-light .devtools-sidebar-tabs tabs > tab[selected] + tab {
|
||||
border-image: @solidSeparatorLight@;
|
||||
}
|
||||
|
||||
.theme-light .devtools-sidebar-tabs tabs > tab[selected] + tab:hover {
|
||||
background: #ddd;
|
||||
border-image: @solidSeparatorLight@;
|
||||
}
|
||||
|
||||
.theme-light .devtools-sidebar-tabs tabs > tab[selected],
|
||||
.theme-light .devtools-sidebar-tabs tabs > tab[selected]:hover:active {
|
||||
color: var(--theme-selection-color);
|
||||
background: #4c9ed9;
|
||||
border-image: @solidSeparatorLight@;
|
||||
}
|
||||
|
||||
/* Toolbox - moved from toolbox.css.
|
||||
|
@ -18,3 +18,10 @@ DSO_LDOPTS := -shared
|
||||
# correctly. Note that the binary produced here is a host tool and doesn't need
|
||||
# to be distributed.
|
||||
MACOSX_DEPLOYMENT_TARGET :=
|
||||
|
||||
# Temporarily relax the requirements for libstdc++ symbol versions on static
|
||||
# analysis plugin in order to use a recent clang by accepting libstdc++ from
|
||||
# gcc 4.4.0 (GLIBCXX_3.4.11).
|
||||
ifdef CHECK_STDCXX
|
||||
CHECK_STDCXX = $(call CHECK_SYMBOLS,$(1),GLIBCXX,libstdc++,v[1] > 3 || (v[1] == 3 && v[2] == 4 && v[3] > 11))
|
||||
endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
#!/usr/bin/python2.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/.
|
||||
@ -97,6 +97,8 @@ def build_one_stage_aux(stage_dir, llvm_source_dir, gcc_toolchain_dir):
|
||||
configure_opts = ["--enable-optimized",
|
||||
"--enable-targets=" + ",".join(targets),
|
||||
"--disable-assertions",
|
||||
"--disable-libedit",
|
||||
"--with-python=/usr/local/bin/python2.7",
|
||||
"--prefix=%s" % inst_dir,
|
||||
"--with-gcc-toolchain=%s" % gcc_toolchain_dir,
|
||||
"--disable-compiler-version-checks"]
|
||||
@ -115,6 +117,7 @@ if __name__ == "__main__":
|
||||
llvm_source_dir = source_dir + "/llvm"
|
||||
clang_source_dir = source_dir + "/clang"
|
||||
compiler_rt_source_dir = source_dir + "/compiler-rt"
|
||||
libcxx_source_dir = source_dir + "/libcxx"
|
||||
|
||||
gcc_dir = "/tools/gcc-4.7.3-0moz1"
|
||||
|
||||
@ -132,15 +135,19 @@ if __name__ == "__main__":
|
||||
llvm_repo = config["llvm_repo"]
|
||||
clang_repo = config["clang_repo"]
|
||||
compiler_repo = config["compiler_repo"]
|
||||
libcxx_repo = config["libcxx_repo"]
|
||||
|
||||
if not os.path.exists(source_dir):
|
||||
os.makedirs(source_dir)
|
||||
svn_co(llvm_repo, llvm_source_dir, llvm_revision)
|
||||
svn_co(clang_repo, clang_source_dir, llvm_revision)
|
||||
svn_co(compiler_repo, compiler_rt_source_dir, llvm_revision)
|
||||
svn_co(libcxx_repo, libcxx_source_dir, llvm_revision)
|
||||
os.symlink("../../clang", llvm_source_dir + "/tools/clang")
|
||||
os.symlink("../../compiler-rt",
|
||||
llvm_source_dir + "/projects/compiler-rt")
|
||||
os.symlink("../../libcxx",
|
||||
llvm_source_dir + "/projects/libcxx")
|
||||
for p in config.get("patches", {}).get(get_platform(), []):
|
||||
patch(p, source_dir)
|
||||
|
||||
@ -153,12 +160,16 @@ if __name__ == "__main__":
|
||||
|
||||
if is_darwin():
|
||||
extra_cflags = ""
|
||||
extra_cxxflags = ""
|
||||
extra_cxxflags = "-stdlib=libc++"
|
||||
extra_cflags2 = ""
|
||||
extra_cxxflags2 = "-stdlib=libc++"
|
||||
cc = "/usr/bin/clang"
|
||||
cxx = "/usr/bin/clang++"
|
||||
else:
|
||||
extra_cflags = "-static-libgcc"
|
||||
extra_cxxflags = "-static-libgcc -static-libstdc++"
|
||||
extra_cflags = ""
|
||||
extra_cxxflags = ""
|
||||
extra_cflags2 = "-static-libgcc"
|
||||
extra_cxxflags2 = "-static-libgcc -static-libstdc++"
|
||||
cc = gcc_dir + "/bin/gcc"
|
||||
cxx = gcc_dir + "/bin/g++"
|
||||
|
||||
@ -167,12 +178,15 @@ if __name__ == "__main__":
|
||||
else:
|
||||
os.environ['LD_LIBRARY_PATH'] = '%s/lib64/' % gcc_dir
|
||||
|
||||
build_one_stage({"CC": cc, "CXX": cxx}, stage1_dir, llvm_source_dir, gcc_dir)
|
||||
build_one_stage(
|
||||
{"CC": cc + " %s" % extra_cflags,
|
||||
"CXX": cxx + " %s" % extra_cxxflags},
|
||||
stage1_dir, llvm_source_dir, gcc_dir)
|
||||
|
||||
stage2_dir = build_dir + '/stage2'
|
||||
build_one_stage(
|
||||
{"CC": stage1_inst_dir + "/bin/clang %s" % extra_cflags,
|
||||
"CXX": stage1_inst_dir + "/bin/clang++ %s" % extra_cxxflags},
|
||||
{"CC": stage1_inst_dir + "/bin/clang %s" % extra_cflags2,
|
||||
"CXX": stage1_inst_dir + "/bin/clang++ %s" % extra_cxxflags2},
|
||||
stage2_dir, llvm_source_dir, gcc_dir)
|
||||
|
||||
build_tar_package("tar", "clang.tar.bz2", stage2_dir, "clang")
|
||||
|
@ -1,11 +1,12 @@
|
||||
{
|
||||
"llvm_revision": "200213",
|
||||
"llvm_revision": "241406",
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/trunk",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk",
|
||||
"patches": {
|
||||
"macosx64": ["llvm-debug-frame.patch"],
|
||||
"linux64": ["llvm-debug-frame.patch", "no-sse-on-linux-trunk.patch"],
|
||||
"linux32": ["llvm-debug-frame.patch", "no-sse-on-linux-trunk.patch"]
|
||||
"linux64": ["llvm-debug-frame.patch"],
|
||||
"linux32": ["llvm-debug-frame.patch"]
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
|
||||
index d6d4510..c488d4a 100644
|
||||
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
|
||||
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
|
||||
@@ -172,6 +172,8 @@ bool AsmPrinter::doInitialization(Module &M) {
|
||||
OutStreamer.EmitFileDirective(M.getModuleIdentifier());
|
||||
Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp
|
||||
===================================================================
|
||||
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (revision 226419)
|
||||
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (working copy)
|
||||
@@ -210,6 +210,8 @@
|
||||
OutStreamer->EmitFileDirective(M.getModuleIdentifier());
|
||||
}
|
||||
|
||||
+ OutStreamer.EmitCFISections(true, true);
|
||||
|
||||
+ OutStreamer->EmitCFISections(true, true);
|
||||
+
|
||||
GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
|
||||
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
|
||||
for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I)
|
||||
for (auto &I : *MI)
|
||||
|
@ -1,13 +0,0 @@
|
||||
Index: lib/Driver/Tools.cpp
|
||||
===================================================================
|
||||
--- a/clang/lib/Driver/Tools.cpp (revision 199443)
|
||||
+++ b/clang/lib/Driver/Tools.cpp (working copy)
|
||||
@@ -1226,7 +1226,7 @@
|
||||
// All x86 devices running Android have core2 as their common
|
||||
// denominator. This makes a better choice than pentium4.
|
||||
if (Triple.getEnvironment() == llvm::Triple::Android)
|
||||
- return "core2";
|
||||
+ return "686";
|
||||
|
||||
// Everything else goes to x86-64 in 64-bit mode.
|
||||
if (Is64Bit)
|
@ -311,7 +311,7 @@ CONFIG_STATUS_DEPS := \
|
||||
$(TOPSRCDIR)/nsprpub/configure \
|
||||
$(TOPSRCDIR)/config/milestone.txt \
|
||||
$(TOPSRCDIR)/browser/config/version.txt \
|
||||
$(TOPSRCDIR)/browser/config/version_about.txt \
|
||||
$(TOPSRCDIR)/browser/config/version_display.txt \
|
||||
$(TOPSRCDIR)/build/virtualenv_packages.txt \
|
||||
$(TOPSRCDIR)/python/mozbuild/mozbuild/virtualenv.py \
|
||||
$(TOPSRCDIR)/testing/mozbase/packages.txt \
|
||||
|
14
configure.in
14
configure.in
@ -1959,14 +1959,14 @@ MOZILLA_SYMBOLVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --t
|
||||
|
||||
dnl Get version of various core apps from the version files.
|
||||
FIREFOX_VERSION=`cat $_topsrcdir/browser/config/version.txt`
|
||||
FIREFOX_VERSION_ABOUT=`cat $_topsrcdir/browser/config/version_about.txt`
|
||||
FIREFOX_VERSION_DISPLAY=`cat $_topsrcdir/browser/config/version_display.txt`
|
||||
|
||||
if test -z "$FIREFOX_VERSION"; then
|
||||
AC_MSG_ERROR([FIREFOX_VERSION is unexpectedly blank.])
|
||||
fi
|
||||
|
||||
if test -z "$FIREFOX_VERSION_ABOUT"; then
|
||||
AC_MSG_ERROR([FIREFOX_VERSION_ABOUT is unexpectedly blank.])
|
||||
if test -z "$FIREFOX_VERSION_DISPLAY"; then
|
||||
AC_MSG_ERROR([FIREFOX_VERSION_DISPLAY is unexpectedly blank.])
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(MOZILLA_VERSION,"$MOZILLA_VERSION")
|
||||
@ -8760,7 +8760,7 @@ AC_SUBST(MOZ_CHILD_PROCESS_BUNDLE)
|
||||
# Mac Bundle name, Updater, Installer), it is typically used for nightly
|
||||
# builds (e.g. Aurora for Firefox).
|
||||
# - MOZ_APP_VERSION: Defines the application version number.
|
||||
# - MOZ_APP_VERSION_ABOUT: Defines the application version number. Used
|
||||
# - MOZ_APP_VERSION_DISPLAY: Defines the application version number. Used
|
||||
# in the "About" window. If not set, defaults to MOZ_APP_VERSION.
|
||||
# - MOZ_APP_NAME: Used for e.g. the binary program file name. If not set,
|
||||
# defaults to a lowercase form of MOZ_APP_BASENAME.
|
||||
@ -8780,8 +8780,8 @@ if test -z "$MOZ_APP_REMOTINGNAME"; then
|
||||
MOZ_APP_REMOTINGNAME=$MOZ_APP_NAME
|
||||
fi
|
||||
|
||||
if test -z "$MOZ_APP_VERSION_ABOUT"; then
|
||||
MOZ_APP_VERSION_ABOUT=$MOZ_APP_VERSION
|
||||
if test -z "$MOZ_APP_VERSION_DISPLAY"; then
|
||||
MOZ_APP_VERSION_DISPLAY=$MOZ_APP_VERSION
|
||||
fi
|
||||
|
||||
# For extensions and langpacks, we require a max version that is compatible
|
||||
@ -8820,7 +8820,7 @@ AC_DEFINE_UNQUOTED(MOZ_APP_UA_NAME, "$MOZ_APP_UA_NAME")
|
||||
AC_SUBST(MOZ_APP_UA_NAME)
|
||||
AC_DEFINE_UNQUOTED(MOZ_APP_UA_VERSION, "$MOZ_APP_VERSION")
|
||||
AC_SUBST(MOZ_APP_VERSION)
|
||||
AC_SUBST(MOZ_APP_VERSION_ABOUT)
|
||||
AC_SUBST(MOZ_APP_VERSION_DISPLAY)
|
||||
AC_SUBST(MOZ_APP_MAXVERSION)
|
||||
AC_DEFINE_UNQUOTED(FIREFOX_VERSION,$FIREFOX_VERSION)
|
||||
AC_SUBST(FIREFOX_VERSION)
|
||||
|
@ -3217,11 +3217,6 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
|
||||
mLoadedDataFired = false;
|
||||
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
|
||||
|
||||
if (mIsEncrypted) {
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
obs->NotifyObservers(static_cast<nsIContent*>(this), "media-eme-metadataloaded", nullptr);
|
||||
}
|
||||
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
|
||||
if (IsVideo() && HasVideo()) {
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("resize"));
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "VideoSegment.h"
|
||||
#include "MediaQueue.h"
|
||||
#include "MediaData.h"
|
||||
#include "MediaInfo.h"
|
||||
#include "SharedBuffer.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
@ -185,13 +184,32 @@ OutputStreamData::Init(DecodedStream* aDecodedStream, ProcessedMediaStream* aStr
|
||||
aStream->AddListener(mListener);
|
||||
}
|
||||
|
||||
DecodedStream::DecodedStream()
|
||||
DecodedStream::DecodedStream(MediaQueue<AudioData>& aAudioQueue,
|
||||
MediaQueue<VideoData>& aVideoQueue)
|
||||
: mMonitor("DecodedStream::mMonitor")
|
||||
, mPlaying(false)
|
||||
, mAudioQueue(aAudioQueue)
|
||||
, mVideoQueue(aVideoQueue)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::StartPlayback(int64_t aStartTime, const MediaInfo& aInfo)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
if (mStartTime.isNothing()) {
|
||||
mStartTime.emplace(aStartTime);
|
||||
mInfo = aInfo;
|
||||
}
|
||||
}
|
||||
|
||||
void DecodedStream::StopPlayback()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
mStartTime.reset();
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::DestroyData()
|
||||
{
|
||||
@ -343,38 +361,8 @@ DecodedStream::SetPlaying(bool aPlaying)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DecodedStream::HaveEnoughAudio(const MediaInfo& aInfo) const
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
|
||||
if (mData->mStreamInitialized && !mData->mHaveSentFinishAudio) {
|
||||
MOZ_ASSERT(aInfo.HasAudio());
|
||||
TrackID audioTrackId = aInfo.mAudio.mTrackId;
|
||||
if (!mData->mStream->HaveEnoughBuffered(audioTrackId)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DecodedStream::HaveEnoughVideo(const MediaInfo& aInfo) const
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
|
||||
if (mData->mStreamInitialized && !mData->mHaveSentFinishVideo) {
|
||||
MOZ_ASSERT(aInfo.HasVideo());
|
||||
TrackID videoTrackId = aInfo.mVideo.mTrackId;
|
||||
if (!mData->mStream->HaveEnoughBuffered(videoTrackId)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::InitTracks(int64_t aStartTime, const MediaInfo& aInfo)
|
||||
DecodedStream::InitTracks()
|
||||
{
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
|
||||
@ -384,20 +372,20 @@ DecodedStream::InitTracks(int64_t aStartTime, const MediaInfo& aInfo)
|
||||
|
||||
SourceMediaStream* sourceStream = mData->mStream;
|
||||
|
||||
if (aInfo.HasAudio()) {
|
||||
TrackID audioTrackId = aInfo.mAudio.mTrackId;
|
||||
if (mInfo.HasAudio()) {
|
||||
TrackID audioTrackId = mInfo.mAudio.mTrackId;
|
||||
AudioSegment* audio = new AudioSegment();
|
||||
sourceStream->AddAudioTrack(audioTrackId, aInfo.mAudio.mRate, 0, audio,
|
||||
sourceStream->AddAudioTrack(audioTrackId, mInfo.mAudio.mRate, 0, audio,
|
||||
SourceMediaStream::ADDTRACK_QUEUED);
|
||||
mData->mNextAudioTime = aStartTime;
|
||||
mData->mNextAudioTime = mStartTime.ref();
|
||||
}
|
||||
|
||||
if (aInfo.HasVideo()) {
|
||||
TrackID videoTrackId = aInfo.mVideo.mTrackId;
|
||||
if (mInfo.HasVideo()) {
|
||||
TrackID videoTrackId = mInfo.mVideo.mTrackId;
|
||||
VideoSegment* video = new VideoSegment();
|
||||
sourceStream->AddTrack(videoTrackId, 0, video,
|
||||
SourceMediaStream::ADDTRACK_QUEUED);
|
||||
mData->mNextVideoTime = aStartTime;
|
||||
mData->mNextVideoTime = mStartTime.ref();
|
||||
}
|
||||
|
||||
sourceStream->FinishAddTracks();
|
||||
@ -452,28 +440,25 @@ SendStreamAudio(DecodedStreamData* aStream, int64_t aStartTime,
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::SendAudio(int64_t aStartTime,
|
||||
const MediaInfo& aInfo,
|
||||
MediaQueue<AudioData>& aQueue,
|
||||
double aVolume, bool aIsSameOrigin)
|
||||
DecodedStream::SendAudio(double aVolume, bool aIsSameOrigin)
|
||||
{
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
|
||||
if (!aInfo.HasAudio()) {
|
||||
if (!mInfo.HasAudio()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AudioSegment output;
|
||||
uint32_t rate = aInfo.mAudio.mRate;
|
||||
uint32_t rate = mInfo.mAudio.mRate;
|
||||
nsAutoTArray<nsRefPtr<AudioData>,10> audio;
|
||||
TrackID audioTrackId = aInfo.mAudio.mTrackId;
|
||||
TrackID audioTrackId = mInfo.mAudio.mTrackId;
|
||||
SourceMediaStream* sourceStream = mData->mStream;
|
||||
|
||||
// It's OK to hold references to the AudioData because AudioData
|
||||
// is ref-counted.
|
||||
aQueue.GetElementsAfter(mData->mNextAudioTime, &audio);
|
||||
mAudioQueue.GetElementsAfter(mData->mNextAudioTime, &audio);
|
||||
for (uint32_t i = 0; i < audio.Length(); ++i) {
|
||||
SendStreamAudio(mData.get(), aStartTime, audio[i], &output, rate, aVolume);
|
||||
SendStreamAudio(mData.get(), mStartTime.ref(), audio[i], &output, rate, aVolume);
|
||||
}
|
||||
|
||||
if (!aIsSameOrigin) {
|
||||
@ -487,7 +472,7 @@ DecodedStream::SendAudio(int64_t aStartTime,
|
||||
sourceStream->AppendToTrack(audioTrackId, &output);
|
||||
}
|
||||
|
||||
if (aQueue.IsFinished() && !mData->mHaveSentFinishAudio) {
|
||||
if (mAudioQueue.IsFinished() && !mData->mHaveSentFinishAudio) {
|
||||
sourceStream->EndTrack(audioTrackId);
|
||||
mData->mHaveSentFinishAudio = true;
|
||||
}
|
||||
@ -520,25 +505,22 @@ ZeroDurationAtLastChunk(VideoSegment& aInput)
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::SendVideo(int64_t aStartTime,
|
||||
const MediaInfo& aInfo,
|
||||
MediaQueue<VideoData>& aQueue,
|
||||
bool aIsSameOrigin)
|
||||
DecodedStream::SendVideo(bool aIsSameOrigin)
|
||||
{
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
|
||||
if (!aInfo.HasVideo()) {
|
||||
if (!mInfo.HasVideo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
VideoSegment output;
|
||||
TrackID videoTrackId = aInfo.mVideo.mTrackId;
|
||||
TrackID videoTrackId = mInfo.mVideo.mTrackId;
|
||||
nsAutoTArray<nsRefPtr<VideoData>, 10> video;
|
||||
SourceMediaStream* sourceStream = mData->mStream;
|
||||
|
||||
// It's OK to hold references to the VideoData because VideoData
|
||||
// is ref-counted.
|
||||
aQueue.GetElementsAfter(mData->mNextVideoTime, &video);
|
||||
mVideoQueue.GetElementsAfter(mData->mNextVideoTime, &video);
|
||||
|
||||
for (uint32_t i = 0; i < video.Length(); ++i) {
|
||||
VideoData* v = video[i];
|
||||
@ -580,7 +562,7 @@ DecodedStream::SendVideo(int64_t aStartTime,
|
||||
sourceStream->AppendToTrack(videoTrackId, &output);
|
||||
}
|
||||
|
||||
if (aQueue.IsFinished() && !mData->mHaveSentFinishVideo) {
|
||||
if (mVideoQueue.IsFinished() && !mData->mHaveSentFinishVideo) {
|
||||
if (mData->mEOSVideoCompensation) {
|
||||
VideoSegment endSegment;
|
||||
// Calculate the deviation clock time from DecodedStream.
|
||||
@ -601,21 +583,21 @@ DecodedStream::SendVideo(int64_t aStartTime,
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::AdvanceTracks(int64_t aStartTime, const MediaInfo& aInfo)
|
||||
DecodedStream::AdvanceTracks()
|
||||
{
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
|
||||
StreamTime endPosition = 0;
|
||||
|
||||
if (aInfo.HasAudio()) {
|
||||
if (mInfo.HasAudio()) {
|
||||
StreamTime audioEnd = mData->mStream->TicksToTimeRoundDown(
|
||||
aInfo.mAudio.mRate, mData->mAudioFramesWritten);
|
||||
mInfo.mAudio.mRate, mData->mAudioFramesWritten);
|
||||
endPosition = std::max(endPosition, audioEnd);
|
||||
}
|
||||
|
||||
if (aInfo.HasVideo()) {
|
||||
if (mInfo.HasVideo()) {
|
||||
StreamTime videoEnd = mData->mStream->MicrosecondsToStreamTimeRoundDown(
|
||||
mData->mNextVideoTime - aStartTime);
|
||||
mData->mNextVideoTime - mStartTime.ref());
|
||||
endPosition = std::max(endPosition, videoEnd);
|
||||
}
|
||||
|
||||
@ -625,21 +607,18 @@ DecodedStream::AdvanceTracks(int64_t aStartTime, const MediaInfo& aInfo)
|
||||
}
|
||||
|
||||
bool
|
||||
DecodedStream::SendData(int64_t aStartTime,
|
||||
const MediaInfo& aInfo,
|
||||
MediaQueue<AudioData>& aAudioQueue,
|
||||
MediaQueue<VideoData>& aVideoQueue,
|
||||
double aVolume, bool aIsSameOrigin)
|
||||
DecodedStream::SendData(double aVolume, bool aIsSameOrigin)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
MOZ_ASSERT(mStartTime.isSome(), "Must be called after StartPlayback()");
|
||||
|
||||
InitTracks(aStartTime, aInfo);
|
||||
SendAudio(aStartTime, aInfo, aAudioQueue, aVolume, aIsSameOrigin);
|
||||
SendVideo(aStartTime, aInfo, aVideoQueue, aIsSameOrigin);
|
||||
AdvanceTracks(aStartTime, aInfo);
|
||||
InitTracks();
|
||||
SendAudio(aVolume, aIsSameOrigin);
|
||||
SendVideo(aIsSameOrigin);
|
||||
AdvanceTracks();
|
||||
|
||||
bool finished = (!aInfo.HasAudio() || aAudioQueue.IsFinished()) &&
|
||||
(!aInfo.HasVideo() || aVideoQueue.IsFinished());
|
||||
bool finished = (!mInfo.HasAudio() || mAudioQueue.IsFinished()) &&
|
||||
(!mInfo.HasVideo() || mVideoQueue.IsFinished());
|
||||
|
||||
if (finished && !mData->mHaveSentFinish) {
|
||||
mData->mHaveSentFinish = true;
|
||||
@ -650,17 +629,22 @@ DecodedStream::SendData(int64_t aStartTime,
|
||||
}
|
||||
|
||||
CheckedInt64
|
||||
DecodedStream::AudioEndTime(int64_t aStartTime, uint32_t aRate) const
|
||||
DecodedStream::AudioEndTime() const
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
return aStartTime + FramesToUsecs(mData->mAudioFramesWritten, aRate);
|
||||
MOZ_ASSERT(mStartTime.isSome(), "Must be called after StartPlayback()");
|
||||
return mStartTime.ref() +
|
||||
FramesToUsecs(mData->mAudioFramesWritten, mInfo.mAudio.mRate);
|
||||
}
|
||||
|
||||
int64_t
|
||||
DecodedStream::GetPosition() const
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
return mData->GetPosition();
|
||||
// This is only called after MDSM starts playback. So mStartTime is
|
||||
// guaranteed to be something.
|
||||
MOZ_ASSERT(mStartTime.isSome());
|
||||
return mStartTime.ref() + mData->GetPosition();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -9,17 +9,18 @@
|
||||
|
||||
#include "nsRefPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "MediaInfo.h"
|
||||
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/gfx/Point.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class AudioData;
|
||||
class VideoData;
|
||||
class MediaInfo;
|
||||
class AudioSegment;
|
||||
class MediaStream;
|
||||
class MediaInputPort;
|
||||
@ -96,24 +97,26 @@ public:
|
||||
class DecodedStream {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DecodedStream);
|
||||
public:
|
||||
DecodedStream();
|
||||
DecodedStream(MediaQueue<AudioData>& aAudioQueue,
|
||||
MediaQueue<VideoData>& aVideoQueue);
|
||||
|
||||
// Mimic MDSM::StartAudioThread.
|
||||
// Must be called before any calls to SendData().
|
||||
void StartPlayback(int64_t aStartTime, const MediaInfo& aInfo);
|
||||
// Mimic MDSM::StopAudioThread.
|
||||
void StopPlayback();
|
||||
|
||||
void DestroyData();
|
||||
void RecreateData();
|
||||
void Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
|
||||
void Remove(MediaStream* aStream);
|
||||
void SetPlaying(bool aPlaying);
|
||||
bool HaveEnoughAudio(const MediaInfo& aInfo) const;
|
||||
bool HaveEnoughVideo(const MediaInfo& aInfo) const;
|
||||
CheckedInt64 AudioEndTime(int64_t aStartTime, uint32_t aRate) const;
|
||||
CheckedInt64 AudioEndTime() const;
|
||||
int64_t GetPosition() const;
|
||||
bool IsFinished() const;
|
||||
|
||||
// Return true if stream is finished.
|
||||
bool SendData(int64_t aStartTime,
|
||||
const MediaInfo& aInfo,
|
||||
MediaQueue<AudioData>& aAudioQueue,
|
||||
MediaQueue<VideoData>& aVideoQueue,
|
||||
double aVolume, bool aIsSameOrigin);
|
||||
bool SendData(double aVolume, bool aIsSameOrigin);
|
||||
|
||||
protected:
|
||||
virtual ~DecodedStream() {}
|
||||
@ -123,18 +126,10 @@ private:
|
||||
void RecreateData(MediaStreamGraph* aGraph);
|
||||
void Connect(OutputStreamData* aStream);
|
||||
nsTArray<OutputStreamData>& OutputStreams();
|
||||
void InitTracks(int64_t aStartTime, const MediaInfo& aInfo);
|
||||
void AdvanceTracks(int64_t aStartTime, const MediaInfo& aInfo);
|
||||
|
||||
void SendAudio(int64_t aStartTime,
|
||||
const MediaInfo& aInfo,
|
||||
MediaQueue<AudioData>& aQueue,
|
||||
double aVolume, bool aIsSameOrigin);
|
||||
|
||||
void SendVideo(int64_t aStartTime,
|
||||
const MediaInfo& aInfo,
|
||||
MediaQueue<VideoData>& aQueue,
|
||||
bool aIsSameOrigin);
|
||||
void InitTracks();
|
||||
void AdvanceTracks();
|
||||
void SendAudio(double aVolume, bool aIsSameOrigin);
|
||||
void SendVideo(bool aIsSameOrigin);
|
||||
|
||||
UniquePtr<DecodedStreamData> mData;
|
||||
// Data about MediaStreams that are being fed by the decoder.
|
||||
@ -150,6 +145,11 @@ private:
|
||||
mutable ReentrantMonitor mMonitor;
|
||||
|
||||
bool mPlaying;
|
||||
Maybe<int64_t> mStartTime;
|
||||
MediaInfo mInfo;
|
||||
|
||||
MediaQueue<AudioData>& mAudioQueue;
|
||||
MediaQueue<VideoData>& mVideoQueue;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -159,6 +159,19 @@ void MediaDecoder::NotifyOwnerActivityChanged()
|
||||
StartDormantTimer();
|
||||
}
|
||||
|
||||
bool
|
||||
MediaDecoder::IsHeuristicDormantSupported() const
|
||||
{
|
||||
return
|
||||
#if defined(MOZ_EME) && defined(RELEASE_BUILD)
|
||||
// We disallow dormant for encrypted media on Beta and Release until
|
||||
// bug 1181864 is fixed.
|
||||
mInfo &&
|
||||
!mInfo->IsEncrypted() &&
|
||||
#endif
|
||||
mIsHeuristicDormantSupported;
|
||||
}
|
||||
|
||||
void MediaDecoder::UpdateDormantState(bool aDormantTimeout, bool aActivity)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -174,9 +187,11 @@ void MediaDecoder::UpdateDormantState(bool aDormantTimeout, bool aActivity)
|
||||
}
|
||||
|
||||
DECODER_LOG("UpdateDormantState aTimeout=%d aActivity=%d mIsDormant=%d "
|
||||
"ownerActive=%d ownerHidden=%d mIsHeuristicDormant=%d mPlayState=%s",
|
||||
"ownerActive=%d ownerHidden=%d mIsHeuristicDormant=%d "
|
||||
"mPlayState=%s encrypted=%s",
|
||||
aDormantTimeout, aActivity, mIsDormant, mOwner->IsActive(),
|
||||
mOwner->IsHidden(), mIsHeuristicDormant, PlayStateStr());
|
||||
mOwner->IsHidden(), mIsHeuristicDormant, PlayStateStr(),
|
||||
(!mInfo ? "Unknown" : (mInfo->IsEncrypted() ? "1" : "0")));
|
||||
|
||||
bool prevDormant = mIsDormant;
|
||||
mIsDormant = false;
|
||||
@ -188,10 +203,11 @@ void MediaDecoder::UpdateDormantState(bool aDormantTimeout, bool aActivity)
|
||||
mIsDormant = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Try to enable dormant by idle heuristic, when the owner is hidden.
|
||||
bool prevHeuristicDormant = mIsHeuristicDormant;
|
||||
mIsHeuristicDormant = false;
|
||||
if (mIsHeuristicDormantSupported && mOwner->IsHidden()) {
|
||||
if (IsHeuristicDormantSupported() && mOwner->IsHidden()) {
|
||||
if (aDormantTimeout && !aActivity &&
|
||||
(mPlayState == PLAY_STATE_PAUSED || IsEnded())) {
|
||||
// Enable heuristic dormant
|
||||
@ -252,7 +268,7 @@ void MediaDecoder::DormantTimerExpired(nsITimer* aTimer, void* aClosure)
|
||||
void MediaDecoder::StartDormantTimer()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!mIsHeuristicDormantSupported) {
|
||||
if (!IsHeuristicDormantSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1057,6 +1057,9 @@ protected:
|
||||
|
||||
virtual void CallSeek(const SeekTarget& aTarget);
|
||||
|
||||
// Returns true if heuristic dormant is supported.
|
||||
bool IsHeuristicDormantSupported() const;
|
||||
|
||||
MediaPromiseRequestHolder<SeekPromise> mSeekRequest;
|
||||
|
||||
// True when seeking or otherwise moving the play position around in
|
||||
|
@ -212,7 +212,6 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
||||
mFragmentEndTime(-1),
|
||||
mReader(aReader),
|
||||
mCurrentPosition(mTaskQueue, 0, "MediaDecoderStateMachine::mCurrentPosition (Canonical)"),
|
||||
mStreamStartTime(0),
|
||||
mAudioEndTime(-1),
|
||||
mDecodedAudioEndTime(-1),
|
||||
mVideoFrameEndTime(-1),
|
||||
@ -244,7 +243,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
||||
mSentLoadedMetadataEvent(false),
|
||||
mSentFirstFrameLoadedEvent(false),
|
||||
mSentPlaybackEndedEvent(false),
|
||||
mDecodedStream(new DecodedStream())
|
||||
mDecodedStream(new DecodedStream(mAudioQueue, mVideoQueue))
|
||||
{
|
||||
MOZ_COUNT_CTOR(MediaDecoderStateMachine);
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
@ -371,13 +370,10 @@ void MediaDecoderStateMachine::SendStreamData()
|
||||
AssertCurrentThreadInMonitor();
|
||||
MOZ_ASSERT(!mAudioSink, "Should've been stopped in RunStateMachine()");
|
||||
|
||||
bool finished = mDecodedStream->SendData(
|
||||
mStreamStartTime, mInfo, AudioQueue(), VideoQueue(),
|
||||
mVolume, mDecoder->IsSameOriginMedia());
|
||||
bool finished = mDecodedStream->SendData(mVolume, mDecoder->IsSameOriginMedia());
|
||||
|
||||
if (mInfo.HasAudio()) {
|
||||
CheckedInt64 playedUsecs = mDecodedStream->AudioEndTime(
|
||||
mStreamStartTime, mInfo.mAudio.mRate);
|
||||
CheckedInt64 playedUsecs = mDecodedStream->AudioEndTime();
|
||||
if (playedUsecs.isValid()) {
|
||||
OnAudioEndTimeUpdate(playedUsecs.value());
|
||||
}
|
||||
@ -414,7 +410,10 @@ bool MediaDecoderStateMachine::HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs)
|
||||
return false;
|
||||
}
|
||||
|
||||
return !mAudioCaptured || mDecodedStream->HaveEnoughAudio(mInfo);
|
||||
// We don't have to check SourceMediaStream::HaveEnoughBuffered() in the
|
||||
// case of stream-capture for MDSM will ensure buffering level is high enough
|
||||
// for playback speed at 1x at which the DecodedStream is playing.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MediaDecoderStateMachine::HaveEnoughDecodedVideo()
|
||||
@ -426,7 +425,7 @@ bool MediaDecoderStateMachine::HaveEnoughDecodedVideo()
|
||||
return false;
|
||||
}
|
||||
|
||||
return !mAudioCaptured || mDecodedStream->HaveEnoughVideo(mInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1092,6 +1091,12 @@ void MediaDecoderStateMachine::MaybeStartPlayback()
|
||||
nsresult rv = StartAudioThread();
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
// Tell DecodedStream to start playback with specified start time and media
|
||||
// info. This is consistent with how we create AudioSink in StartAudioThread().
|
||||
if (mAudioCaptured) {
|
||||
mDecodedStream->StartPlayback(GetMediaTime(), mInfo);
|
||||
}
|
||||
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
DispatchDecodeTasksIfNeeded();
|
||||
}
|
||||
@ -2144,7 +2149,6 @@ MediaDecoderStateMachine::SeekCompleted()
|
||||
} else {
|
||||
newCurrentTime = video ? video->mTime : seekTime;
|
||||
}
|
||||
mStreamStartTime = newCurrentTime;
|
||||
mPlayDuration = newCurrentTime;
|
||||
|
||||
mDecoder->StartProgressUpdates();
|
||||
@ -2419,6 +2423,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
||||
}
|
||||
|
||||
StopAudioThread();
|
||||
mDecodedStream->StopPlayback();
|
||||
|
||||
if (mPlayState == MediaDecoder::PLAY_STATE_PLAYING &&
|
||||
!mSentPlaybackEndedEvent)
|
||||
@ -2460,10 +2465,10 @@ MediaDecoderStateMachine::Reset()
|
||||
// outside of the decoder monitor while we are clearing the queue and causes
|
||||
// crash for no samples to be popped.
|
||||
StopAudioThread();
|
||||
mDecodedStream->StopPlayback();
|
||||
|
||||
mVideoFrameEndTime = -1;
|
||||
mDecodedVideoEndTime = -1;
|
||||
mStreamStartTime = 0;
|
||||
mAudioEndTime = -1;
|
||||
mDecodedAudioEndTime = -1;
|
||||
mAudioCompleted = false;
|
||||
@ -2600,7 +2605,7 @@ int64_t MediaDecoderStateMachine::GetStreamClock() const
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
return mStreamStartTime + mDecodedStream->GetPosition();
|
||||
return mDecodedStream->GetPosition();
|
||||
}
|
||||
|
||||
int64_t MediaDecoderStateMachine::GetVideoStreamPosition(TimeStamp aTimeStamp) const
|
||||
@ -3134,11 +3139,15 @@ void MediaDecoderStateMachine::DispatchAudioCaptured()
|
||||
if (!self->mAudioCaptured) {
|
||||
// Stop the audio sink if it's running.
|
||||
self->StopAudioThread();
|
||||
self->mStreamStartTime = self->GetMediaTime();
|
||||
// Reset mAudioEndTime which will be updated as we send audio data to
|
||||
// stream. Otherwise it will remain -1 if we don't have audio.
|
||||
self->mAudioEndTime = -1;
|
||||
self->mAudioCaptured = true;
|
||||
// Start DecodedStream if we are already playing. Otherwise it will be
|
||||
// handled in MaybeStartPlayback().
|
||||
if (self->IsPlaying()) {
|
||||
self->mDecodedStream->StartPlayback(self->GetMediaTime(), self->mInfo);
|
||||
}
|
||||
self->ScheduleStateMachine();
|
||||
}
|
||||
});
|
||||
|
@ -1066,10 +1066,6 @@ protected:
|
||||
public:
|
||||
AbstractCanonical<int64_t>* CanonicalCurrentPosition() { return &mCurrentPosition; }
|
||||
protected:
|
||||
// The presentation time of the first audio/video frame that is sent to the
|
||||
// media stream.
|
||||
int64_t mStreamStartTime;
|
||||
|
||||
// The end time of the last audio frame that's been pushed onto the audio
|
||||
// hardware in microseconds. This will approximately be the end time of the
|
||||
// audio stream, unless another frame is pushed to the hardware.
|
||||
|
@ -1545,4 +1545,10 @@ function setMediaTestsPrefs(callback, extraPrefs) {
|
||||
SpecialPowers.pushPrefEnv({"set": prefs}, callback);
|
||||
}
|
||||
|
||||
// B2G emulator and Android 2.3 are condidered slow platforms
|
||||
function isSlowPlatform() {
|
||||
return SpecialPowers.Services.appinfo.name == "B2G" ||
|
||||
navigator.userAgent.indexOf("Mobile") != -1 && androidVersion == 10;
|
||||
}
|
||||
|
||||
SimpleTest.requestFlakyTimeout("untriaged");
|
||||
|
@ -12,6 +12,11 @@
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
//longer timeout for slow platforms
|
||||
if (isSlowPlatform()) {
|
||||
SimpleTest.requestLongerTimeout(1.5);
|
||||
}
|
||||
|
||||
var manager = new MediaTestManager;
|
||||
|
||||
// Fragment parameters to try
|
||||
|
@ -10,11 +10,6 @@
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function isSlowPlatform() {
|
||||
return SpecialPowers.Services.appinfo.name == "B2G" ||
|
||||
navigator.userAgent.indexOf("Mobile") != -1 && androidVersion == 10;
|
||||
}
|
||||
|
||||
// longer timeout for slow platforms
|
||||
if (isSlowPlatform()) {
|
||||
SimpleTest.requestLongerTimeout(3);
|
||||
|
@ -10,11 +10,6 @@
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function isSlowPlatform() {
|
||||
return SpecialPowers.Services.appinfo.name == "B2G" ||
|
||||
navigator.userAgent.indexOf("Mobile") != -1 && androidVersion == 10;
|
||||
}
|
||||
|
||||
// longer timeout for slow platforms
|
||||
if (isSlowPlatform()) {
|
||||
SimpleTest.requestLongerTimeout(3);
|
||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
@ -3996,19 +3996,7 @@ FireControllerChangeOnMatchingDocument(nsISupports* aKey,
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
ClaimMatchingClients(nsISupportsHashKey* aKey, void* aData)
|
||||
{
|
||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
ServiceWorkerRegistrationInfo* workerRegistration =
|
||||
static_cast<ServiceWorkerRegistrationInfo*>(aData);
|
||||
nsCOMPtr<nsIDocument> document = do_QueryInterface(aKey->GetKey());
|
||||
|
||||
swm->MaybeClaimClient(document, workerRegistration);
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
} // namespace
|
||||
} // anonymous namespace
|
||||
|
||||
void
|
||||
ServiceWorkerManager::GetAllClients(nsIPrincipal* aPrincipal,
|
||||
@ -4076,7 +4064,11 @@ ServiceWorkerManager::ClaimClients(nsIPrincipal* aPrincipal,
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
mAllDocuments.EnumerateEntries(ClaimMatchingClients, registration);
|
||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
for (auto iter = mAllDocuments.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsCOMPtr<nsIDocument> document = do_QueryInterface(iter.Get()->GetKey());
|
||||
swm->MaybeClaimClient(document, registration);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -82,240 +82,6 @@ ServiceWorkerManagerService::UnregisterActor(ServiceWorkerManagerParent* aParent
|
||||
mAgents.RemoveEntry(aParent);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct MOZ_STACK_CLASS RegistrationData final
|
||||
{
|
||||
RegistrationData(ServiceWorkerRegistrationData& aData,
|
||||
uint64_t aParentID)
|
||||
: mData(aData)
|
||||
, mParentID(aParentID)
|
||||
#ifdef DEBUG
|
||||
, mParentFound(false)
|
||||
#endif
|
||||
{
|
||||
MOZ_COUNT_CTOR(RegistrationData);
|
||||
}
|
||||
|
||||
~RegistrationData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(RegistrationData);
|
||||
}
|
||||
|
||||
const ServiceWorkerRegistrationData& mData;
|
||||
const uint64_t mParentID;
|
||||
#ifdef DEBUG
|
||||
bool mParentFound;
|
||||
#endif
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
RegistrationEnumerator(nsPtrHashKey<ServiceWorkerManagerParent>* aKey, void* aPtr)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
auto* data = static_cast<RegistrationData*>(aPtr);
|
||||
|
||||
ServiceWorkerManagerParent* parent = aKey->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent->ID() != data->mParentID) {
|
||||
unused << parent->SendNotifyRegister(data->mData);
|
||||
#ifdef DEBUG
|
||||
} else {
|
||||
data->mParentFound = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
struct MOZ_STACK_CLASS SoftUpdateData final
|
||||
{
|
||||
SoftUpdateData(const OriginAttributes& aOriginAttributes,
|
||||
const nsAString& aScope,
|
||||
uint64_t aParentID)
|
||||
: mOriginAttributes(aOriginAttributes)
|
||||
, mScope(aScope)
|
||||
, mParentID(aParentID)
|
||||
#ifdef DEBUG
|
||||
, mParentFound(false)
|
||||
#endif
|
||||
{
|
||||
MOZ_COUNT_CTOR(SoftUpdateData);
|
||||
}
|
||||
|
||||
~SoftUpdateData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(SoftUpdateData);
|
||||
}
|
||||
|
||||
const OriginAttributes& mOriginAttributes;
|
||||
const nsString mScope;
|
||||
const uint64_t mParentID;
|
||||
#ifdef DEBUG
|
||||
bool mParentFound;
|
||||
#endif
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
SoftUpdateEnumerator(nsPtrHashKey<ServiceWorkerManagerParent>* aKey, void* aPtr)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
auto* data = static_cast<SoftUpdateData*>(aPtr);
|
||||
ServiceWorkerManagerParent* parent = aKey->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent->ID() != data->mParentID) {
|
||||
unused <<parent->SendNotifySoftUpdate(data->mOriginAttributes,
|
||||
data->mScope);
|
||||
#ifdef DEBUG
|
||||
} else {
|
||||
data->mParentFound = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
struct MOZ_STACK_CLASS UnregisterData final
|
||||
{
|
||||
UnregisterData(const PrincipalInfo& aPrincipalInfo,
|
||||
const nsAString& aScope,
|
||||
uint64_t aParentID)
|
||||
: mPrincipalInfo(aPrincipalInfo)
|
||||
, mScope(aScope)
|
||||
, mParentID(aParentID)
|
||||
#ifdef DEBUG
|
||||
, mParentFound(false)
|
||||
#endif
|
||||
{
|
||||
MOZ_COUNT_CTOR(UnregisterData);
|
||||
}
|
||||
|
||||
~UnregisterData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(UnregisterData);
|
||||
}
|
||||
|
||||
const PrincipalInfo mPrincipalInfo;
|
||||
const nsString mScope;
|
||||
const uint64_t mParentID;
|
||||
#ifdef DEBUG
|
||||
bool mParentFound;
|
||||
#endif
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
UnregisterEnumerator(nsPtrHashKey<ServiceWorkerManagerParent>* aKey, void* aPtr)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
auto* data = static_cast<UnregisterData*>(aPtr);
|
||||
ServiceWorkerManagerParent* parent = aKey->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent->ID() != data->mParentID) {
|
||||
unused << parent->SendNotifyUnregister(data->mPrincipalInfo, data->mScope);
|
||||
#ifdef DEBUG
|
||||
} else {
|
||||
data->mParentFound = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
struct MOZ_STACK_CLASS RemoveAllData final
|
||||
{
|
||||
explicit RemoveAllData(uint64_t aParentID)
|
||||
: mParentID(aParentID)
|
||||
#ifdef DEBUG
|
||||
, mParentFound(false)
|
||||
#endif
|
||||
{
|
||||
MOZ_COUNT_CTOR(RemoveAllData);
|
||||
}
|
||||
|
||||
~RemoveAllData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(RemoveAllData);
|
||||
}
|
||||
|
||||
const uint64_t mParentID;
|
||||
#ifdef DEBUG
|
||||
bool mParentFound;
|
||||
#endif
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
RemoveAllEnumerator(nsPtrHashKey<ServiceWorkerManagerParent>* aKey, void* aPtr)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
auto* data = static_cast<RemoveAllData*>(aPtr);
|
||||
ServiceWorkerManagerParent* parent = aKey->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent->ID() != data->mParentID) {
|
||||
unused << parent->SendNotifyRemoveAll();
|
||||
#ifdef DEBUG
|
||||
} else {
|
||||
data->mParentFound = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
struct MOZ_STACK_CLASS RemoveData final
|
||||
{
|
||||
RemoveData(const nsACString& aHost,
|
||||
uint64_t aParentID)
|
||||
: mHost(aHost)
|
||||
, mParentID(aParentID)
|
||||
#ifdef DEBUG
|
||||
, mParentFound(false)
|
||||
#endif
|
||||
{
|
||||
MOZ_COUNT_CTOR(RemoveData);
|
||||
}
|
||||
|
||||
~RemoveData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(RemoveData);
|
||||
}
|
||||
|
||||
const nsCString mHost;
|
||||
const uint64_t mParentID;
|
||||
#ifdef DEBUG
|
||||
bool mParentFound;
|
||||
#endif
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
RemoveEnumerator(nsPtrHashKey<ServiceWorkerManagerParent>* aKey, void* aPtr)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
auto* data = static_cast<RemoveData*>(aPtr);
|
||||
ServiceWorkerManagerParent* parent = aKey->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent->ID() != data->mParentID) {
|
||||
unused << parent->SendNotifyRemove(data->mHost);
|
||||
#ifdef DEBUG
|
||||
} else {
|
||||
data->mParentFound = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void
|
||||
ServiceWorkerManagerService::PropagateRegistration(
|
||||
uint64_t aParentID,
|
||||
@ -323,11 +89,22 @@ ServiceWorkerManagerService::PropagateRegistration(
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
RegistrationData data(aData, aParentID);
|
||||
mAgents.EnumerateEntries(RegistrationEnumerator, &data);
|
||||
DebugOnly<bool> parentFound = false;
|
||||
for (auto iter = mAgents.Iter(); !iter.Done(); iter.Next()) {
|
||||
ServiceWorkerManagerParent* parent = iter.Get()->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent->ID() != aParentID) {
|
||||
unused << parent->SendNotifyRegister(aData);
|
||||
#ifdef DEBUG
|
||||
} else {
|
||||
parentFound = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(data.mParentFound);
|
||||
MOZ_ASSERT(parentFound);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -339,11 +116,24 @@ ServiceWorkerManagerService::PropagateSoftUpdate(
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
SoftUpdateData data(aOriginAttributes, aScope, aParentID);
|
||||
mAgents.EnumerateEntries(SoftUpdateEnumerator, &data);
|
||||
DebugOnly<bool> parentFound = false;
|
||||
for (auto iter = mAgents.Iter(); !iter.Done(); iter.Next()) {
|
||||
ServiceWorkerManagerParent* parent = iter.Get()->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent->ID() != aParentID) {
|
||||
nsString scope(aScope);
|
||||
unused << parent->SendNotifySoftUpdate(aOriginAttributes,
|
||||
scope);
|
||||
#ifdef DEBUG
|
||||
} else {
|
||||
parentFound = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(data.mParentFound);
|
||||
MOZ_ASSERT(parentFound);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -364,11 +154,23 @@ ServiceWorkerManagerService::PropagateUnregister(
|
||||
service->UnregisterServiceWorker(aPrincipalInfo,
|
||||
NS_ConvertUTF16toUTF8(aScope));
|
||||
|
||||
UnregisterData data(aPrincipalInfo, aScope, aParentID);
|
||||
mAgents.EnumerateEntries(UnregisterEnumerator, &data);
|
||||
DebugOnly<bool> parentFound = false;
|
||||
for (auto iter = mAgents.Iter(); !iter.Done(); iter.Next()) {
|
||||
ServiceWorkerManagerParent* parent = iter.Get()->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent->ID() != aParentID) {
|
||||
nsString scope(aScope);
|
||||
unused << parent->SendNotifyUnregister(aPrincipalInfo, scope);
|
||||
#ifdef DEBUG
|
||||
} else {
|
||||
parentFound = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(data.mParentFound);
|
||||
MOZ_ASSERT(parentFound);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -378,11 +180,23 @@ ServiceWorkerManagerService::PropagateRemove(uint64_t aParentID,
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
RemoveData data(aHost, aParentID);
|
||||
mAgents.EnumerateEntries(RemoveEnumerator, &data);
|
||||
DebugOnly<bool> parentFound = false;
|
||||
for (auto iter = mAgents.Iter(); !iter.Done(); iter.Next()) {
|
||||
ServiceWorkerManagerParent* parent = iter.Get()->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent->ID() != aParentID) {
|
||||
nsCString host(aHost);
|
||||
unused << parent->SendNotifyRemove(host);
|
||||
#ifdef DEBUG
|
||||
} else {
|
||||
parentFound = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(data.mParentFound);
|
||||
MOZ_ASSERT(parentFound);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -397,11 +211,22 @@ ServiceWorkerManagerService::PropagateRemoveAll(uint64_t aParentID)
|
||||
|
||||
service->RemoveAll();
|
||||
|
||||
RemoveAllData data(aParentID);
|
||||
mAgents.EnumerateEntries(RemoveAllEnumerator, &data);
|
||||
DebugOnly<bool> parentFound = false;
|
||||
for (auto iter = mAgents.Iter(); !iter.Done(); iter.Next()) {
|
||||
ServiceWorkerManagerParent* parent = iter.Get()->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent->ID() != aParentID) {
|
||||
unused << parent->SendNotifyRemoveAll();
|
||||
#ifdef DEBUG
|
||||
} else {
|
||||
parentFound = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(data.mParentFound);
|
||||
MOZ_ASSERT(parentFound);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -231,6 +231,7 @@ if CONFIG['GNU_CC']:
|
||||
'-Wno-incompatible-pointer-types',
|
||||
'-Wno-tautological-compare',
|
||||
'-Wno-tautological-constant-out-of-range-compare',
|
||||
'-Wno-error=uninitialized',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
|
||||
|
@ -154,8 +154,7 @@ static void LayerManagerUserDataDestroy(void *data)
|
||||
* 1) Construction: layers are created, inserted, removed and have
|
||||
* properties set on them in this phase.
|
||||
* BeginTransaction and BeginTransactionWithTarget start a transaction in
|
||||
* the Construction phase. When the client has finished constructing the layer
|
||||
* tree, it should call EndConstruction() to enter the drawing phase.
|
||||
* the Construction phase.
|
||||
* 2) Drawing: PaintedLayers are rendered into in this phase, in tree
|
||||
* order. When the client has finished drawing into the PaintedLayers, it should
|
||||
* call EndTransaction to complete the transaction.
|
||||
|
@ -54,6 +54,43 @@ struct TabSizes
|
||||
size_t other;
|
||||
};
|
||||
|
||||
// These are the measurements used by Servo. It's important that this is a POD
|
||||
// struct so that Servo can have a parallel |repr(C)| Rust equivalent.
|
||||
struct ServoSizes
|
||||
{
|
||||
enum Kind {
|
||||
GCHeapUsed,
|
||||
GCHeapUnused,
|
||||
GCHeapAdmin,
|
||||
GCHeapDecommitted,
|
||||
MallocHeap,
|
||||
NonHeap,
|
||||
Ignore
|
||||
};
|
||||
|
||||
ServoSizes() { mozilla::PodZero(this); }
|
||||
|
||||
void add(Kind kind, size_t n) {
|
||||
switch (kind) {
|
||||
case GCHeapUsed: gcHeapUsed += n; break;
|
||||
case GCHeapUnused: gcHeapUnused += n; break;
|
||||
case GCHeapAdmin: gcHeapAdmin += n; break;
|
||||
case GCHeapDecommitted: gcHeapDecommitted += n; break;
|
||||
case MallocHeap: mallocHeap += n; break;
|
||||
case NonHeap: nonHeap += n; break;
|
||||
case Ignore: /* do nothing */ break;
|
||||
default: MOZ_CRASH("bad ServoSizes kind");
|
||||
}
|
||||
}
|
||||
|
||||
size_t gcHeapUsed;
|
||||
size_t gcHeapUnused;
|
||||
size_t gcHeapAdmin;
|
||||
size_t gcHeapDecommitted;
|
||||
size_t mallocHeap;
|
||||
size_t nonHeap;
|
||||
};
|
||||
|
||||
} // namespace JS
|
||||
|
||||
namespace js {
|
||||
@ -92,24 +129,24 @@ struct CStringHashPolicy
|
||||
// then use the following macros to transform those lists into the required
|
||||
// methods.
|
||||
//
|
||||
// - The |tabKind| value is used when measuring TabSizes.
|
||||
//
|
||||
// - The |servoKind| value is used when measuring ServoSizes and also for
|
||||
// the various sizeOfLiveGCThings() methods.
|
||||
//
|
||||
// In some classes, one or more of the macro arguments aren't used. We use '_'
|
||||
// for those.
|
||||
//
|
||||
#define DECL_SIZE(kind, gc, mSize) size_t mSize;
|
||||
#define ZERO_SIZE(kind, gc, mSize) mSize(0),
|
||||
#define COPY_OTHER_SIZE(kind, gc, mSize) mSize(other.mSize),
|
||||
#define ADD_OTHER_SIZE(kind, gc, mSize) mSize += other.mSize;
|
||||
#define SUB_OTHER_SIZE(kind, gc, mSize) MOZ_ASSERT(mSize >= other.mSize); \
|
||||
mSize -= other.mSize;
|
||||
#define ADD_SIZE_TO_N(kind, gc, mSize) n += mSize;
|
||||
#define ADD_SIZE_TO_N_IF_LIVE_GC_THING(kind, gc, mSize) n += (js::gc) ? mSize : 0;
|
||||
#define ADD_TO_TAB_SIZES(kind, gc, mSize) sizes->add(JS::TabSizes::kind, mSize);
|
||||
|
||||
// Used to annotate which size_t fields measure live GC things and which don't.
|
||||
enum {
|
||||
NotLiveGCThing = false,
|
||||
IsLiveGCThing = true
|
||||
};
|
||||
#define DECL_SIZE(tabKind, servoKind, mSize) size_t mSize;
|
||||
#define ZERO_SIZE(tabKind, servoKind, mSize) mSize(0),
|
||||
#define COPY_OTHER_SIZE(tabKind, servoKind, mSize) mSize(other.mSize),
|
||||
#define ADD_OTHER_SIZE(tabKind, servoKind, mSize) mSize += other.mSize;
|
||||
#define SUB_OTHER_SIZE(tabKind, servoKind, mSize) MOZ_ASSERT(mSize >= other.mSize); \
|
||||
mSize -= other.mSize;
|
||||
#define ADD_SIZE_TO_N(tabKind, servoKind, mSize) n += mSize;
|
||||
#define ADD_SIZE_TO_N_IF_LIVE_GC_THING(tabKind, servoKind, mSize) n += (ServoSizes::servoKind == ServoSizes::GCHeapUsed) ? mSize : 0;
|
||||
#define ADD_TO_TAB_SIZES(tabKind, servoKind, mSize) sizes->add(JS::TabSizes::tabKind, mSize);
|
||||
#define ADD_TO_SERVO_SIZES(tabKind, servoKind, mSize) sizes->add(JS::ServoSizes::servoKind, mSize);
|
||||
|
||||
} // namespace js
|
||||
|
||||
@ -118,21 +155,21 @@ namespace JS {
|
||||
struct ClassInfo
|
||||
{
|
||||
#define FOR_EACH_SIZE(macro) \
|
||||
macro(Objects, IsLiveGCThing, objectsGCHeap) \
|
||||
macro(Objects, NotLiveGCThing, objectsMallocHeapSlots) \
|
||||
macro(Objects, NotLiveGCThing, objectsMallocHeapElementsNonAsmJS) \
|
||||
macro(Objects, NotLiveGCThing, objectsMallocHeapElementsAsmJS) \
|
||||
macro(Objects, NotLiveGCThing, objectsNonHeapElementsAsmJS) \
|
||||
macro(Objects, NotLiveGCThing, objectsNonHeapElementsMapped) \
|
||||
macro(Objects, NotLiveGCThing, objectsNonHeapCodeAsmJS) \
|
||||
macro(Objects, NotLiveGCThing, objectsMallocHeapMisc) \
|
||||
macro(Objects, GCHeapUsed, objectsGCHeap) \
|
||||
macro(Objects, MallocHeap, objectsMallocHeapSlots) \
|
||||
macro(Objects, MallocHeap, objectsMallocHeapElementsNonAsmJS) \
|
||||
macro(Objects, MallocHeap, objectsMallocHeapElementsAsmJS) \
|
||||
macro(Objects, NonHeap, objectsNonHeapElementsAsmJS) \
|
||||
macro(Objects, NonHeap, objectsNonHeapElementsMapped) \
|
||||
macro(Objects, NonHeap, objectsNonHeapCodeAsmJS) \
|
||||
macro(Objects, MallocHeap, objectsMallocHeapMisc) \
|
||||
\
|
||||
macro(Other, IsLiveGCThing, shapesGCHeapTree) \
|
||||
macro(Other, IsLiveGCThing, shapesGCHeapDict) \
|
||||
macro(Other, IsLiveGCThing, shapesGCHeapBase) \
|
||||
macro(Other, NotLiveGCThing, shapesMallocHeapTreeTables) \
|
||||
macro(Other, NotLiveGCThing, shapesMallocHeapDictTables) \
|
||||
macro(Other, NotLiveGCThing, shapesMallocHeapTreeKids) \
|
||||
macro(Other, GCHeapUsed, shapesGCHeapTree) \
|
||||
macro(Other, GCHeapUsed, shapesGCHeapDict) \
|
||||
macro(Other, GCHeapUsed, shapesGCHeapBase) \
|
||||
macro(Other, MallocHeap, shapesMallocHeapTreeTables) \
|
||||
macro(Other, MallocHeap, shapesMallocHeapDictTables) \
|
||||
macro(Other, MallocHeap, shapesMallocHeapTreeKids)
|
||||
|
||||
ClassInfo()
|
||||
: FOR_EACH_SIZE(ZERO_SIZE)
|
||||
@ -168,6 +205,10 @@ struct ClassInfo
|
||||
FOR_EACH_SIZE(ADD_TO_TAB_SIZES)
|
||||
}
|
||||
|
||||
void addToServoSizes(ServoSizes *sizes) const {
|
||||
FOR_EACH_SIZE(ADD_TO_SERVO_SIZES)
|
||||
}
|
||||
|
||||
FOR_EACH_SIZE(DECL_SIZE)
|
||||
int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE)
|
||||
|
||||
@ -201,17 +242,21 @@ struct NotableClassInfo : public ClassInfo
|
||||
struct CodeSizes
|
||||
{
|
||||
#define FOR_EACH_SIZE(macro) \
|
||||
macro(_, _, ion) \
|
||||
macro(_, _, baseline) \
|
||||
macro(_, _, regexp) \
|
||||
macro(_, _, other) \
|
||||
macro(_, _, unused)
|
||||
macro(_, NonHeap, ion) \
|
||||
macro(_, NonHeap, baseline) \
|
||||
macro(_, NonHeap, regexp) \
|
||||
macro(_, NonHeap, other) \
|
||||
macro(_, NonHeap, unused)
|
||||
|
||||
CodeSizes()
|
||||
: FOR_EACH_SIZE(ZERO_SIZE)
|
||||
dummy()
|
||||
{}
|
||||
|
||||
void addToServoSizes(ServoSizes *sizes) const {
|
||||
FOR_EACH_SIZE(ADD_TO_SERVO_SIZES)
|
||||
}
|
||||
|
||||
FOR_EACH_SIZE(DECL_SIZE)
|
||||
int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE)
|
||||
|
||||
@ -221,24 +266,30 @@ struct CodeSizes
|
||||
// Data for tracking GC memory usage.
|
||||
struct GCSizes
|
||||
{
|
||||
// |nurseryDecommitted| is marked as NonHeap rather than GCHeapDecommitted
|
||||
// because we don't consider the nursery to be part of the GC heap.
|
||||
#define FOR_EACH_SIZE(macro) \
|
||||
macro(_, _, marker) \
|
||||
macro(_, _, nurseryCommitted) \
|
||||
macro(_, _, nurseryDecommitted) \
|
||||
macro(_, _, nurseryMallocedBuffers) \
|
||||
macro(_, _, storeBufferVals) \
|
||||
macro(_, _, storeBufferCells) \
|
||||
macro(_, _, storeBufferSlots) \
|
||||
macro(_, _, storeBufferWholeCells) \
|
||||
macro(_, _, storeBufferRelocVals) \
|
||||
macro(_, _, storeBufferRelocCells) \
|
||||
macro(_, _, storeBufferGenerics)
|
||||
macro(_, MallocHeap, marker) \
|
||||
macro(_, NonHeap, nurseryCommitted) \
|
||||
macro(_, NonHeap, nurseryDecommitted) \
|
||||
macro(_, MallocHeap, nurseryMallocedBuffers) \
|
||||
macro(_, MallocHeap, storeBufferVals) \
|
||||
macro(_, MallocHeap, storeBufferCells) \
|
||||
macro(_, MallocHeap, storeBufferSlots) \
|
||||
macro(_, MallocHeap, storeBufferWholeCells) \
|
||||
macro(_, MallocHeap, storeBufferRelocVals) \
|
||||
macro(_, MallocHeap, storeBufferRelocCells) \
|
||||
macro(_, MallocHeap, storeBufferGenerics)
|
||||
|
||||
GCSizes()
|
||||
: FOR_EACH_SIZE(ZERO_SIZE)
|
||||
dummy()
|
||||
{}
|
||||
|
||||
void addToServoSizes(ServoSizes *sizes) const {
|
||||
FOR_EACH_SIZE(ADD_TO_SERVO_SIZES)
|
||||
}
|
||||
|
||||
FOR_EACH_SIZE(DECL_SIZE)
|
||||
int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE)
|
||||
|
||||
@ -253,10 +304,10 @@ struct GCSizes
|
||||
struct StringInfo
|
||||
{
|
||||
#define FOR_EACH_SIZE(macro) \
|
||||
macro(Strings, IsLiveGCThing, gcHeapLatin1) \
|
||||
macro(Strings, IsLiveGCThing, gcHeapTwoByte) \
|
||||
macro(Strings, NotLiveGCThing, mallocHeapLatin1) \
|
||||
macro(Strings, NotLiveGCThing, mallocHeapTwoByte)
|
||||
macro(Strings, GCHeapUsed, gcHeapLatin1) \
|
||||
macro(Strings, GCHeapUsed, gcHeapTwoByte) \
|
||||
macro(Strings, MallocHeap, mallocHeapLatin1) \
|
||||
macro(Strings, MallocHeap, mallocHeapTwoByte)
|
||||
|
||||
StringInfo()
|
||||
: FOR_EACH_SIZE(ZERO_SIZE)
|
||||
@ -290,6 +341,10 @@ struct StringInfo
|
||||
FOR_EACH_SIZE(ADD_TO_TAB_SIZES)
|
||||
}
|
||||
|
||||
void addToServoSizes(ServoSizes *sizes) const {
|
||||
FOR_EACH_SIZE(ADD_TO_SERVO_SIZES)
|
||||
}
|
||||
|
||||
FOR_EACH_SIZE(DECL_SIZE)
|
||||
uint32_t numCopies; // How many copies of the string have we seen?
|
||||
|
||||
@ -326,9 +381,9 @@ struct NotableStringInfo : public StringInfo
|
||||
struct ScriptSourceInfo
|
||||
{
|
||||
#define FOR_EACH_SIZE(macro) \
|
||||
macro(_, _, compressed) \
|
||||
macro(_, _, uncompressed) \
|
||||
macro(_, _, misc)
|
||||
macro(_, MallocHeap, compressed) \
|
||||
macro(_, MallocHeap, uncompressed) \
|
||||
macro(_, MallocHeap, misc)
|
||||
|
||||
ScriptSourceInfo()
|
||||
: FOR_EACH_SIZE(ZERO_SIZE)
|
||||
@ -345,6 +400,10 @@ struct ScriptSourceInfo
|
||||
numScripts--;
|
||||
}
|
||||
|
||||
void addToServoSizes(ServoSizes *sizes) const {
|
||||
FOR_EACH_SIZE(ADD_TO_SERVO_SIZES)
|
||||
}
|
||||
|
||||
bool isNotable() const {
|
||||
static const size_t NotabilityThreshold = 16 * 1024;
|
||||
size_t n = 0;
|
||||
@ -387,16 +446,16 @@ struct NotableScriptSourceInfo : public ScriptSourceInfo
|
||||
struct RuntimeSizes
|
||||
{
|
||||
#define FOR_EACH_SIZE(macro) \
|
||||
macro(_, _, object) \
|
||||
macro(_, _, atomsTable) \
|
||||
macro(_, _, contexts) \
|
||||
macro(_, _, dtoa) \
|
||||
macro(_, _, temporary) \
|
||||
macro(_, _, interpreterStack) \
|
||||
macro(_, _, mathCache) \
|
||||
macro(_, _, uncompressedSourceCache) \
|
||||
macro(_, _, compressedSourceSet) \
|
||||
macro(_, _, scriptData) \
|
||||
macro(_, MallocHeap, object) \
|
||||
macro(_, MallocHeap, atomsTable) \
|
||||
macro(_, MallocHeap, contexts) \
|
||||
macro(_, MallocHeap, dtoa) \
|
||||
macro(_, MallocHeap, temporary) \
|
||||
macro(_, MallocHeap, interpreterStack) \
|
||||
macro(_, MallocHeap, mathCache) \
|
||||
macro(_, MallocHeap, uncompressedSourceCache) \
|
||||
macro(_, MallocHeap, compressedSourceSet) \
|
||||
macro(_, MallocHeap, scriptData)
|
||||
|
||||
RuntimeSizes()
|
||||
: FOR_EACH_SIZE(ZERO_SIZE)
|
||||
@ -417,14 +476,21 @@ struct RuntimeSizes
|
||||
js_delete(allScriptSources);
|
||||
}
|
||||
|
||||
void addToServoSizes(ServoSizes *sizes) const {
|
||||
FOR_EACH_SIZE(ADD_TO_SERVO_SIZES)
|
||||
scriptSourceInfo.addToServoSizes(sizes);
|
||||
code.addToServoSizes(sizes);
|
||||
gc.addToServoSizes(sizes);
|
||||
}
|
||||
|
||||
// The script source measurements in |scriptSourceInfo| are initially for
|
||||
// all script sources. At the end, if the measurement granularity is
|
||||
// FineGrained, we subtract the measurements of the notable script sources
|
||||
// and move them into |notableScriptSources|.
|
||||
FOR_EACH_SIZE(DECL_SIZE)
|
||||
ScriptSourceInfo scriptSourceInfo;
|
||||
CodeSizes code;
|
||||
GCSizes gc;
|
||||
ScriptSourceInfo scriptSourceInfo;
|
||||
CodeSizes code;
|
||||
GCSizes gc;
|
||||
|
||||
typedef js::HashMap<const char*, ScriptSourceInfo,
|
||||
js::CStringHashPolicy,
|
||||
@ -440,25 +506,25 @@ struct RuntimeSizes
|
||||
#undef FOR_EACH_SIZE
|
||||
};
|
||||
|
||||
struct GCThingSizes
|
||||
struct UnusedGCThingSizes
|
||||
{
|
||||
#define FOR_EACH_SIZE(macro) \
|
||||
macro(_, _, object) \
|
||||
macro(_, _, script) \
|
||||
macro(_, _, lazyScript) \
|
||||
macro(_, _, shape) \
|
||||
macro(_, _, baseShape) \
|
||||
macro(_, _, objectGroup) \
|
||||
macro(_, _, string) \
|
||||
macro(_, _, symbol) \
|
||||
macro(_, _, jitcode) \
|
||||
macro(Other, GCHeapUnused, object) \
|
||||
macro(Other, GCHeapUnused, script) \
|
||||
macro(Other, GCHeapUnused, lazyScript) \
|
||||
macro(Other, GCHeapUnused, shape) \
|
||||
macro(Other, GCHeapUnused, baseShape) \
|
||||
macro(Other, GCHeapUnused, objectGroup) \
|
||||
macro(Other, GCHeapUnused, string) \
|
||||
macro(Other, GCHeapUnused, symbol) \
|
||||
macro(Other, GCHeapUnused, jitcode) \
|
||||
|
||||
GCThingSizes()
|
||||
UnusedGCThingSizes()
|
||||
: FOR_EACH_SIZE(ZERO_SIZE)
|
||||
dummy()
|
||||
{}
|
||||
|
||||
GCThingSizes(GCThingSizes&& other)
|
||||
UnusedGCThingSizes(UnusedGCThingSizes&& other)
|
||||
: FOR_EACH_SIZE(COPY_OTHER_SIZE)
|
||||
dummy()
|
||||
{}
|
||||
@ -475,11 +541,11 @@ struct GCThingSizes
|
||||
case JS::TraceKind::LazyScript: lazyScript += n; break;
|
||||
case JS::TraceKind::ObjectGroup: objectGroup += n; break;
|
||||
default:
|
||||
MOZ_CRASH("Bad trace kind for GCThingSizes");
|
||||
MOZ_CRASH("Bad trace kind for UnusedGCThingSizes");
|
||||
}
|
||||
}
|
||||
|
||||
void addSizes(const GCThingSizes& other) {
|
||||
void addSizes(const UnusedGCThingSizes& other) {
|
||||
FOR_EACH_SIZE(ADD_OTHER_SIZE)
|
||||
}
|
||||
|
||||
@ -489,6 +555,14 @@ struct GCThingSizes
|
||||
return n;
|
||||
}
|
||||
|
||||
void addToTabSizes(JS::TabSizes *sizes) const {
|
||||
FOR_EACH_SIZE(ADD_TO_TAB_SIZES)
|
||||
}
|
||||
|
||||
void addToServoSizes(JS::ServoSizes *sizes) const {
|
||||
FOR_EACH_SIZE(ADD_TO_SERVO_SIZES)
|
||||
}
|
||||
|
||||
FOR_EACH_SIZE(DECL_SIZE)
|
||||
int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE)
|
||||
|
||||
@ -498,15 +572,15 @@ struct GCThingSizes
|
||||
struct ZoneStats
|
||||
{
|
||||
#define FOR_EACH_SIZE(macro) \
|
||||
macro(Other, IsLiveGCThing, symbolsGCHeap) \
|
||||
macro(Other, NotLiveGCThing, gcHeapArenaAdmin) \
|
||||
macro(Other, IsLiveGCThing, lazyScriptsGCHeap) \
|
||||
macro(Other, NotLiveGCThing, lazyScriptsMallocHeap) \
|
||||
macro(Other, IsLiveGCThing, jitCodesGCHeap) \
|
||||
macro(Other, IsLiveGCThing, objectGroupsGCHeap) \
|
||||
macro(Other, NotLiveGCThing, objectGroupsMallocHeap) \
|
||||
macro(Other, NotLiveGCThing, typePool) \
|
||||
macro(Other, NotLiveGCThing, baselineStubsOptimized) \
|
||||
macro(Other, GCHeapUsed, symbolsGCHeap) \
|
||||
macro(Other, GCHeapAdmin, gcHeapArenaAdmin) \
|
||||
macro(Other, GCHeapUsed, lazyScriptsGCHeap) \
|
||||
macro(Other, MallocHeap, lazyScriptsMallocHeap) \
|
||||
macro(Other, GCHeapUsed, jitCodesGCHeap) \
|
||||
macro(Other, GCHeapUsed, objectGroupsGCHeap) \
|
||||
macro(Other, MallocHeap, objectGroupsMallocHeap) \
|
||||
macro(Other, MallocHeap, typePool) \
|
||||
macro(Other, MallocHeap, baselineStubsOptimized)
|
||||
|
||||
ZoneStats()
|
||||
: FOR_EACH_SIZE(ZERO_SIZE)
|
||||
@ -558,16 +632,23 @@ struct ZoneStats
|
||||
void addToTabSizes(JS::TabSizes* sizes) const {
|
||||
MOZ_ASSERT(isTotals);
|
||||
FOR_EACH_SIZE(ADD_TO_TAB_SIZES)
|
||||
sizes->add(JS::TabSizes::Other, unusedGCThings.totalSize());
|
||||
unusedGCThings.addToTabSizes(sizes);
|
||||
stringInfo.addToTabSizes(sizes);
|
||||
}
|
||||
|
||||
void addToServoSizes(JS::ServoSizes *sizes) const {
|
||||
MOZ_ASSERT(isTotals);
|
||||
FOR_EACH_SIZE(ADD_TO_SERVO_SIZES)
|
||||
unusedGCThings.addToServoSizes(sizes);
|
||||
stringInfo.addToServoSizes(sizes);
|
||||
}
|
||||
|
||||
// These string measurements are initially for all strings. At the end,
|
||||
// if the measurement granularity is FineGrained, we subtract the
|
||||
// measurements of the notable script sources and move them into
|
||||
// |notableStrings|.
|
||||
FOR_EACH_SIZE(DECL_SIZE)
|
||||
GCThingSizes unusedGCThings;
|
||||
UnusedGCThingSizes unusedGCThings;
|
||||
StringInfo stringInfo;
|
||||
void* extra; // This field can be used by embedders.
|
||||
|
||||
@ -588,25 +669,29 @@ struct ZoneStats
|
||||
|
||||
struct CompartmentStats
|
||||
{
|
||||
// We assume that |objectsPrivate| is on the malloc heap, but it's not
|
||||
// actually guaranteed. But for Servo, at least, it's a moot point because
|
||||
// it doesn't provide an ObjectPrivateVisitor so the value will always be
|
||||
// zero.
|
||||
#define FOR_EACH_SIZE(macro) \
|
||||
macro(Private, NotLiveGCThing, objectsPrivate) \
|
||||
macro(Other, IsLiveGCThing, scriptsGCHeap) \
|
||||
macro(Other, NotLiveGCThing, scriptsMallocHeapData) \
|
||||
macro(Other, NotLiveGCThing, baselineData) \
|
||||
macro(Other, NotLiveGCThing, baselineStubsFallback) \
|
||||
macro(Other, NotLiveGCThing, ionData) \
|
||||
macro(Other, NotLiveGCThing, typeInferenceTypeScripts) \
|
||||
macro(Other, NotLiveGCThing, typeInferenceAllocationSiteTables) \
|
||||
macro(Other, NotLiveGCThing, typeInferenceArrayTypeTables) \
|
||||
macro(Other, NotLiveGCThing, typeInferenceObjectTypeTables) \
|
||||
macro(Other, NotLiveGCThing, compartmentObject) \
|
||||
macro(Other, NotLiveGCThing, compartmentTables) \
|
||||
macro(Other, NotLiveGCThing, innerViewsTable) \
|
||||
macro(Other, NotLiveGCThing, lazyArrayBuffersTable) \
|
||||
macro(Other, NotLiveGCThing, objectMetadataTable) \
|
||||
macro(Other, NotLiveGCThing, crossCompartmentWrappersTable) \
|
||||
macro(Other, NotLiveGCThing, regexpCompartment) \
|
||||
macro(Other, NotLiveGCThing, savedStacksSet)
|
||||
macro(Private, MallocHeap, objectsPrivate) \
|
||||
macro(Other, GCHeapUsed, scriptsGCHeap) \
|
||||
macro(Other, MallocHeap, scriptsMallocHeapData) \
|
||||
macro(Other, MallocHeap, baselineData) \
|
||||
macro(Other, MallocHeap, baselineStubsFallback) \
|
||||
macro(Other, MallocHeap, ionData) \
|
||||
macro(Other, MallocHeap, typeInferenceTypeScripts) \
|
||||
macro(Other, MallocHeap, typeInferenceAllocationSiteTables) \
|
||||
macro(Other, MallocHeap, typeInferenceArrayTypeTables) \
|
||||
macro(Other, MallocHeap, typeInferenceObjectTypeTables) \
|
||||
macro(Other, MallocHeap, compartmentObject) \
|
||||
macro(Other, MallocHeap, compartmentTables) \
|
||||
macro(Other, MallocHeap, innerViewsTable) \
|
||||
macro(Other, MallocHeap, lazyArrayBuffersTable) \
|
||||
macro(Other, MallocHeap, objectMetadataTable) \
|
||||
macro(Other, MallocHeap, crossCompartmentWrappersTable) \
|
||||
macro(Other, MallocHeap, regexpCompartment) \
|
||||
macro(Other, MallocHeap, savedStacksSet)
|
||||
|
||||
CompartmentStats()
|
||||
: FOR_EACH_SIZE(ZERO_SIZE)
|
||||
@ -658,12 +743,18 @@ struct CompartmentStats
|
||||
classInfo.addToTabSizes(sizes);
|
||||
}
|
||||
|
||||
void addToServoSizes(ServoSizes *sizes) const {
|
||||
MOZ_ASSERT(isTotals);
|
||||
FOR_EACH_SIZE(ADD_TO_SERVO_SIZES);
|
||||
classInfo.addToServoSizes(sizes);
|
||||
}
|
||||
|
||||
// The class measurements in |classInfo| are initially for all classes. At
|
||||
// the end, if the measurement granularity is FineGrained, we subtract the
|
||||
// measurements of the notable classes and move them into |notableClasses|.
|
||||
FOR_EACH_SIZE(DECL_SIZE)
|
||||
ClassInfo classInfo;
|
||||
void* extra; // This field can be used by embedders.
|
||||
ClassInfo classInfo;
|
||||
void* extra; // This field can be used by embedders.
|
||||
|
||||
typedef js::HashMap<const char*, ClassInfo,
|
||||
js::CStringHashPolicy,
|
||||
@ -682,13 +773,18 @@ typedef js::Vector<ZoneStats, 0, js::SystemAllocPolicy> ZoneStatsVector;
|
||||
|
||||
struct RuntimeStats
|
||||
{
|
||||
// |gcHeapChunkTotal| is ignored because it's the sum of all the other
|
||||
// values. |gcHeapGCThings| is ignored because it's the sum of some of the
|
||||
// values from the zones and compartments. Both of those values are not
|
||||
// reported directly, but are just present for sanity-checking other
|
||||
// values.
|
||||
#define FOR_EACH_SIZE(macro) \
|
||||
macro(_, _, gcHeapChunkTotal) \
|
||||
macro(_, _, gcHeapDecommittedArenas) \
|
||||
macro(_, _, gcHeapUnusedChunks) \
|
||||
macro(_, _, gcHeapUnusedArenas) \
|
||||
macro(_, _, gcHeapChunkAdmin) \
|
||||
macro(_, _, gcHeapGCThings) \
|
||||
macro(_, Ignore, gcHeapChunkTotal) \
|
||||
macro(_, GCHeapDecommitted, gcHeapDecommittedArenas) \
|
||||
macro(_, GCHeapUnused, gcHeapUnusedChunks) \
|
||||
macro(_, GCHeapUnused, gcHeapUnusedArenas) \
|
||||
macro(_, GCHeapAdmin, gcHeapChunkAdmin) \
|
||||
macro(_, Ignore, gcHeapGCThings)
|
||||
|
||||
explicit RuntimeStats(mozilla::MallocSizeOf mallocSizeOf)
|
||||
: FOR_EACH_SIZE(ZERO_SIZE)
|
||||
@ -709,7 +805,7 @@ struct RuntimeStats
|
||||
// - unused bytes
|
||||
// - rtStats.gcHeapUnusedChunks (empty chunks)
|
||||
// - rtStats.gcHeapUnusedArenas (empty arenas within non-empty chunks)
|
||||
// - rtStats.zTotals.unusedGCThings (empty GC thing slots within non-empty arenas)
|
||||
// - rtStats.zTotals.unusedGCThings.totalSize() (empty GC thing slots within non-empty arenas)
|
||||
// - used bytes
|
||||
// - rtStats.gcHeapChunkAdmin
|
||||
// - rtStats.zTotals.gcHeapArenaAdmin
|
||||
@ -721,6 +817,11 @@ struct RuntimeStats
|
||||
// it's rare, and (b) this means that rtStats.gcHeapUnusedChunks is a
|
||||
// multiple of the chunk size, which is good.
|
||||
|
||||
void addToServoSizes(ServoSizes *sizes) const {
|
||||
FOR_EACH_SIZE(ADD_TO_SERVO_SIZES)
|
||||
runtime.addToServoSizes(sizes);
|
||||
}
|
||||
|
||||
FOR_EACH_SIZE(DECL_SIZE)
|
||||
|
||||
RuntimeSizes runtime;
|
||||
@ -774,6 +875,10 @@ extern JS_PUBLIC_API(bool)
|
||||
AddSizeOfTab(JSRuntime* rt, JS::HandleObject obj, mozilla::MallocSizeOf mallocSizeOf,
|
||||
ObjectPrivateVisitor* opv, TabSizes* sizes);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
AddServoSizeOf(JSRuntime *rt, mozilla::MallocSizeOf mallocSizeOf,
|
||||
ObjectPrivateVisitor *opv, ServoSizes *sizes);
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#undef DECL_SIZE
|
||||
|
@ -284,6 +284,7 @@ Function Properties of the `Debugger.Memory.prototype` Object
|
||||
"timestamp": <i>timestamp</i>,
|
||||
"frame": <i>allocationSite</i>,
|
||||
"class": <i>className</i>,
|
||||
"size": <i>byteSize</i>,
|
||||
}
|
||||
</pre>
|
||||
|
||||
@ -302,6 +303,9 @@ Function Properties of the `Debugger.Memory.prototype` Object
|
||||
`[[Class]]` property, for example "Array", "Date", "RegExp", or (most
|
||||
commonly) "Object".
|
||||
|
||||
* *byteSize* is the size of the newly tenured object (within the tenured
|
||||
heap, not the nursery) in bytes.
|
||||
|
||||
When `trackingTenurePromotions` is `false`, `drainTenurePromotionsLog()`
|
||||
throws an `Error`.
|
||||
|
||||
|
@ -140,6 +140,7 @@ Zone::logPromotionsToTenured()
|
||||
return;
|
||||
|
||||
auto now = JS_GetCurrentEmbedderTime();
|
||||
JSRuntime* rt = runtimeFromAnyThread();
|
||||
|
||||
for (auto** dbgp = dbgs->begin(); dbgp != dbgs->end(); dbgp++) {
|
||||
if (!(*dbgp)->isEnabled() || !(*dbgp)->isTrackingTenurePromotions())
|
||||
@ -147,7 +148,7 @@ Zone::logPromotionsToTenured()
|
||||
|
||||
for (auto range = awaitingTenureLogging.all(); !range.empty(); range.popFront()) {
|
||||
if ((*dbgp)->isDebuggee(range.front()->compartment()))
|
||||
(*dbgp)->logTenurePromotion(*range.front(), now);
|
||||
(*dbgp)->logTenurePromotion(rt, *range.front(), now);
|
||||
}
|
||||
}
|
||||
|
||||
|
48
js/src/jit-test/tests/debug/Memory-tenurePromotionsLog-07.js
Normal file
48
js/src/jit-test/tests/debug/Memory-tenurePromotionsLog-07.js
Normal file
@ -0,0 +1,48 @@
|
||||
// Test basic sizes of entries in the tenure promotions log. Does not attempt to
|
||||
// test the actual object sizes in depth, as heap-analysis/byteSize-of-object.js
|
||||
// does that pretty thoroughly, just that they are present where expected.
|
||||
|
||||
const root = newGlobal();
|
||||
const dbg = root.dbg = new Debugger();
|
||||
const wrappedRoot = dbg.addDebuggee(root)
|
||||
|
||||
root.eval(`
|
||||
this.tests = [];
|
||||
|
||||
function Ctor() { }
|
||||
|
||||
function AsmModule(stdlib, foreign, heap) {
|
||||
"use asm";
|
||||
|
||||
function test() {
|
||||
return 5|0;
|
||||
}
|
||||
|
||||
return { test: test };
|
||||
}
|
||||
const buf = new ArrayBuffer(1024*8);
|
||||
|
||||
(function immediate() {
|
||||
this.dbg.memory.trackingTenurePromotions = true;
|
||||
|
||||
this.tests.push( new Object() );
|
||||
this.tests.push( new Array() );
|
||||
this.tests.push( new Uint8Array(256) );
|
||||
this.tests.push( (function () { return arguments; }()) );
|
||||
this.tests.push( AsmModule(this, {}, buf) );
|
||||
this.tests.push( /2manyproblemz/g );
|
||||
this.tests.push( [1,2,3][Symbol.iterator]() );
|
||||
this.tests.push( Error() );
|
||||
this.tests.push( new Ctor );
|
||||
this.tests.push( {} );
|
||||
this.tests.push( new Date );
|
||||
this.tests.push( [1,2,3] );
|
||||
|
||||
}).call(this);
|
||||
|
||||
minorgc();
|
||||
`);
|
||||
|
||||
const promotions = dbg.memory.drainTenurePromotionsLog();
|
||||
print(uneval(promotions));
|
||||
assertEq(promotions.every(p => p.size >= 1), true);
|
@ -7,6 +7,7 @@
|
||||
#include "vm/Debugger-inl.h"
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
@ -46,6 +47,7 @@ using JS::dbg::Builder;
|
||||
using js::frontend::IsIdentifier;
|
||||
using mozilla::ArrayLength;
|
||||
using mozilla::DebugOnly;
|
||||
using mozilla::MakeScopeExit;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::UniquePtr;
|
||||
|
||||
@ -1699,10 +1701,18 @@ Debugger::isDebuggee(const JSCompartment* compartment) const
|
||||
return compartment->isDebuggee() && debuggees.has(compartment->maybeGlobal());
|
||||
}
|
||||
|
||||
Debugger::TenurePromotionsEntry::TenurePromotionsEntry(JSRuntime* rt, JSObject& obj, double when)
|
||||
: className(obj.getClass()->name),
|
||||
when(when),
|
||||
frame(getObjectAllocationSite(obj)),
|
||||
size(JS::ubi::Node(&obj).size(rt->debuggerMallocSizeOf))
|
||||
{ }
|
||||
|
||||
|
||||
void
|
||||
Debugger::logTenurePromotion(JSObject& obj, double when)
|
||||
Debugger::logTenurePromotion(JSRuntime* rt, JSObject& obj, double when)
|
||||
{
|
||||
auto* entry = js_new<TenurePromotionsEntry>(obj, when);
|
||||
auto* entry = js_new<TenurePromotionsEntry>(rt, obj, when);
|
||||
if (!entry)
|
||||
CrashAtUnhandlableOOM("Debugger::logTenurePromotion");
|
||||
|
||||
@ -3298,75 +3308,86 @@ Debugger::addDebuggeeGlobal(JSContext* cx, Handle<GlobalObject*> global)
|
||||
/*
|
||||
* For global to become this js::Debugger's debuggee:
|
||||
*
|
||||
* 1. global must be in this->debuggees,
|
||||
* 2. this js::Debugger must be in global->getDebuggers(),
|
||||
* 1. this js::Debugger must be in global->getDebuggers(),
|
||||
* 2. global must be in this->debuggees,
|
||||
* 3. it must be in zone->getDebuggers(),
|
||||
* 4. JSCompartment::isDebuggee()'s bit must be set, and
|
||||
* 4. the debuggee's zone must be in this->debuggeeZones,
|
||||
* 5. if we are tracking allocations, the SavedStacksMetadataCallback must be
|
||||
* installed for this compartment.
|
||||
* installed for this compartment, and
|
||||
* 6. JSCompartment::isDebuggee()'s bit must be set.
|
||||
*
|
||||
* All five indications must be kept consistent.
|
||||
* All six indications must be kept consistent.
|
||||
*/
|
||||
|
||||
bool inDebuggees = false;
|
||||
bool inGlobalDebuggers = false;
|
||||
bool inZoneDebuggers = false;
|
||||
bool inDebuggeeZones = false;
|
||||
|
||||
AutoCompartment ac(cx, global);
|
||||
Zone* zone = global->zone();
|
||||
|
||||
// (1)
|
||||
auto* globalDebuggers = GlobalObject::getOrCreateDebuggers(cx, global);
|
||||
if (!globalDebuggers)
|
||||
goto error;
|
||||
if (!globalDebuggers->append(this))
|
||||
goto oom;
|
||||
inGlobalDebuggers = true;
|
||||
|
||||
if (!debuggees.put(global))
|
||||
goto oom;
|
||||
inDebuggees = true;
|
||||
|
||||
Zone::DebuggerVector* zoneDebuggers;
|
||||
if (!debuggeeZones.has(zone)) {
|
||||
zoneDebuggers = zone->getOrCreateDebuggers(cx);
|
||||
if (!zoneDebuggers)
|
||||
goto error;
|
||||
if (!zoneDebuggers->append(this))
|
||||
goto oom;
|
||||
inZoneDebuggers = true;
|
||||
|
||||
if (!debuggeeZones.put(zone))
|
||||
goto oom;
|
||||
inDebuggeeZones = true;
|
||||
return false;
|
||||
if (!globalDebuggers->append(this)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
auto globalDebuggersGuard = MakeScopeExit([&] {
|
||||
globalDebuggers->popBack();
|
||||
});
|
||||
|
||||
// (2)
|
||||
if (!debuggees.put(global)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
auto debuggeesGuard = MakeScopeExit([&] {
|
||||
debuggees.remove(global);
|
||||
});
|
||||
|
||||
bool addingZoneRelation = !debuggeeZones.has(zone);
|
||||
|
||||
// (3)
|
||||
auto* zoneDebuggers = zone->getOrCreateDebuggers(cx);
|
||||
if (!zoneDebuggers)
|
||||
return false;
|
||||
if (addingZoneRelation && !zoneDebuggers->append(this)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
auto zoneDebuggersGuard = MakeScopeExit([&] {
|
||||
if (addingZoneRelation)
|
||||
zoneDebuggers->popBack();
|
||||
});
|
||||
|
||||
// (4)
|
||||
if (addingZoneRelation && !debuggeeZones.put(zone)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
auto debuggeeZonesGuard = MakeScopeExit([&] {
|
||||
if (addingZoneRelation)
|
||||
debuggeeZones.remove(zone);
|
||||
});
|
||||
|
||||
// (5)
|
||||
if (trackingAllocationSites && !Debugger::addAllocationsTracking(cx, *global))
|
||||
goto error;
|
||||
return false;
|
||||
auto allocationsTrackingGuard = MakeScopeExit([&] {
|
||||
if (trackingAllocationSites)
|
||||
Debugger::removeAllocationsTracking(*global);
|
||||
});
|
||||
|
||||
// (6)
|
||||
debuggeeCompartment->setIsDebuggee();
|
||||
debuggeeCompartment->updateDebuggerObservesAsmJS();
|
||||
|
||||
if (observesAllExecution() && !ensureExecutionObservabilityOfCompartment(cx, debuggeeCompartment))
|
||||
goto error;
|
||||
return false;
|
||||
|
||||
globalDebuggersGuard.release();
|
||||
debuggeesGuard.release();
|
||||
zoneDebuggersGuard.release();
|
||||
debuggeeZonesGuard.release();
|
||||
allocationsTrackingGuard.release();
|
||||
return true;
|
||||
|
||||
oom:
|
||||
ReportOutOfMemory(cx);
|
||||
// Fall through...
|
||||
|
||||
error:
|
||||
// Maintain consistency on error.
|
||||
if (inGlobalDebuggers)
|
||||
globalDebuggers->popBack();
|
||||
if (inDebuggees)
|
||||
debuggees.remove(global);
|
||||
if (inZoneDebuggers)
|
||||
zoneDebuggers->popBack();
|
||||
if (inDebuggeeZones)
|
||||
debuggeeZones.remove(zone);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -269,7 +269,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void logTenurePromotion(JSObject& obj, double when);
|
||||
void logTenurePromotion(JSRuntime* rt, JSObject& obj, double when);
|
||||
static JSObject* getObjectAllocationSite(JSObject& obj);
|
||||
|
||||
private:
|
||||
@ -286,15 +286,12 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
|
||||
struct TenurePromotionsEntry : public mozilla::LinkedListElement<TenurePromotionsEntry>
|
||||
{
|
||||
TenurePromotionsEntry(JSObject& obj, double when)
|
||||
: className(obj.getClass()->name),
|
||||
when(when),
|
||||
frame(getObjectAllocationSite(obj))
|
||||
{ }
|
||||
TenurePromotionsEntry(JSRuntime* rt, JSObject& obj, double when);
|
||||
|
||||
const char* className;
|
||||
double when;
|
||||
RelocatablePtrObject frame;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
using TenurePromotionsLog = mozilla::LinkedList<TenurePromotionsEntry>;
|
||||
|
@ -387,6 +387,10 @@ DebuggerMemory::drainTenurePromotionsLog(JSContext* cx, unsigned argc, Value* vp
|
||||
if (!DefineProperty(cx, obj, cx->names().class_, classNameValue))
|
||||
return false;
|
||||
|
||||
RootedValue sizeValue(cx, NumberValue(entry->size));
|
||||
if (!DefineProperty(cx, obj, cx->names().size, sizeValue))
|
||||
return false;
|
||||
|
||||
result->setDenseElement(i, ObjectValue(*obj));
|
||||
|
||||
// Pop the front queue entry, and delete it immediately, so that
|
||||
|
@ -693,9 +693,9 @@ FindNotableScriptSources(JS::RuntimeSizes& runtime)
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::CollectRuntimeStats(JSRuntime* rt, RuntimeStats* rtStats, ObjectPrivateVisitor* opv,
|
||||
bool anonymize)
|
||||
static bool
|
||||
CollectRuntimeStatsHelper(JSRuntime* rt, RuntimeStats* rtStats, ObjectPrivateVisitor* opv,
|
||||
bool anonymize, IterateCellCallback statsCellCallback)
|
||||
{
|
||||
if (!rtStats->compartmentStatsVector.reserve(rt->numCompartments))
|
||||
return false;
|
||||
@ -720,7 +720,7 @@ JS::CollectRuntimeStats(JSRuntime* rt, RuntimeStats* rtStats, ObjectPrivateVisit
|
||||
StatsZoneCallback,
|
||||
StatsCompartmentCallback,
|
||||
StatsArenaCallback,
|
||||
StatsCellCallback<FineGrained>);
|
||||
statsCellCallback);
|
||||
|
||||
// Take the "explicit/js/runtime/" measurements.
|
||||
rt->addSizeOfIncludingThis(rtStats->mallocSizeOf_, &rtStats->runtime);
|
||||
@ -728,7 +728,7 @@ JS::CollectRuntimeStats(JSRuntime* rt, RuntimeStats* rtStats, ObjectPrivateVisit
|
||||
if (!FindNotableScriptSources(rtStats->runtime))
|
||||
return false;
|
||||
|
||||
ZoneStatsVector& zs = rtStats->zoneStatsVector;
|
||||
JS::ZoneStatsVector& zs = rtStats->zoneStatsVector;
|
||||
ZoneStats& zTotals = rtStats->zTotals;
|
||||
|
||||
// We don't look for notable strings for zTotals. So we first sum all the
|
||||
@ -743,7 +743,7 @@ JS::CollectRuntimeStats(JSRuntime* rt, RuntimeStats* rtStats, ObjectPrivateVisit
|
||||
|
||||
MOZ_ASSERT(!zTotals.allStrings);
|
||||
|
||||
CompartmentStatsVector& cs = rtStats->compartmentStatsVector;
|
||||
JS::CompartmentStatsVector& cs = rtStats->compartmentStatsVector;
|
||||
CompartmentStats& cTotals = rtStats->cTotals;
|
||||
|
||||
// As with the zones, we sum all compartments first, and then get the
|
||||
@ -790,6 +790,13 @@ JS::CollectRuntimeStats(JSRuntime* rt, RuntimeStats* rtStats, ObjectPrivateVisit
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::CollectRuntimeStats(JSRuntime *rt, RuntimeStats *rtStats, ObjectPrivateVisitor *opv,
|
||||
bool anonymize)
|
||||
{
|
||||
return CollectRuntimeStatsHelper(rt, rtStats, opv, anonymize, StatsCellCallback<FineGrained>);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(size_t)
|
||||
JS::SystemCompartmentCount(JSRuntime* rt)
|
||||
{
|
||||
@ -820,26 +827,26 @@ JS::PeakSizeOfTemporary(const JSRuntime* rt)
|
||||
|
||||
namespace JS {
|
||||
|
||||
class SimpleJSRuntimeStats : public JS::RuntimeStats
|
||||
{
|
||||
public:
|
||||
explicit SimpleJSRuntimeStats(MallocSizeOf mallocSizeOf)
|
||||
: JS::RuntimeStats(mallocSizeOf)
|
||||
{}
|
||||
|
||||
virtual void initExtraZoneStats(JS::Zone* zone, JS::ZoneStats* zStats)
|
||||
override
|
||||
{}
|
||||
|
||||
virtual void initExtraCompartmentStats(
|
||||
JSCompartment* c, JS::CompartmentStats* cStats) override
|
||||
{}
|
||||
};
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
AddSizeOfTab(JSRuntime* rt, HandleObject obj, MallocSizeOf mallocSizeOf, ObjectPrivateVisitor* opv,
|
||||
TabSizes* sizes)
|
||||
{
|
||||
class SimpleJSRuntimeStats : public JS::RuntimeStats
|
||||
{
|
||||
public:
|
||||
explicit SimpleJSRuntimeStats(MallocSizeOf mallocSizeOf)
|
||||
: JS::RuntimeStats(mallocSizeOf)
|
||||
{}
|
||||
|
||||
virtual void initExtraZoneStats(JS::Zone* zone, JS::ZoneStats* zStats)
|
||||
override
|
||||
{}
|
||||
|
||||
virtual void initExtraCompartmentStats(
|
||||
JSCompartment* c, JS::CompartmentStats* cStats) override
|
||||
{}
|
||||
};
|
||||
|
||||
SimpleJSRuntimeStats rtStats(mallocSizeOf);
|
||||
|
||||
JS::Zone* zone = GetObjectZone(obj);
|
||||
@ -855,8 +862,10 @@ AddSizeOfTab(JSRuntime* rt, HandleObject obj, MallocSizeOf mallocSizeOf, ObjectP
|
||||
StatsClosure closure(&rtStats, opv, /* anonymize = */ false);
|
||||
if (!closure.init())
|
||||
return false;
|
||||
IterateZoneCompartmentsArenasCells(rt, zone, &closure, StatsZoneCallback,
|
||||
StatsCompartmentCallback, StatsArenaCallback,
|
||||
IterateZoneCompartmentsArenasCells(rt, zone, &closure,
|
||||
StatsZoneCallback,
|
||||
StatsCompartmentCallback,
|
||||
StatsArenaCallback,
|
||||
StatsCellCallback<CoarseGrained>);
|
||||
|
||||
MOZ_ASSERT(rtStats.zoneStatsVector.length() == 1);
|
||||
@ -874,5 +883,38 @@ AddSizeOfTab(JSRuntime* rt, HandleObject obj, MallocSizeOf mallocSizeOf, ObjectP
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
AddServoSizeOf(JSRuntime *rt, MallocSizeOf mallocSizeOf, ObjectPrivateVisitor *opv,
|
||||
ServoSizes *sizes)
|
||||
{
|
||||
SimpleJSRuntimeStats rtStats(mallocSizeOf);
|
||||
|
||||
// No need to anonymize because the results will be aggregated.
|
||||
if (!CollectRuntimeStatsHelper(rt, &rtStats, opv, /* anonymize = */ false,
|
||||
StatsCellCallback<CoarseGrained>))
|
||||
return false;
|
||||
|
||||
#ifdef DEBUG
|
||||
size_t gcHeapTotalOriginal = sizes->gcHeapUsed +
|
||||
sizes->gcHeapUnused +
|
||||
sizes->gcHeapAdmin +
|
||||
sizes->gcHeapDecommitted;
|
||||
#endif
|
||||
|
||||
rtStats.addToServoSizes(sizes);
|
||||
rtStats.zTotals.addToServoSizes(sizes);
|
||||
rtStats.cTotals.addToServoSizes(sizes);
|
||||
|
||||
#ifdef DEBUG
|
||||
size_t gcHeapTotal = sizes->gcHeapUsed +
|
||||
sizes->gcHeapUnused +
|
||||
sizes->gcHeapAdmin +
|
||||
sizes->gcHeapDecommitted;
|
||||
MOZ_ASSERT(rtStats.gcHeapChunkTotal == gcHeapTotal - gcHeapTotalOriginal);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace JS
|
||||
|
||||
|
@ -226,7 +226,7 @@ public:
|
||||
* sets the container layer children to layers which together render
|
||||
* the contents of the display list. It reuses existing layers from
|
||||
* the retained layer manager if possible.
|
||||
* aContainer may be null, in which case we construct a root layer.
|
||||
* aContainerItem may be null, in which case we construct a root layer.
|
||||
* This gets called by display list code. It calls BuildLayer on the
|
||||
* items in the display list, making items with their own layers
|
||||
* children of the new container, and assigning all other items to
|
||||
@ -479,7 +479,7 @@ public:
|
||||
* longer than the transaction.
|
||||
*
|
||||
* Updates the geometry, frame list and clip.
|
||||
* For items within a PaintedLayer, a geometry object must be specifed to retain
|
||||
* For items within a PaintedLayer, a geometry object must be specified to retain
|
||||
* until the next transaction.
|
||||
*
|
||||
*/
|
||||
|
@ -1018,7 +1018,7 @@ protected:
|
||||
* class represents an entity that can be drawn on the screen, e.g., a
|
||||
* frame's CSS background, or a frame's text string.
|
||||
*
|
||||
* nsDisplayListItems can be containers --- i.e., they can perform hit testing
|
||||
* nsDisplayItems can be containers --- i.e., they can perform hit testing
|
||||
* and painting by recursively traversing a list of child items.
|
||||
*
|
||||
* These are arena-allocated during display list construction. A typical
|
||||
@ -1615,8 +1615,8 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a new item to the top of the list. If the item is null we return
|
||||
* NS_ERROR_OUT_OF_MEMORY. The intended usage is AppendNewToTop(new ...);
|
||||
* Append a new item to the top of the list. The intended usage is
|
||||
* AppendNewToTop(new ...);
|
||||
*/
|
||||
void AppendNewToTop(nsDisplayItem* aItem) {
|
||||
if (aItem) {
|
||||
@ -1625,8 +1625,8 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a new item to the bottom of the list. If the item is null we return
|
||||
* NS_ERROR_OUT_OF_MEMORY. The intended usage is AppendNewToBottom(new ...);
|
||||
* Append a new item to the bottom of the list. The intended usage is
|
||||
* AppendNewToBottom(new ...);
|
||||
*/
|
||||
void AppendNewToBottom(nsDisplayItem* aItem) {
|
||||
if (aItem) {
|
||||
|
@ -1751,40 +1751,6 @@ nsListControlFrame::GetIndexFromDOMEvent(nsIDOMEvent* aMouseEvent,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int32_t numOptions = GetNumberOfOptions();
|
||||
if (numOptions < 1)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsPoint pt = nsLayoutUtils::GetDOMEventCoordinatesRelativeTo(aMouseEvent, this);
|
||||
|
||||
// If the event coordinate is above the first option frame, then target the
|
||||
// first option frame
|
||||
nsRefPtr<dom::HTMLOptionElement> firstOption = GetOption(0);
|
||||
NS_ASSERTION(firstOption, "Can't find first option that's supposed to be there");
|
||||
nsIFrame* optionFrame = firstOption->GetPrimaryFrame();
|
||||
if (optionFrame) {
|
||||
nsPoint ptInOptionFrame = pt - optionFrame->GetOffsetTo(this);
|
||||
if (ptInOptionFrame.y < 0 && ptInOptionFrame.x >= 0 &&
|
||||
ptInOptionFrame.x < optionFrame->GetSize().width) {
|
||||
aCurIndex = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<dom::HTMLOptionElement> lastOption = GetOption(numOptions - 1);
|
||||
// If the event coordinate is below the last option frame, then target the
|
||||
// last option frame
|
||||
NS_ASSERTION(lastOption, "Can't find last option that's supposed to be there");
|
||||
optionFrame = lastOption->GetPrimaryFrame();
|
||||
if (optionFrame) {
|
||||
nsPoint ptInOptionFrame = pt - optionFrame->GetOffsetTo(this);
|
||||
if (ptInOptionFrame.y >= optionFrame->GetSize().height && ptInOptionFrame.x >= 0 &&
|
||||
ptInOptionFrame.x < optionFrame->GetSize().width) {
|
||||
aCurIndex = numOptions - 1;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -125,19 +125,14 @@ FontFaceSet::FontFaceSet(nsPIDOMWindow* aWindow, nsIDocument* aDocument)
|
||||
mUserFontSet = new UserFontSet(this);
|
||||
}
|
||||
|
||||
static PLDHashOperator DestroyIterator(nsPtrHashKey<nsFontFaceLoader>* aKey,
|
||||
void* aUserArg)
|
||||
{
|
||||
aKey->GetKey()->Cancel();
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
FontFaceSet::~FontFaceSet()
|
||||
{
|
||||
MOZ_COUNT_DTOR(FontFaceSet);
|
||||
|
||||
Disconnect();
|
||||
mLoaders.EnumerateEntries(DestroyIterator, nullptr);
|
||||
for (auto it = mLoaders.Iter(); !it.Done(); it.Next()) {
|
||||
it.Get()->GetKey()->Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
@ -45,22 +45,6 @@ ImageLoader::SetAnimationModeEnumerator(nsISupports* aKey, FrameSet* aValue,
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
ClearImageHashSet(nsPtrHashKey<ImageLoader::Image>* aKey, void* aClosure)
|
||||
{
|
||||
nsIDocument* doc = static_cast<nsIDocument*>(aClosure);
|
||||
ImageLoader::Image* image = aKey->GetKey();
|
||||
|
||||
imgIRequest* request = image->mRequests.GetWeak(doc);
|
||||
if (request) {
|
||||
request->CancelAndForgetObserver(NS_BINDING_ABORTED);
|
||||
}
|
||||
|
||||
image->mRequests.Remove(doc);
|
||||
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::DropDocumentReference()
|
||||
{
|
||||
@ -68,7 +52,17 @@ ImageLoader::DropDocumentReference()
|
||||
// on the document being null) as that means the presshell has already
|
||||
// been destroyed, and it also calls ClearFrames when it is destroyed.
|
||||
ClearFrames(GetPresContext());
|
||||
mImages.EnumerateEntries(&ClearImageHashSet, mDocument);
|
||||
|
||||
for (auto it = mImages.Iter(); !it.Done(); it.Next()) {
|
||||
ImageLoader::Image* image = it.Get()->GetKey();
|
||||
imgIRequest* request = image->mRequests.GetWeak(mDocument);
|
||||
if (request) {
|
||||
request->CancelAndForgetObserver(NS_BINDING_ABORTED);
|
||||
}
|
||||
image->mRequests.Remove(mDocument);
|
||||
}
|
||||
mImages.Clear();
|
||||
|
||||
mDocument = nullptr;
|
||||
}
|
||||
|
||||
|
@ -659,30 +659,6 @@ nsSVGEffects::GetFilterProperty(nsIFrame *aFrame)
|
||||
(aFrame->Properties().Get(FilterProperty()));
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
GatherEnumerator(nsPtrHashKey<nsSVGRenderingObserver>* aEntry, void* aArg)
|
||||
{
|
||||
nsTArray<nsSVGRenderingObserver*>* array =
|
||||
static_cast<nsTArray<nsSVGRenderingObserver*>*>(aArg);
|
||||
array->AppendElement(aEntry->GetKey());
|
||||
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
GatherEnumeratorForReflow(nsPtrHashKey<nsSVGRenderingObserver>* aEntry, void* aArg)
|
||||
{
|
||||
if (!aEntry->GetKey()->ObservesReflow()) {
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsTArray<nsSVGRenderingObserver*>* array =
|
||||
static_cast<nsTArray<nsSVGRenderingObserver*>*>(aArg);
|
||||
array->AppendElement(aEntry->GetKey());
|
||||
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGRenderingObserverList::InvalidateAll()
|
||||
{
|
||||
@ -691,8 +667,10 @@ nsSVGRenderingObserverList::InvalidateAll()
|
||||
|
||||
nsAutoTArray<nsSVGRenderingObserver*,10> observers;
|
||||
|
||||
// The PL_DHASH_REMOVE in GatherEnumerator drops all our observers here:
|
||||
mObservers.EnumerateEntries(GatherEnumerator, &observers);
|
||||
for (auto it = mObservers.Iter(); !it.Done(); it.Next()) {
|
||||
observers.AppendElement(it.Get()->GetKey());
|
||||
}
|
||||
mObservers.Clear();
|
||||
|
||||
for (uint32_t i = 0; i < observers.Length(); ++i) {
|
||||
observers[i]->InvalidateViaReferencedElement();
|
||||
@ -707,8 +685,13 @@ nsSVGRenderingObserverList::InvalidateAllForReflow()
|
||||
|
||||
nsAutoTArray<nsSVGRenderingObserver*,10> observers;
|
||||
|
||||
// The PL_DHASH_REMOVE in GatherEnumerator drops all our observers here:
|
||||
mObservers.EnumerateEntries(GatherEnumeratorForReflow, &observers);
|
||||
for (auto it = mObservers.Iter(); !it.Done(); it.Next()) {
|
||||
nsSVGRenderingObserver* obs = it.Get()->GetKey();
|
||||
if (obs->ObservesReflow()) {
|
||||
observers.AppendElement(obs);
|
||||
it.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < observers.Length(); ++i) {
|
||||
observers[i]->InvalidateViaReferencedElement();
|
||||
@ -720,8 +703,10 @@ nsSVGRenderingObserverList::RemoveAll()
|
||||
{
|
||||
nsAutoTArray<nsSVGRenderingObserver*,10> observers;
|
||||
|
||||
// The PL_DHASH_REMOVE in GatherEnumerator drops all our observers here:
|
||||
mObservers.EnumerateEntries(GatherEnumerator, &observers);
|
||||
for (auto it = mObservers.Iter(); !it.Done(); it.Next()) {
|
||||
observers.AppendElement(it.Get()->GetKey());
|
||||
}
|
||||
mObservers.Clear();
|
||||
|
||||
// Our list is now cleared. We need to notify the observers we've removed,
|
||||
// so they can update their state & remove themselves as mutation-observers.
|
||||
|
@ -623,19 +623,14 @@ nsDisplayOuterSVG::Paint(nsDisplayListBuilder* aBuilder,
|
||||
#endif
|
||||
}
|
||||
|
||||
static PLDHashOperator CheckForeignObjectInvalidatedArea(nsPtrHashKey<nsSVGForeignObjectFrame>* aEntry, void* aData)
|
||||
{
|
||||
nsRegion* region = static_cast<nsRegion*>(aData);
|
||||
region->Or(*region, aEntry->GetKey()->GetInvalidRegion());
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsRegion
|
||||
nsSVGOuterSVGFrame::FindInvalidatedForeignObjectFrameChildren(nsIFrame* aFrame)
|
||||
{
|
||||
nsRegion result;
|
||||
if (mForeignObjectHash && mForeignObjectHash->Count()) {
|
||||
mForeignObjectHash->EnumerateEntries(CheckForeignObjectInvalidatedArea, &result);
|
||||
for (auto it = mForeignObjectHash->Iter(); !it.Done(); it.Next()) {
|
||||
result.Or(result, it.Get()->GetKey()->GetInvalidRegion());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
if (!mInflated) {
|
||||
if (!mInflated || getVisibility() == View.GONE) {
|
||||
// There's nothing to hide yet.
|
||||
return;
|
||||
}
|
||||
@ -104,8 +104,13 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
||||
// Always clear the Find string, primarily for privacy.
|
||||
mFindText.setText("");
|
||||
|
||||
// Only close the IMM if its EditText is the one with focus.
|
||||
if (mFindText.isFocused()) {
|
||||
getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
|
||||
}
|
||||
|
||||
// Close the FIPB / FindHelper state.
|
||||
setVisibility(GONE);
|
||||
getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Closed", null));
|
||||
}
|
||||
|
||||
|
BIN
mobile/android/base/resources/drawable-hdpi/flat_icon.png
Normal file
BIN
mobile/android/base/resources/drawable-hdpi/flat_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 807 B |
BIN
mobile/android/base/resources/drawable-xhdpi/flat_icon.png
Normal file
BIN
mobile/android/base/resources/drawable-xhdpi/flat_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
BIN
mobile/android/base/resources/drawable-xxhdpi/flat_icon.png
Normal file
BIN
mobile/android/base/resources/drawable-xxhdpi/flat_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
@ -267,7 +267,7 @@ public class CommandProcessor {
|
||||
final NotificationManager notificationManager = (NotificationManager) context.getSystemService(ns);
|
||||
|
||||
// Create a Notification.
|
||||
final int icon = R.drawable.icon;
|
||||
final int icon = R.drawable.flat_icon;
|
||||
String notificationTitle = context.getString(R.string.sync_new_tab);
|
||||
if (title != null) {
|
||||
notificationTitle = notificationTitle.concat(": " + title);
|
||||
|
@ -9,7 +9,7 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
function init() {
|
||||
// Include the build date and a warning about Telemetry
|
||||
// if this is an "a#" (nightly or aurora) build
|
||||
#expand const version = "__MOZ_APP_VERSION_ABOUT__";
|
||||
#expand const version = "__MOZ_APP_VERSION_DISPLAY__";
|
||||
if (/a\d+$/.test(version)) {
|
||||
let buildID = Services.appinfo.appBuildID;
|
||||
let buildDate = buildID.slice(0, 4) + "-" + buildID.slice(4, 6) + "-" + buildID.slice(6, 8);
|
||||
|
@ -24,7 +24,7 @@
|
||||
<body dir="&locale.dir;">
|
||||
<div id="header">
|
||||
<div id="wordmark"></div>
|
||||
#expand <p id="version">__MOZ_APP_VERSION_ABOUT__</p>
|
||||
#expand <p id="version">__MOZ_APP_VERSION_DISPLAY__</p>
|
||||
</div>
|
||||
|
||||
<div id="banner">
|
||||
|
@ -7,7 +7,7 @@
|
||||
DEFINES['AB_CD'] = CONFIG['MOZ_UI_LOCALE']
|
||||
DEFINES['PACKAGE'] = 'browser'
|
||||
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
|
||||
DEFINES['MOZ_APP_VERSION_ABOUT'] = CONFIG['MOZ_APP_VERSION_ABOUT']
|
||||
DEFINES['MOZ_APP_VERSION_DISPLAY'] = CONFIG['MOZ_APP_VERSION_DISPLAY']
|
||||
DEFINES['ANDROID_PACKAGE_NAME'] = CONFIG['ANDROID_PACKAGE_NAME']
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
@ -92,7 +92,6 @@ class CommandAction(argparse.Action):
|
||||
elif values:
|
||||
command = values[0].lower()
|
||||
args = values[1:]
|
||||
|
||||
if command == 'help':
|
||||
if args and args[0] not in ['-h', '--help']:
|
||||
# Make sure args[0] is indeed a command.
|
||||
@ -102,8 +101,17 @@ class CommandAction(argparse.Action):
|
||||
sys.exit(0)
|
||||
elif '-h' in args or '--help' in args:
|
||||
# -h or --help is in the command arguments.
|
||||
self._handle_command_help(parser, command)
|
||||
sys.exit(0)
|
||||
if '--' in args:
|
||||
# -- is in command arguments
|
||||
if '-h' in args[:args.index('--')] or '--help' in args[:args.index('--')]:
|
||||
# Honor -h or --help only if it appears before --
|
||||
self._handle_main_help(parser, command)
|
||||
sys.exit(0)
|
||||
else:
|
||||
self._handle_main_help(parser, command)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
else:
|
||||
raise NoCommandError()
|
||||
|
||||
|
@ -12,7 +12,6 @@ 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", "--screenshot-on-fail",
|
||||
"--total-chunks=16",
|
||||
],
|
||||
},
|
||||
"mochitest-gl": {
|
||||
|
@ -13,7 +13,6 @@ 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", "--screenshot-on-fail",
|
||||
"--total-chunks=16",
|
||||
],
|
||||
},
|
||||
"mochitest-gl": {
|
||||
|
@ -10,6 +10,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Troubleshoot.jsm");
|
||||
Cu.import("resource://gre/modules/ResetProfile.jsm");
|
||||
Cu.import("resource://gre/modules/AppConstants.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
|
||||
"resource://gre/modules/PluralForm.jsm");
|
||||
@ -37,7 +38,7 @@ let snapshotFormatters = {
|
||||
$("application-box").textContent = data.name;
|
||||
$("useragent-box").textContent = data.userAgent;
|
||||
$("supportLink").href = data.supportURL;
|
||||
let version = data.version;
|
||||
let version = AppConstants.MOZ_APP_VERSION_DISPLAY;
|
||||
if (data.vendor)
|
||||
version += " (" + data.vendor + ")";
|
||||
$("version-box").textContent = version;
|
||||
|
@ -189,7 +189,7 @@ function runTests()
|
||||
synthesizeMouse(document.getElementById("option3"), 2, 2, { type: "mousedown" });
|
||||
synthesizeMouse(document.getElementById("option3"), 2, 1000, { type: "mousemove" });
|
||||
var select = document.getElementById("select");
|
||||
is(select.selectedIndex, 9, "scroll select");
|
||||
is(select.selectedIndex, 2, "scroll select");
|
||||
synthesizeMouse(document.getElementById("select"), 2, 2, { type: "mouseup" });
|
||||
|
||||
synthesizeMouse(custom, 2, 2, { type: "mousedown" });
|
||||
|
@ -355,25 +355,45 @@ define('source-map/source-map-consumer', ['require', 'exports', 'module' , 'sou
|
||||
function SourceMapConsumer_fromSourceMap(aSourceMap) {
|
||||
var smc = Object.create(BasicSourceMapConsumer.prototype);
|
||||
|
||||
smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
|
||||
smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
|
||||
var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
|
||||
var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
|
||||
smc.sourceRoot = aSourceMap._sourceRoot;
|
||||
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
|
||||
smc.sourceRoot);
|
||||
smc.file = aSourceMap._file;
|
||||
|
||||
smc.__generatedMappings = aSourceMap._mappings.toArray().slice();
|
||||
smc.__originalMappings = aSourceMap._mappings.toArray().slice().sort();
|
||||
// Because we are modifying the entries (by converting string sources and
|
||||
// names to indices into the sources and names ArraySets), we have to make
|
||||
// a copy of the entry or else bad things happen. Shared mutable state
|
||||
// strikes again! See github issue #191.
|
||||
|
||||
smc.__generatedMappings.forEach(function (m) {
|
||||
if (m.source !== null) {
|
||||
m.source = smc._sources.indexOf(m.source);
|
||||
var generatedMappings = aSourceMap._mappings.toArray().slice();
|
||||
var destGeneratedMappings = smc.__generatedMappings = [];
|
||||
var destOriginalMappings = smc.__originalMappings = [];
|
||||
|
||||
if (m.name !== null) {
|
||||
m.name = smc._names.indexOf(m.name);
|
||||
for (var i = 0, length = generatedMappings.length; i < length; i++) {
|
||||
var srcMapping = generatedMappings[i];
|
||||
var destMapping = new Mapping;
|
||||
destMapping.generatedLine = srcMapping.generatedLine;
|
||||
destMapping.generatedColumn = srcMapping.generatedColumn;
|
||||
|
||||
if (srcMapping.source) {
|
||||
destMapping.source = sources.indexOf(srcMapping.source);
|
||||
destMapping.originalLine = srcMapping.originalLine;
|
||||
destMapping.originalColumn = srcMapping.originalColumn;
|
||||
|
||||
if (srcMapping.name) {
|
||||
destMapping.name = names.indexOf(srcMapping.name);
|
||||
}
|
||||
|
||||
destOriginalMappings.push(destMapping);
|
||||
}
|
||||
});
|
||||
|
||||
destGeneratedMappings.push(destMapping);
|
||||
}
|
||||
|
||||
quickSort(smc.__originalMappings, util.compareByOriginalPositions);
|
||||
|
||||
return smc;
|
||||
};
|
||||
|
||||
@ -507,7 +527,7 @@ define('source-map/source-map-consumer', ['require', 'exports', 'module' , 'sou
|
||||
}
|
||||
}
|
||||
|
||||
quickSort(generatedMappings, util.compareByGeneratedPositions);
|
||||
quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated);
|
||||
this.__generatedMappings = generatedMappings;
|
||||
|
||||
quickSort(originalMappings, util.compareByOriginalPositions);
|
||||
@ -597,7 +617,7 @@ define('source-map/source-map-consumer', ['require', 'exports', 'module' , 'sou
|
||||
this._generatedMappings,
|
||||
"generatedLine",
|
||||
"generatedColumn",
|
||||
util.compareByGeneratedPositions,
|
||||
util.compareByGeneratedPositionsDeflated,
|
||||
util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)
|
||||
);
|
||||
|
||||
@ -1066,7 +1086,7 @@ define('source-map/source-map-consumer', ['require', 'exports', 'module' , 'sou
|
||||
};
|
||||
};
|
||||
|
||||
quickSort(this.__generatedMappings, util.compareByGeneratedPositions);
|
||||
quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated);
|
||||
quickSort(this.__originalMappings, util.compareByOriginalPositions);
|
||||
};
|
||||
|
||||
@ -1355,15 +1375,15 @@ define('source-map/util', ['require', 'exports', 'module' , ], function(require,
|
||||
exports.compareByOriginalPositions = compareByOriginalPositions;
|
||||
|
||||
/**
|
||||
* Comparator between two mappings where the generated positions are
|
||||
* compared.
|
||||
* Comparator between two mappings with deflated source and name indices where
|
||||
* the generated positions are compared.
|
||||
*
|
||||
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
|
||||
* mappings with the same generated line and column, but different
|
||||
* source/name/original line and column the same. Useful when searching for a
|
||||
* mapping with a stubbed out mapping.
|
||||
*/
|
||||
function compareByGeneratedPositions(mappingA, mappingB, onlyCompareGenerated) {
|
||||
function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
|
||||
var cmp = mappingA.generatedLine - mappingB.generatedLine;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
@ -1391,7 +1411,53 @@ define('source-map/util', ['require', 'exports', 'module' , ], function(require,
|
||||
|
||||
return mappingA.name - mappingB.name;
|
||||
};
|
||||
exports.compareByGeneratedPositions = compareByGeneratedPositions;
|
||||
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
|
||||
|
||||
function strcmp(aStr1, aStr2) {
|
||||
if (aStr1 === aStr2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (aStr1 > aStr2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparator between two mappings with inflated source and name strings where
|
||||
* the generated positions are compared.
|
||||
*/
|
||||
function compareByGeneratedPositionsInflated(mappingA, mappingB) {
|
||||
var cmp = mappingA.generatedLine - mappingB.generatedLine;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = strcmp(mappingA.source, mappingB.source);
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.originalLine - mappingB.originalLine;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
return strcmp(mappingA.name, mappingB.name);
|
||||
};
|
||||
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
|
||||
|
||||
});
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
@ -2238,7 +2304,6 @@ define('source-map/source-map-generator', ['require', 'exports', 'module' , 'so
|
||||
var mapping;
|
||||
|
||||
var mappings = this._mappings.toArray();
|
||||
|
||||
for (var i = 0, len = mappings.length; i < len; i++) {
|
||||
mapping = mappings[i];
|
||||
|
||||
@ -2251,7 +2316,7 @@ define('source-map/source-map-generator', ['require', 'exports', 'module' , 'so
|
||||
}
|
||||
else {
|
||||
if (i > 0) {
|
||||
if (!util.compareByGeneratedPositions(mapping, mappings[i - 1])) {
|
||||
if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
|
||||
continue;
|
||||
}
|
||||
result += ',';
|
||||
@ -2360,7 +2425,7 @@ define('source-map/mapping-list', ['require', 'exports', 'module' , 'source-map
|
||||
var columnA = mappingA.generatedColumn;
|
||||
var columnB = mappingB.generatedColumn;
|
||||
return lineB > lineA || lineB == lineA && columnB >= columnA ||
|
||||
util.compareByGeneratedPositions(mappingA, mappingB) <= 0;
|
||||
util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2413,7 +2478,7 @@ define('source-map/mapping-list', ['require', 'exports', 'module' , 'source-map
|
||||
*/
|
||||
MappingList.prototype.toArray = function MappingList_toArray() {
|
||||
if (!this._sorted) {
|
||||
this._array.sort(util.compareByGeneratedPositions);
|
||||
this._array.sort(util.compareByGeneratedPositionsInflated);
|
||||
this._sorted = true;
|
||||
}
|
||||
return this._array;
|
||||
|
@ -652,15 +652,15 @@ define('lib/source-map/util', ['require', 'exports', 'module' , ], function(requ
|
||||
exports.compareByOriginalPositions = compareByOriginalPositions;
|
||||
|
||||
/**
|
||||
* Comparator between two mappings where the generated positions are
|
||||
* compared.
|
||||
* Comparator between two mappings with deflated source and name indices where
|
||||
* the generated positions are compared.
|
||||
*
|
||||
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
|
||||
* mappings with the same generated line and column, but different
|
||||
* source/name/original line and column the same. Useful when searching for a
|
||||
* mapping with a stubbed out mapping.
|
||||
*/
|
||||
function compareByGeneratedPositions(mappingA, mappingB, onlyCompareGenerated) {
|
||||
function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
|
||||
var cmp = mappingA.generatedLine - mappingB.generatedLine;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
@ -688,7 +688,53 @@ define('lib/source-map/util', ['require', 'exports', 'module' , ], function(requ
|
||||
|
||||
return mappingA.name - mappingB.name;
|
||||
};
|
||||
exports.compareByGeneratedPositions = compareByGeneratedPositions;
|
||||
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
|
||||
|
||||
function strcmp(aStr1, aStr2) {
|
||||
if (aStr1 === aStr2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (aStr1 > aStr2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparator between two mappings with inflated source and name strings where
|
||||
* the generated positions are compared.
|
||||
*/
|
||||
function compareByGeneratedPositionsInflated(mappingA, mappingB) {
|
||||
var cmp = mappingA.generatedLine - mappingB.generatedLine;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = strcmp(mappingA.source, mappingB.source);
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.originalLine - mappingB.originalLine;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
||||
if (cmp !== 0) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
return strcmp(mappingA.name, mappingB.name);
|
||||
};
|
||||
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
|
||||
|
||||
});
|
||||
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||
|
@ -1062,6 +1062,30 @@ define("test/source-map/test-source-map-consumer", ["require", "exports", "modul
|
||||
assert.equal(pos.column, 4);
|
||||
};
|
||||
|
||||
exports['test issue #191'] = function (assert, util) {
|
||||
var generator = new SourceMapGenerator({ file: 'a.css' });
|
||||
generator.addMapping({
|
||||
source: 'b.css',
|
||||
original: {
|
||||
line: 1,
|
||||
column: 0
|
||||
},
|
||||
generated: {
|
||||
line: 1,
|
||||
column: 0
|
||||
}
|
||||
});
|
||||
|
||||
// Create a SourceMapConsumer from the SourceMapGenerator, ...
|
||||
var consumer = SourceMapConsumer.fromSourceMap(generator);
|
||||
// ... and then try and use the SourceMapGenerator again. This should not
|
||||
// throw.
|
||||
generator.toJSON();
|
||||
|
||||
assert.ok(true, "Using a SourceMapGenerator again after creating a " +
|
||||
"SourceMapConsumer from it should not throw");
|
||||
};
|
||||
|
||||
});
|
||||
function run_test() {
|
||||
runSourceMapTests('test/source-map/test-source-map-consumer', do_throw);
|
||||
|
@ -723,6 +723,30 @@ define("test/source-map/test-source-map-generator", ["require", "exports", "modu
|
||||
|
||||
util.assertEqualMaps(assert, map1.toJSON(), expectedMap.toJSON());
|
||||
};
|
||||
|
||||
exports['test issue #192'] = function (assert, util) {
|
||||
var generator = new SourceMapGenerator();
|
||||
generator.addMapping({
|
||||
source: 'a.js',
|
||||
generated: { line: 1, column: 10 },
|
||||
original: { line: 1, column: 10 },
|
||||
});
|
||||
generator.addMapping({
|
||||
source: 'b.js',
|
||||
generated: { line: 1, column: 10 },
|
||||
original: { line: 2, column: 20 },
|
||||
});
|
||||
|
||||
var consumer = new SourceMapConsumer(generator.toJSON());
|
||||
|
||||
var n = 0;
|
||||
consumer.eachMapping(function () { n++ });
|
||||
|
||||
assert.equal(n, 2,
|
||||
"Should not de-duplicate mappings that have the same " +
|
||||
"generated positions, but different original positions.");
|
||||
};
|
||||
|
||||
});
|
||||
function run_test() {
|
||||
runSourceMapTests('test/source-map/test-source-map-generator', do_throw);
|
||||
|
@ -172,6 +172,7 @@ this.AppConstants = Object.freeze({
|
||||
|
||||
MOZ_APP_NAME: "@MOZ_APP_NAME@",
|
||||
MOZ_APP_VERSION: "@MOZ_APP_VERSION@",
|
||||
MOZ_APP_VERSION_DISPLAY: "@MOZ_APP_VERSION_DISPLAY@",
|
||||
MOZ_BUILD_APP: "@MOZ_BUILD_APP@",
|
||||
MOZ_UPDATE_CHANNEL: "@MOZ_UPDATE_CHANNEL@",
|
||||
MOZ_WIDGET_TOOLKIT: "@MOZ_WIDGET_TOOLKIT@",
|
||||
|
@ -172,7 +172,7 @@ let dataProviders = {
|
||||
application: function application(done) {
|
||||
let data = {
|
||||
name: Services.appinfo.name,
|
||||
version: Services.appinfo.version,
|
||||
version: AppConstants.MOZ_APP_VERSION_DISPLAY,
|
||||
buildID: Services.appinfo.appBuildID,
|
||||
userAgent: Cc["@mozilla.org/network/protocol;1?name=http"].
|
||||
getService(Ci.nsIHttpProtocolHandler).
|
||||
|
@ -101,6 +101,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
for var in ('ANDROID_PACKAGE_NAME',
|
||||
'MOZ_APP_NAME',
|
||||
'MOZ_APP_VERSION',
|
||||
'MOZ_APP_VERSION_DISPLAY',
|
||||
'MOZ_WIDGET_TOOLKIT',
|
||||
'DLL_PREFIX',
|
||||
'DLL_SUFFIX'):
|
||||
|
60
tools/rewriting/ThirdPartyPaths.txt
Normal file
60
tools/rewriting/ThirdPartyPaths.txt
Normal file
@ -0,0 +1,60 @@
|
||||
browser/components/translation/cld2/
|
||||
build/stlport/
|
||||
db/sqlite3/src/
|
||||
dom/media/platforms/ffmpeg/libav
|
||||
extensions/spellcheck/hunspell/src/*.cxx
|
||||
extensions/spellcheck/hunspell/src/*.hxx
|
||||
gfx/2d/convolver
|
||||
gfx/2d/image_operations
|
||||
gfx/angle/
|
||||
gfx/cairo/
|
||||
gfx/graphite2/
|
||||
gfx/harfbuzz/
|
||||
gfx/ots/
|
||||
gfx/qcms/
|
||||
gfx/skia/
|
||||
gfx/ycbcr/
|
||||
intl/hyphenation/
|
||||
intl/icu/
|
||||
ipc/chromium/
|
||||
js/src/jit/arm64/vixl/
|
||||
media/kiss_ftt/
|
||||
media/libav/
|
||||
media/libcubeb/
|
||||
media/libjpeg/
|
||||
media/libmkv/
|
||||
media/libnestegg/
|
||||
media/libogg/
|
||||
media/libopus/
|
||||
media/libpng/
|
||||
media/libsoundtouch/
|
||||
media/libspeex_resampler/
|
||||
media/libstagefright/
|
||||
media/libtheora/
|
||||
media/libtremor/
|
||||
media/libvorbis/
|
||||
media/libvpx/
|
||||
media/libyuv/
|
||||
media/mtransport/
|
||||
media/openmax_dl/
|
||||
media/pocketsphinx/
|
||||
media/sphinxbase/
|
||||
media/webrtc/trunk/
|
||||
memory/jemalloc/src/
|
||||
mfbt/decimal/
|
||||
mfbt/double-conversion/
|
||||
mfbt/lz4
|
||||
modules/brotli/
|
||||
modules/freetype2/
|
||||
modules/libbz2/
|
||||
modules/libmar/
|
||||
modules/zlib/
|
||||
netwerk/sctp/src/
|
||||
netwerk/srtp/src/
|
||||
nsprpub/
|
||||
other-licenses/
|
||||
security/sandbox/chromium/
|
||||
testing/gtest/gmock/
|
||||
testing/gtest/gtest/
|
||||
toolkit/components/protobuf/
|
||||
toolkit/crashreporter/google-breakpad/
|
@ -792,30 +792,49 @@ PL_DHashTableSizeOfIncludingThis(
|
||||
|
||||
PLDHashTable::Iterator::Iterator(Iterator&& aOther)
|
||||
: mTable(aOther.mTable)
|
||||
, mCurrent(aOther.mCurrent)
|
||||
, mStart(aOther.mStart)
|
||||
, mLimit(aOther.mLimit)
|
||||
, mCurrent(aOther.mCurrent)
|
||||
, mNexts(aOther.mNexts)
|
||||
, mNextsLimit(aOther.mNextsLimit)
|
||||
, mHaveRemoved(aOther.mHaveRemoved)
|
||||
{
|
||||
// No need to change |mChecker| here.
|
||||
aOther.mTable = nullptr;
|
||||
aOther.mCurrent = nullptr;
|
||||
aOther.mStart = nullptr;
|
||||
aOther.mLimit = nullptr;
|
||||
aOther.mCurrent = nullptr;
|
||||
aOther.mNexts = 0;
|
||||
aOther.mNextsLimit = 0;
|
||||
aOther.mHaveRemoved = false;
|
||||
}
|
||||
|
||||
PLDHashTable::Iterator::Iterator(PLDHashTable* aTable)
|
||||
: mTable(aTable)
|
||||
, mCurrent(mTable->mEntryStore)
|
||||
, mStart(mTable->mEntryStore)
|
||||
, mLimit(mTable->mEntryStore + mTable->Capacity() * mTable->mEntrySize)
|
||||
, mCurrent(mTable->mEntryStore)
|
||||
, mNexts(0)
|
||||
, mNextsLimit(mTable->EntryCount())
|
||||
, mHaveRemoved(false)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
mTable->mChecker.StartReadOp();
|
||||
#endif
|
||||
|
||||
// Advance to the first live entry, or to the end if there are none.
|
||||
while (IsOnNonLiveEntry()) {
|
||||
mCurrent += mTable->mEntrySize;
|
||||
if (ChaosMode::isActive(ChaosMode::HashTableIteration) &&
|
||||
mTable->Capacity() > 0) {
|
||||
// Start iterating at a random entry. It would be even more chaotic to
|
||||
// iterate in fully random order, but that's harder.
|
||||
mCurrent += ChaosMode::randomUint32LessThan(mTable->Capacity()) *
|
||||
mTable->mEntrySize;
|
||||
}
|
||||
|
||||
// Advance to the first live entry, if there is one.
|
||||
if (!Done()) {
|
||||
while (IsOnNonLiveEntry()) {
|
||||
MoveToNextEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -834,13 +853,23 @@ PLDHashTable::Iterator::~Iterator()
|
||||
bool
|
||||
PLDHashTable::Iterator::Done() const
|
||||
{
|
||||
return mCurrent == mLimit;
|
||||
return mNexts == mNextsLimit;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
PLDHashTable::Iterator::IsOnNonLiveEntry() const
|
||||
{
|
||||
return !Done() && !ENTRY_IS_LIVE(reinterpret_cast<PLDHashEntryHdr*>(mCurrent));
|
||||
MOZ_ASSERT(!Done());
|
||||
return !ENTRY_IS_LIVE(reinterpret_cast<PLDHashEntryHdr*>(mCurrent));
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE void
|
||||
PLDHashTable::Iterator::MoveToNextEntry()
|
||||
{
|
||||
mCurrent += mTable->mEntrySize;
|
||||
if (mCurrent == mLimit) {
|
||||
mCurrent = mStart; // Wrap-around. Possible due to Chaos Mode.
|
||||
}
|
||||
}
|
||||
|
||||
PLDHashEntryHdr*
|
||||
@ -858,9 +887,14 @@ PLDHashTable::Iterator::Next()
|
||||
{
|
||||
MOZ_ASSERT(!Done());
|
||||
|
||||
do {
|
||||
mCurrent += mTable->mEntrySize;
|
||||
} while (IsOnNonLiveEntry());
|
||||
mNexts++;
|
||||
|
||||
// Advance to the next live entry, if there is one.
|
||||
if (!Done()) {
|
||||
do {
|
||||
MoveToNextEntry();
|
||||
} while (IsOnNonLiveEntry());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -393,12 +393,16 @@ public:
|
||||
PLDHashTable* mTable; // Main table pointer.
|
||||
|
||||
private:
|
||||
char* mCurrent; // Pointer to the current entry.
|
||||
char* mStart; // The first entry.
|
||||
char* mLimit; // One past the last entry.
|
||||
char* mCurrent; // Pointer to the current entry.
|
||||
uint32_t mNexts; // Number of Next() calls.
|
||||
uint32_t mNextsLimit; // Next() call limit.
|
||||
|
||||
bool mHaveRemoved; // Have any elements been removed?
|
||||
|
||||
bool IsOnNonLiveEntry() const;
|
||||
void MoveToNextEntry();
|
||||
|
||||
Iterator() = delete;
|
||||
Iterator(const Iterator&) = delete;
|
||||
|
Loading…
Reference in New Issue
Block a user